|
| 1 | +# HSCTF 2020 |
| 2 | + |
| 3 | +b1c got 3rd. maxxed all but pwn bc half of it was heap lol |
| 4 | + |
| 5 | +## Generic Flag Checker |
| 6 | + |
| 7 | +> https://twitter.com/mcclure111/status/1002648636516282368 |
| 8 | +
|
| 9 | +For some reason I solved a decently-worth rev chall this CTF instead of getting aplet to do it ("not on Windows"). |
| 10 | + |
| 11 | +Just running the exe gives us a `bad input`. So we reason that it must be passed in with the command line. It gives back, "checking..." and then depending on the length of the input, either a "Incorrect!" or it just exits. |
| 12 | + |
| 13 | +Obviously there must be some memcmp happening, and using `strings memes.exe` we see a memcmp at the end. |
| 14 | + |
| 15 | + |
| 16 | +Opening it in Ghidra makes the disassembly look scary so we opt for dynamic analysis. |
| 17 | + |
| 18 | +Open it in x64db. Configure it to send cmd line input with `File > Change Command Line`. For now, let's just use `AAAABBBBCCCCDDDD` as our input. |
| 19 | + |
| 20 | +In the beginning there are just some Windows DLL stuff so we can just skip to memes.EntryPoint with the call stack after it appears. |
| 21 | + |
| 22 | +We can keep going until we see "checking..." inputted. After some annoying breakpointing we can see that the call to whatever outputs "checking..." is here: |
| 23 | + |
| 24 | + |
| 25 | +Skipping through it, we end up at a function call to what appears to be the flag checking function. |
| 26 | + |
| 27 | + |
| 28 | +Eventually, we see our own input at: |
| 29 | + |
| 30 | + |
| 31 | + |
| 32 | + |
| 33 | +A few more F8s... What's this? |
| 34 | + |
| 35 | + |
| 36 | + |
| 37 | +It seems to have taken off 5 characters (`AAAAB`) from the front and 1 character (`D`) from the back, which perfectly fits the flag format! Now we know it must be checking the contents of our flag. |
| 38 | + |
| 39 | + |
| 40 | +After holding down F8 through a loop, we can see our modified flag being built, and our original input ends up as: |
| 41 | + |
| 42 | + |
| 43 | + |
| 44 | +Now, you may have to squint a bit, but you'll see that the new character is simply the old character minus the index of it in the string. If you're not convinced, you can simply input a `flag{ABCDEF}`. The registers will end up as `AAAAAA`. |
| 45 | + |
| 46 | +Great, so now we know what's happening to our input. What's it comparing to? |
| 47 | + |
| 48 | +Holding down F8 again, we see a suspicious string, |
| 49 | + |
| 50 | + |
| 51 | + |
| 52 | +stored in the registers near 00007FF6CBC012DE. Moreover, we can even see a `memcmp` call soon after! |
| 53 | + |
| 54 | + |
| 55 | + |
| 56 | +So, let's just reverse the subtraction of the index by adding the index back. |
| 57 | + |
| 58 | +```py= |
| 59 | +s = "con\\i`g^k" |
| 60 | +for i in range(len(x)): |
| 61 | + print(chr(ord(x[i])+i), end="") |
| 62 | +``` |
| 63 | + |
| 64 | +This gives us the flag. |
| 65 | + |
| 66 | + |
| 67 | +Flag: `flag{cpp_memes}` |
0 commit comments