]> git.somenet.org - pub/jan/ctf-seminar.git/blob - writeups/them/seccon19.md
Add write-up for OTW day-25: Lost in Maze
[pub/jan/ctf-seminar.git] / writeups / them / seccon19.md
1 # SECCON 2019 
2
3 ## The CTF in retrospective
4
5 I started playing this CTF after my two colleagues @someone and @astra informed me of the course, so i joined a little late (this is also the reason why i was not in the corresponding mattermost channel at that time). I spent around 12 hours playing this CTF, some more after plus some more for this writeup. Since i usually don't swap challenges a lot when playing CTF, the write-up is rather short in number (1 challenge only) but i attempted to make our train-of-thought very clear to at least provide a good documentation to what we did.
6
7 ## Challenges
8
9 ### Unsolved
10
11 #### for-repair
12
13 I worked at this challenge together with @astra and @someone from mattermost, sitting in a room next to each other.
14
15 The challenge was as follows:
16
17 ```
18   This file lost one sector. Please repair it.
19   960x540
20 ```
21
22 The download link gave us a ~2.7MB file that should be repaired. We started analysing it.
23
24  * `file` did not recognize it as something special, just "data".
25  * `binwalk` found some MYSQL compressed data file and some LZMA compressed data, but both seemed rather unlikely at that time.
26  * `strings` had some very interesting results: 
27   `JUNK LIST INFOISFT Lavf58.28.100 JUNK LIST movi00dc 00dc`
28   Especially the String `00dc` was interesting since it had more than 500 occurrences.
29   * `hexdump -C <file> | less -n 100` resulted in something that looks like some kind of header and then a repeating patteren revolving around the `00dc` we already have seen.
30
31 A google search for some of the keywords such as "JUNK LIST INFOISFT" and "00dc" gave a lot of hints towards an avi video file. This also matches up well with the file name `960x540` which seems to indicate a image/video resolution. 
32
33 At this point i attempted multiple video players to just run the file, including `mplayer vlc mpv`, but without success. Either nothing happened at all or unknown errors were reported. Especially interesting at this point is that no tool was able to recognize the file format. 
34
35 We searched online for several avi repair tools that could either repair it or atleast give us more information on what is broken exactly, but none really helped.
36
37 Since the challenge description says "lost one sector", it became quite likely that the file is missing header information and the repeating pattern noticed probably are frames of a video. This would mean if we would know what file format exactly it is, we might be able to read or recreate missing header information.
38
39 An attempt to fix the file was made by prefixing the file with 512 bytes (because 512 is the traditional size of a `sector`) of zeros. It was hoped that this might help various previously listed tools to recognize the file better. We did this using `dd if=/dev/zero of=./zerosector bs=1 count=512 && cat zerosector 960x540.avi > 960x540.mod.avi`.
40
41 Since the header probably has important information about the format of file contents, we attempted to convert the video using `ffmpeg -c:v <codec> -i "960x540.mod.avi" -c:v copy "recovery.avi"` with various different codecs we obtained `ffmpeg -codecs`. The idea was, if we specify the correct input codec to read, `ffmpeg` might just have enough information to copy and create a good video file as output. Some codecs produced an output, some just didn't work. Those that delivered output we attempted to play and see if it worked. But it didn't, mostly black and/or noise.
42
43 Next, we tried finding a reference video with the same resolution (960x540), so we could compare the file format and/or reuse [parts of] the header if possible. We found such a file [here][reference_video]. A side by side comparison of the hexdumps showed that only the information in the beginning seems missing, due to the position of the string "vprpD" which can be found at the exact same position in reference video line `0x000010f0` matching our file line `0x00000ef0`. Also, the reference file showed the same structure (keywords mentioned above) as our file, validating our believes in a video file.
44
45 We now tried to copy over the first 512 bytes (`0x000010f0 - 0x00000ef0 = 0x200 = 512 = traditional sector size`) from our reference video over to ours using `dd if=./reference.avi of=./960x540.mod.avi bs=1 count=512 conv=notrunc`, which allowed a little better results when attempting to play back the video with various media players. VLC now detected a runtime of 0:15 for this video (which is different from the 0:34 of the reference video, otherwise that would indicate that we just copied an encoded length field as well instead of using the one corresponding to our video).
46
47 We started spending a lot of time researching what the header actually contains and how we could find and reconstruct the missing information. We had some ideas, mostly revolving around writting our own decoder to extract frames. This is the point were the CTF ended, sadly, because at this point we were only one command aways from the solution :/ The rest below I found out after the end of the CTF.
48
49 If we had tried to convert the last file again using ffmpeg we would have had the result. `ffmpeg -c:v cinepak -i "960x540.mod.avi" -c:v copy "recovery.avi"`. (The codec parameter could have been found again using bruteforce trying every possible codec from `ffmpeg -codecs`) The result would have been a 10 second  video that is mostly black and shows three texts for a short while, one of which would have been the flag: `SECCON{FORENSICS_MOVIE_SECCON2019_TKTK}`.
50
51 It is also interesting to see that other teams according to their write-ups wrote some decoders using the ffmpeg api from python ([see here][wup1]) or attempted to do it in C ([see here][wup2]) manually, which we might also have attempted if the CTF would not have ended. 
52
53 The following script can produce a solution from the original input file using what we discoverd during and after the CTF:
54 ```
55 #!/bin/bash
56   INPUTFILE=./960x540.avi
57   REFERENCEFILE=./960x540.reference.avi
58   WORKFILE=./960x540.mod.avi
59   RESULTFILE=./recovery.avi
60
61   #generate missing sector of zeros
62   dd if=/dev/zero of=./zerosector bs=1 count=512
63
64   #prepend missing sector to file
65   cat zerosector $INPUTFILE > $WORKFILE
66
67   #overwrite first sector from reference file
68   if [ ! -e $REFERENCEFILE ]; then
69     wget "https://www.fm91.com.pk/wp-content/uploads/2017/08/960x540-AVI-MPEG-11.avi" -O $REFERENCEFILE
70   fi
71   dd if=$REFERENCEFILE of=$WORKFILE bs=1 count=512 conv=notrunc
72
73   #convert as means of repair using ffmpeg
74   ffmpeg -c:v cinepak -i $WORKFILE -c:v copy $RESULTFILE
75 ```
76
77 #### References:
78
79 [Reference Video][reference_video]  
80 [Write Up using Python and ffmpeg API][wup1]  
81 [GitHub Gist][wup2]  
82
83 [reference_video]: https://www.fm91.com.pk/wp-content/uploads/2017/08/960x540-AVI-MPEG-11.avi
84 [wup1]: https://translate.google.com/translate?hl=en&sl=auto&tl=en&u=http%3A%2F%2Fblog.bonprosoft.com%2F1685
85 [wup2]: https://gist.github.com/hikalium/7567d487d32af63ec0f4bc68e5a354cb