Just like previous years, OSIRIS Lab managed to put awesome challenges for CSAW Quals 2018. I participate from ‘dcua’, here are the write-ups of the solved challenges. I will keep adding/updating tasks time to time. So, consider this write-up(s) under construction.
Twitch Plays Test Flag (MISC) – 1 Point
A mandatory attendance check for every Capture the Flag event.
LDAB (WEB) – 50 Points
We were given a website http://web.chal.csaw.io:8080/
The first page, has one search bar and list of Users with their associated group information.
Lists the same content on the web-page. Interesting as the search query understands * . Numerous possibilities can be explored like Elastic Search etc. They have been covered previously in CTF ( For instance: SECCON 2017)
But, in this case we can try assuming LDAP due to the structure of columns name. A basic injection payload goes as
That provides us the flag at bottom
Algebra (MISC) – 100 Points
Challenge description provides us
nc misc.chal.csaw.io 9002
Basically, it looks like simple algebra where we have to find missing term ‘X’. sympy module makes thing lot faster and easier when performing calculations as such.
Run the solver, sit back & relax. The complexity of the problems get difficult but it should be no problem for our solver.
WhyOS (MISC) – 300 Points
Most painful challenge which tests your grepping skills. A debian and log file was provided. I used binwalk to extract the content of the debian package. We have to look for some entry-point, so I navigated to Library/PreferenceBundles/whyOSsettings.bundle and opened the file Root.plist
No flag hardcoded in the plist file. Seems we have to reverse the dylib and macho files. setflag is what we need to reverse in order to see what is placed as the contents of flag. We reverse the binary & convert into a pseudo-code
Looks, like flag will be logged under CFString. I started grepping, bummer it failed. A struggle followed thereafter, I made the list of most used services in the log. Tried to grep from the lowest used service one by one. Then I thought, the flag isn’t in flag format, but it may have alphanum_alphanum. Tried that
Tried word brute
Apparently, it fails. Very time consuming process considering I have to work on numerous challenges.
I am basically guessing 6 as mid-part. I guessed a lot of range, no success. Then, Hint came that flag is a hex string and that too does not contain 0x
Immediately, I constructed this
Basically, I filtered out useless services which made log. It failed as well. That’s not over, I tried to also convert all hex strings to plain-text using xxd -r -p but well all was blobs of data pushing me far away from flag. I tried grepping ‘5f’ (hex of _) considering flag is preserved in hex and assuming it must have _ somewhere. It failed.
So either there are two options:
1.) Flag is not printable in ASCII, must be other encoding done before Hex conversion
2.) It is byte-by-byte flag
2nd option seems less likely. First is , yeah well. I tried, but failed. So, it’s hex string, what if it is a hash like SHA-1 or MD5. I saw other hint from the organizers on IRC by @pa_ssion (I believe) saying it is more reverse than forensics. Looking closely into app bundle, it seems the log must be under Preferences. I grepped (again) with varying length of hash either 32 or 40 with -E switch, but this time to solve. Just 1 and half hour before end time.
Flag is ca3412b55940568c5b10a616fa7b855e
Flatcrypt (Crypto) – 100 Points
We were given out handout code which uses AES CTR Stream cipher to encrypt data. A peculiarity of AES-CTR is that it encrypts every byte separately unlike encrypting the whole block like AES-ECB or CBC Mode. In AES-CTR mode no padding is required, hence the length of ciphertext is always equal to the length of input. There is a RFC which explains CTR in great detail.
The hand-out code looks as follow:
The encryption key is not provided to us and the counter is instantiated with 8 random bytes. Hence, we cannot break the AES-CTR implementation itself but we have to look for other vulnerabilities. The part which stands out in the code is that the data is being compressed by zlib library and then it is feed into the encrypt routine. Zlib works on back referencing, so if the text which is to be compressed has multiple repeats then zlib will return a lower value then say if the text has no multiple repeats.
Hence, we can compare the length of the cipher-text and look at what character it returns a lowest length which indicates compression is successful and we will keep on prepending other characters to known_flag and brute again until we receive the flag. But, there is a twist. The server requires us to enter at least 20 bytes before it performs the encryption process. We are provided in the distributed file that the character set is lowercase letters and underscores. So, if our first 20 bytes contains none of those, we can utilize our logic properly. We can use
Note that, the last character is the length of the ciphertext.
Just like that, we will retrieve the flag, although we have to guess the first character. Now, to come to the main point — This type of exploit targeting compression is known as CRIME.
Lowe (Crypto) – 200 Points
Typical RSA crypto problem.