Showing posts with label pcap. Show all posts
Showing posts with label pcap. Show all posts

Friday, January 6, 2017

Holiday Hack Challenge 2016 - Writeup (Part 1)




SANS put on another spectacular challenge for us during the holiday times, the Holiday Hack Challenge!  A mix of 2d mmo + security challenges : )

Starting out we see on the instruction page that we're looking for a secret message in Santa's tweets - https://twitter.com/santawclaus

This can also be seen in the introduction image of Santa's Business Card:



The tweets didn't look like much except a bunch of Christmas themed words smashed together...

Precursory thoughts lead me to believe it could be a rudimentary cipher or stego challenge of some kind.  Copying all the tweets into VIM and deleting the timestamps / usernames was the first step. This instantly lead to a solution:




The next part was to look into Santa's Instagram profile.  This was located here - https://www.instagram.com/santawclaus

There were a couple funny images and the main one being a hacker's workspace (Most likely Santa W. Claus or an elf working for him).  Scattered through-out was python reading material, SANS workshops, an nmap scan, half eaten jerky and a little peek at the screen of the user.  On the laptop monitor in the top you see an interesting file SantaGram_v4.2.zip, and the scan contains an interesting url: http://www.northpolewonderland.com/.



Also in the comments, it was riddled with zip remarks (probably highlighting the mistake of leaking the filename) and a pointer to the same server with the actual file and password.  Most of these accounts had no followers or posts, so they were probably setup for the challenge:


After downloading and unpacking the zip, now we have an APK to play with!  Instantly disassembled and decompiled it using apktool to take a look at the source.


The next couple questions had to do with the APK:

3) What username and password are embedded in the APK file?
4) What is the name of the audible component (audio file) in the SantaGram APK file?

For #3, we can simply grep through the contents of the decompiled apk for any trace of 'password', this ended up dropping:

    jSONObject.put("username", "guest");
    jSONObject.put("password", "busyreindeer78");


For #4 we could just use a find and grep for mp3's / audio in the name.

$ find . |grep -i mp3
./res/raw/discombobulatedaudio1.mp3


The next set of challenges had to do with collecting some items in-game to construct a 'Cranberry Pi' eluding to the Raspberry Pi, but ... Christmas flavored?

When talking to a character in the game after all the pieces were collected, they provided a Raspberry Pi image which relate to the next question:

5) What is the password for the "cranpi" account on the Cranberry Pi system?

This was achieved by mounting the Raspberry Pi image on a linux box, then pulling out the passwd & shadow files to crack the 'cranpi' account credentials.  This was done quickly with john & rockyou.


Terminal Doors

Next up was the terminal doors, these were found through-out the 2D game which featured a terminal in-front of a locked door which would unlock when you got the key.


Elf House #2

In the game there was a building called "Elf House #2" which contained a terminal unlocking a room.  Looking at the file system we see that we need to inspect a pcap.  The pcap is owned by another user "Itchy".  Initially your username is "Scratchy" -- most likely referencing the Simpsons in "The Itchy & Scratchy Show"

*******************************************************************************
*                                                                             *
*To open the door, find both parts of the passphrase inside the /out.pcap file* 
*                                                                             *
*******************************************************************************
scratchy@f550041cb156:/$ ls
bin   dev  home  lib64  mnt  out.pcap  root  sbin  sys  usr
boot  etc  lib   media  opt  proc      run   srv   tmp  var
scratchy@f550041cb156:/$ 


Looking at the permissions we have the ability to run strings & tcpdump on the pcap.

  scratchy@006599aaaf89:/$ sudo -l
  sudo: unable to resolve host 006599aaaf89
  Matching Defaults entries for scratchy on 006599aaaf89:
      env_reset, mail_badpass,
      secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
  User scratchy may run the following commands on 006599aaaf89:
      (itchy) NOPASSWD: /usr/sbin/tcpdump
      (itchy) NOPASSWD: /usr/bin/strings

Running strings looking for longer occurrences, we find part of the key.  I guessed the second half based on the theme of the game and the characters provided.

  cratchy@3f9fbad1c2e2:/$ sudo -S -u itchy strings -n 40 out.pcap

  <input type="hidden" name="part1" value="santasli" />

In the door there was an elf providing feedback about "Copy as Curl" in Burp which was very helpful later on in the challenge.


Workshop -> DFER

*******************************************************************************
*                                                                             *
* Find the passphrase from the wumpus.  Play fair or cheat; it's up to you.   * 
*                                                                             *
*******************************************************************************
elf@ee24bd520fdb:~$ 


