Alright so, my initial thought was straight to GDB, but after seeing the "antidebug" tag and combined with the recent ptrace post, I thought that there'd be definitely a call to ptrace to stop the executable from being traced. Which was indeed the case since the output of strace was:
Thus, trying to run the program through GDB wasn't a pleasure:
This output made it obvious that ptrace was being called before main, probably in some sort of "constructor attribute", but I'm not completely sure. The disassembly gives in some intel on this matter:
It looks like a modified version _start(), where dump is a helper debugging function(?), then cdg() is being called, which is probably the ptrace prevention(?) and finally main() is being called.
There is a way to bypass the ptrace anti-debugging technique (through patching the ptrace with NOPs or by patching the return value of ptrace which tells the program if it's being traced or not), but I failed implementing it (maybe @0x00pf can shed some light into it?).
I decided to leave the RE part aside and focus on the crypto part which ended up being fairly easy. By using the strings command, a part of the output is this:
Thanks to some wargames I was playing recently, it immediately hit me that ROT13 was being used. The decrypted part of it is this:
Some Includes here
Nothing interesting really
This is the source code you are looking at..... cool!
Some XORed strings in here
A function to print frobbed strings
This is minimal memfrob version
for (;l >=0; b[l--] ^=42);
And some anti-debug code that you have to remove
in order to debug the program.
It is hidden in an asm file with some opcode misaligment
A function to compare XORed strings without unXORing
This is the main function, but it is not the first function being called, thanks to some linker magic. Ar you using GDB or objdump -d -S?
The function to dump this file as the source code of the program. So you get this messages in your debugger... whenever you figure out that they are ROT13 encoded
The real entry point. It dumps this file, runs the anti-debug function and finally invokes main.... Easy
And voila, the program is using memfrob() for the encryption, aka 42 XORing.
Moving on to the disassembly, I had a bit of a hard time identifying the function symbols in order to understand which function was doing the password checking etc...But:
cmp edx, 0x2a kinda spoiled it since 0x2a == 42 == memfrob()'s encryption. After re-reading a couple of times the disassembly of ck, it seemed like edx was being compared with r8d. edx seemed to be the register holding the user's input and r8d was holding the already XOR'd password (keep in mind the hint from the ROT13 decrypted string "A function to compare XORed strings without unXORing"). So movsx is moving a string stored in the binary into r8d. That string is probably the needed password.
There has to be an easier way than mine but this is what I thought of:
The above pic gives in a lot of useful info but for this challenge I was curious about the load segments. So as you can probably see the text segment (containing the .text, .rodata, .hash, .dynsym, .dynstr, .plt, .rel.got sections) is loaded at the address 0x400000 and the data segment (containing the .data, .dynamic, .got, .bss sections) is loaded at address 0x601000.
Going back to the disassembly of , we can see that a string from the location 0x400318 + something is being stored into r8d. This address lives within the text segment, which kinda makes sense since the .rodata (read-only) section belongs to the text segment and the string itself is part of the binary's "data". So we have an idea of where the string is actually located.
I wrote a quick lil elfparser in order to go through each section and find the one I was interested in. I stored the data of the section in a buffer of size sh_size and starting at address sh_addr. Here is a preview of the output but I won't show it as a whole since the source code belongs to a (hopefully soon) finished project for 0x00sec that I've been working on.
Wherever you see actual addresses next to the sections it means that they will be loaded during runtime, whereas 0x0 means the opposite.
So I stored the content of the text segment itself and XOR'd it with the key in order to get the password and I once I entered it, I joined some really creepy darknet/evil IRC channel.