This was the classic Hunt The Wumpus game. On this one I just played the game, nothing too special, but it was fun!


Workshop -> Santa's Office

This was another quick one.
First started out by using find. After that we get a listing of filenames which need a bunch of escaping to type... But we're lazy, so we'll just use grep. (Output is cut for brevity)

*******************************************************************************
*                                                                             *
* To open the door, find the passphrase file deep in the directories.         * 
*                                                                             *
*******************************************************************************

elf@a13973c497af:~$ find .
./.doormat/. / /\/\\/Don't Look Here!/You are persistent, aren't you?/'/key_for_the_do
or.txt

elf@a13973c497af:~$ grep -r .
.doormat/. / /\/\\/Don't Look Here!/You are persistent, aren't you?/'/key_for_the_door
.txt:key: open_sesame

The key ended up being 'open_sesame' -- It reminded me a lot of one of the earlier bandit challenges, over at http://overthewire.org/wargames/.


Santa's Office

This was one of my favorite discoveries on all of the terminals.  The scene from WarGames played out!  If you haven't seen WarGames definitely go out and grab a copy.

To get through this terminal session, all you have to do is enter the text just like the film.

You can grab the script by watching the video here - https://www.youtube.com/watch?v=-1F7vaNP9w0

GREETINGS PROFESSOR FALKEN.

Hello.

HOW ARE YOU FEELING TODAY?

I'm fine. How are you?

EXCELLENT, IT'S BEEN A LONG TIME. CAN YOU EXPLAIN THE REMOVAL OF YOUR USER ACCOUNT ON 
6/23/73?

People sometimes make mistakes.

YES THEY DO. SHALL WE PLAY A GAME?

Love to. How about Global Thermonuclear War?

WOULDN'T YOU PREFER A GOOD GAME OF CHESS?

Later. Let's play Global Thermonuclear War.

FINE

...

,------~~v,_         _                     _--^\
 |'          \   ,__/ ||                 _/    /,_ _
/             \,/     /         ,,  _,,/^         v v-___
|                    /          |'~^                     \
\                   |         _/                     _ _/^
 \                 /         /                   ,~~^/ | 
  ^~~_       _ _   /          |          __,, _v__\   \/
      '~~,  , ~ \ \           ^~       /    ~   //
          \/     \/             \~,  ,/          
                                   ~~
   UNITED STATES                   SOVIET UNION
WHICH SIDE DO YOU WANT?
     1.    UNITED STATES
     2.    SOVIET UNION
PLEASE CHOOSE ONE: 

1

AWAITING FIRST STRIKE COMMAND
-----------------------------
PLEASE LIST PRIMARY TARGETS BY
CITY AND/OR COUNTRY NAME: 
Las Vegas

LAUNCH INITIATED, HERE'S THE KEY FOR YOUR TROUBLE: 

LOOK AT THE PRETTY LIGHTS

Press Enter To Continue


Train Station

The train was also one of the most interesting terminals, when opening it, you're instantly dropped into an application instead of a shell.  The immediate thought went to exploitation, but we just need to break out of the menu.


Train Management Console: AUTHORIZED USERS ONLY
                ==== MAIN MENU ====
STATUS:                         Train Status
BRAKEON:                        Set Brakes
BRAKEOFF:                       Release Brakes
START:                          Start Train
HELP:                           Open the help document
QUIT:                           Exit console
menu:main> 

First off I tried running each command to see what it did, then went to HELP to see if there was any more information missing.
Looks like the HELP dropped us straight into a less session! This is nice, so maybe we can run commands in less using a bang.

**STATUS** option will show you the current state of the train (brakes, boiler, boiler
 temp, coal level)
**BRAKEON** option enables the brakes.  Brakes should be enabled at every stop and whi
le the train is not in use.
  
**BRAKEOFF** option disables the brakes.  Brakes must be disabled before the **START**
 command will execute.
**START** option will start the train if the brake is released and the user has the co
rrect password.
**HELP** brings you to this file.  If it's not here, this console cannot do it, unLESS
 you know something I don't.
Just in case you wanted to know, here's a really good Cranberry pie recipe:
Ingredients
1 recipe pastry for a 9 inch double crust pie
1 1/2 cups white sugar
1/3 cup all-purpose flour
1/4 teaspoon salt
1/2 cup water 
1 (12 ounce) package fresh cranberries
1/4 cup lemon juice
1 dash ground cinnamon
2 teaspoons butter
Directions:
!bash

!done  (press RETURN)

conductor@bb56a879c8fa:~$ ls -la
total 40
drwxr-xr-x 2 conductor conductor  4096 Dec 10 19:39 .
drwxr-xr-x 6 root      root       4096 Dec 10 19:39 ..
-rw-r--r-- 1 conductor conductor   220 Nov 12  2014 .bash_logout
-rw-r--r-- 1 conductor conductor  3515 Nov 12  2014 .bashrc
-rw-r--r-- 1 conductor conductor   675 Nov 12  2014 .profile
-rwxr-xr-x 1 root      root      10528 Dec 10 19:36 ActivateTrain
-rw-r--r-- 1 root      root       1506 Dec 10 19:36 TrainHelper.txt
-rwxr-xr-x 1 root      root       1588 Dec 10 19:36 Train_Console

conductor@bb56a879c8fa:~$ grep -ri 'pass' .
./Train_Console:PASS="24fb3e89ce2aa0ea422c3d511d40dd84"
./Train_Console:                                read -s -p "Enter Password: " password
./Train_Console:                                [ "$password" == "$PASS" ] && QUEST_UI
D=$QUEST_UID ./ActivateTrain || echo "Access denied"
./TrainHelper.txt:**START** option will start the train if the brake is released and t
he user has the correct password.

conductor@bb56a879c8fa:~$ ./ActivateTrain

Looks like we have the pass now, but we don't even need it with ActivateTrain! :)

   MONTH   DAY     YEAR          HOUR   MIN
  +-----+ +----+ +------+  O AM +----+ +----+      DISCONNECT CAPACITOR DRIVE
  | NOV | | 16 | | 1978 |       | 10 |:| 21 |           BEFORE OPENING
  +-----+ +----+ +------+  X PM +----+ +----+     +------------------------+
                DESTINATION TIME                  |                        |
  +-----------------------------------------+     |    +XX         XX+     |
  +-----------------------------------------+     |    |XXX       XXX|     |
                                                  |  +-+ XXX     XXX +-+   |
   MONTH   DAY     YEAR          HOUR   MIN       |       XXX   XXX        |
  +-----+ +----+ +------+  O AM +----+ +----+     |         XXXXX          |
  | JAN | | 06 | | 2017 |       | 05 |:| 05 |     |          XXX           |
  +-----+ +----+ +------+  X PM +----+ +----+     |          XXX           |
                  PRESENT TIME                    |          XXX           |
  +-----------------------------------------+     | SHIELD EYES FROM LIGHT |
  +-----------------------------------------+     |          XXX           |
                                                  |          XX+-+         |
   MONTH   DAY     YEAR          HOUR   MIN       |                        |
  +-----+ +----+ +------+  O AM +----+ +----+     +------------------------+
  | NOV | | 16 | | 1978 |       | 10 |:| 21 |            +---------+
  +-----+ +----+ +------+  X PM +----+ +----+            |ACTIVATE!|
                LAST TIME DEPARTED                       +---------+
Press Enter to initiate time travel sequence.

--->Activating TIME TRAVEL sequence NOW.....
***** TIME TRAVEL TO 1978 SUCCESSFUL! *****

Nice! This worked! Transported us into 1978.

I'll be posting the second part soon, with more details about the server exploitation in part 4.

Tuesday, May 3, 2016

Google CTF 2016 - Various [No Big Deal Pt. 1, In Recorded Conversation, Spotted Quoll, Ernst Echidna]



So I grouped these all together for two main reasons:
  1. I was inspired seeing this short writeup for GeoKitties - https://twitter.com/k_firsov/status/726841516174508033
  2. Write-ups can take some time, so this is a good way of shortening a few challenges into one post.

Quick note about the writeups below:
  • Each of the examples below are one-liner solutions (they may not be the best one-liners because they can be longcat-long, but were fun to make)
  • Each example below has a one-line output including the CTF{...} flag


No Big Deal Pt. 1 (50):

This one was probably one of the easiest challenges (even easier than the 5pt recon) that I came across, strings'ing the pcap gave an obvious base64 encoded value at the end of the dump, which turned into the flag, here's the one-liner:

strings -n 9 no-big-deal.pcap | tail -n 1 | base64 -D

Result:

CTF{betterfs.than.yours}



In Recorded Conversation (25):

The name of this challenge invoked the idea that there was going to be a hidden conversation to find a flag in.  That was exactly it in a pcap!  For this one I didn't open wireshark and decided to jump into more tshark.  This is not my actual solution for the challenge when I was playing (it was a lot more manual), but the same thing would've worked... Usually there's no time to do silly things like tr, sed & multi-massaged-list-comprehensions to get an answer when you're on the CTF clock.

tshark -r irc.pcap -T fields -e data 2>/dev/null | python -c "import sys; a=sys.stdin.read().split('\n'); a=[x.decode('hex') for x in a]; a=[x for x in a if 'PRIVMSG' in x and '~' not in x]; print a" | tr ',' '\n' | grep #ctf | tail -n 8 | head -n 7 | sed 's/.*://g;s/\\.*//g' | tr '\n' ' ' | sed 's/ //g'

Result:

CTF{some_leaks_are_good_leaks_}



Spotted Quoll (50):

This challenge was mainly solved by a team-mate (Unixist), but I helped out a bit with some minor details.  Also formed it into this massive one-liner:

curl -L https://spotted-quoll.ctfcompetition.com/admin --cookie obsoletePickle=$(python -c 'import pickle; x = pickle.loads("KGRwMQpTJ3B5dGhvbicKcDIKUydwaWNrbGVzJwpwMwpzUydzdWJ0bGUnCnA0ClMnaGludCcKcDUKc1MndXNlcicKcDYKTnMu".decode("base64")); x["user"] = "admin"; print pickle.dumps(x).encode("base64").replace("\n", "")') 2>/dev/null | grep -i ctf

The challenge consisted of identifying that the cookie was in a python pickle format, dumping the current cookie (base64 encoded) and then noticing the user was set to None, changing it to admin and re-encoding it / sending it off.


Result:

Your flag is CTF{but_wait,theres_more.if_you_call} ... but is there more(1)? or less(1)?



Ernst Echidna (50):

This challenge was also a very simple web challenge, consisting of a cookie that was set to the md5 value of your username.  The goal was to view the admin section, so a little echo -n admin | md5sum, and we've got our cookie.


curl https://ernst-echidna.ctfcompetition.com/admin --cookie md5-hash=$(echo -n admin | md5) 2>/dev/null | grep -i ctf

Result:

      Congratulations, your token is 'CTF{renaming-a-bunch-of-levels-sure-is-annoying}



These were all simple, but very fun! Had a good time forming the (mostly) one-liners above today.  Let me know if you have any more efficient examples of these in the comments!



Sunday, May 1, 2016

Google CTF 2016 - A Cute Stegosaurus (100)



Description for this challenge was:

Admire our cutest Stegosaurus ever!


They give you a pcap file called stego.pcap, sooooo let's fire up Wireshark and see if a shark can find a dinosaur.


Initially saw a /message.png route being hit, so I decided to see if I could extract that out of the pcap.


In Wireshark, this is really simple, just follow the TCP stream / File > Export Objects > HTTP, and you'll see it pop up with the file seen in the traffic.




Save and open the file and we get:



YESSSSSSs! A Fr'cken Stegosaurus!!!!

Something about this pun in this makes me tear up a bit....
(Also Pro-Tip for trolling stego solvers in the future, add some random artifacts into the image like they mean something, after staring at that dino leg on the right with the seam, I almost thought it could be hidden there... Not sure if it was the caffeine or sleep-deprivation, either way it'll work on someone)


Anyways, down to business.

Running this image through the standard stego tools & photo editing tools got nothing.  Tried a quick sweep through the threshold, bitplanes, alpha, stereograph, etc.  Nothing too interesting was in the exif data either.


So after taking a break on this one and coming back I looked in the packets again to see if anything else was there for carving.

Started to look for any patterns in any part of the packets (being only 2k of them & fairly regular).
Then I stumbled upon this little gem:



What... is this Urgent pointer thing all about ?  Why so Urgent ?

This must be the Nova Microdash of TCP packets.....


So let's see if we can find out what's so urgent.


After going through a few, it looks like they may actually be in the printable character range.  This one was 70, let's convert that, write it down and go to the next one.  The next was 123, these two combined make the characters 'F{' ... going backwards we'll also see 67 & 84 as 'CT'... All of this together is 'CTF{' -- Looks like we're on the right track.


Now I could've probably done this by hand, but I didn't want to, felt a little lazy and also thought it was a good time to explore tshark more.  So in a new terminal I went ahead and executed this command (kinda luckily guessed this one, I'm not very experienced with tshark):

> tshark -r stego.pcap -T fields -e tcp.urgent_pointer

0
0
0
0
0
0
67
0
84
0
70
0
123
0
65
0
110
0
100
0
...


(Cut the output down for brevity) -- The problem with this output is there are all these 0 bytes that are sneaking in to our nice characters we want to extract. We could just grep these out to make life easier:

> tshark -r stego.pcap -T fields -e tcp.urgent_pointer | egrep -vi "^0$"

67
84
70
123
65
110
100
...


There's probably a really cool hacky way to turn these all to chars on the command-line (leave a comment if you know one), but I just threw it in a python script, did some normal vim/sed magic for converting it to a list, and printed out the result:

arr = [
        67,
        84,
        70,
        123,
        65,
        110,
        100,
        95,
        89,
        111,
        117,
        95,
        84,
        104,
        111,
        117,
        103,
        104,
        116,
        95,
        73,
        116,
        95,
        87,
        97,
        115,
        95,
        73,
        110,
        95,
        84,
        104,
        101,
        95,
        80,
        105,
        99,
        116,
        117,
        114,
        101,
        125,
]

print "".join([chr(x) for x in arr])


After running this we get the answer:

CTF{And_You_Thought_It_Was_In_The_Picture}

Learned a lot in this challenge including urgent flags, how evil a stego creator can get (including imagined scenarios that could've been worse), and how to spell Stegosaurus.


Monday, September 7, 2015

MMA CTF 2015 - Stream... (100)


We didn't end up solving this during the competition, but I thought it would be nice to show the challenge and share the process we went through in finding the flag.

It starts with a pcap file which contains many similar packets (parts of the stream).  After sorting by length and following the TCP stream of one, we find some interesting header content.






































Notably we find the "User-Agent" as NSPlayer, "Content-Type" as "application/x-mms-framed", and in the bytes it shows that it's a "Windows Media Video" (WMV) format.

Now the tricky part is figuring out how we can play this content.  We can save the binary data to a file in Wireshark pressing 'Save As' and editing the header out (Also useful to filter out the conversation by the part we care about in the dropdown menu which defaults to Entire Conversation).

After some research it looked like we could just push the data over a server, and use VLC to interpret it as an MMS stream.  Here's a simple guide for OSX users on how to open MMS streams in VLC - http://elearning.etsu.edu/macmmsguide/index.html

The question is, what does our server need to look like?
Apparently not much.

This was done with very little effort and seemed to work fine (simple Node.js server):
m=require; m('http').createServer(function(_, r) {r.end(m('fs').readFileSync("extracted"))}).listen(4444);
Where "extracted" is the binary file we formed from the stream.

Now All we had to do is view the result in VLC: after launching VLC, you can go to File > Open Network, and give it a url.  In this case we're hosting it locally, so we just point it to mms://localhost:4444 (important to use the mms protocol in this situation)

When playing it we get an initial frame of Rainbow Colors!






























Then more of what we're looking for, in a classic MS PAint window ;)





























The Final Flag Being:
MMA{windows_xp_is_too_old_to_create_problem!!}

MMA CTF 2015 - Splitted (30)

This challenge started with a 7z that extracted a pcap.
Launching wireshark, I sort by the length column to check the largest packets captured.

Looks like there's a zip that was transfered, this is probably what we need to extract, also looks like it's in multiple chunks ('splitted').



After naively doing a "Follow TCP Stream" and exporting the data, I realized the segments were in the wrong order.  Notably the "PK" bytes were in the middle, which are part of the magic bytes for a zip file.  Now we need to figure out how to arrange it correctly.  The intuition of where to find this data came from a friend on the team - http://lockboxx.blogspot.com/
On a past challenge he had mentioned there are parts of the packet describing the order in which streams constructed.  Looking a little further I found the "Content-Range" attribute needed to reconstruct the original file.

By the way, if anyone knows of a nice way in python to pull the "Content-Range" section out of the HTTP headers, please leave a comment below, I would love to know!



In this example, we're looking at the 2nd packet in the chain of total split packets.  It shows the Content-Range is 269-937.  Now we just need to export each data portion of the packet to a file.  We'll start by copying the hex representations to a python file and export the zip this way.

By right-clicking on the field underneath "Media Type" we can go to Copy > Bytes > Hex Stream, which will be the representation of bytes in the payload section of this packet only ( A lot nicer than trimming down the header section of each packet ).



Following the "Content-Range" attribute for each packet, we assemble a python file that will export the zip file contained within the capture:


Now we can extract it with unzip, and check what's inside!
Looks like we have a file called flag.psd.
Let's open that up in gimp and see what we've got.



Looks like we've got a blank canvas!  But there's another layer in the psd.  Turning off the first layer, or swapping the layers seems to do the trick.