0x00 Shellcode概述
- Shellcode与exploit
1) shellcode:缓冲区攻击中植入进程的代码。进行删改文件、窃取数据、上传木马并运行、格式化硬盘等。用汇编语言编写,并转换成二进制机器码,内容和长度受到苛刻限制。
2) exploit: 漏洞利用程序,用于生成攻击性的网络数据包或其他形式的攻击性输入。exploit的核心是淹没返回地址,劫持进程控制权,跳去执行shellcode
3) 区别:shellcode具有一定的通用性,exploit针对特定漏洞
0x01 定位shellcode
漏洞利用过程中,由于动态链接库的装入和卸载等原因,Windows进程的函数栈帧可能产生移位,即shellcode在内存中的地址是动态变化的,因此需要exploit在运行时动态定位栈中的shellcode。
函数返回步骤
1) 保存返回值:函数返回值保存在EAX寄存器
2) 弹出当前栈帧,恢复上一个栈帧
a) ESP + 当前栈帧大小:堆栈平衡基础上,降低栈顶,回收当前栈帧空间
b) POP EBP:前栈帧EBP弹给EBP,恢复上一个栈帧
c) POP EIP:函数返回地址弹给EIP
3) 跳转:按EIP的值返回母函数继续执行
由函数调用过程可知,一般情况下,ESP中地址总是指向系统栈且不会被溢出的数据破坏。函数返回时,ESP所指的位置是淹没的返回地址的下一位(子函数平衡栈ret n时,ESP将指向下n位)。可用”jmp esp”作为跳板动态定位shellcode
1) 用内存中任意一个”jmp esp”的地址覆盖返回地址
2) 函数返回后被重定向去执行内存中jmp esp指令
3) 由于函数返回后ESP指向返回地址后,jmp esp执行后,CPU将到栈区函数返回地址之后的地方取指令执行
4) shellcode的布置。缓冲区前面一段用任意数据填充,把shellcode放在函数返回地址后面。jmp esp执行完就执行shellcode。获取跳板的地址
1) 一些经常被用到的动态链接库会被映射到内存,如kernel.32.dll、user32.dll会被几乎所有进程加载,且加载基址始终相同(不同OS上可能不同)。所有这里使用user32.dll中的jmp esp作为跳板。
2) 编程搜索jmp esp的内存地址。搜索得到以下地址,从中选取0x77d93acc作为定位shellcode的跳板覆盖函数返回地址。
#include <windows.h>
#include <stdio.h>
#define DLL_NAME "user32.dll"
main()
{
BYTE* ptr;
int position,address;
HINSTANCE handle;
BOOL done_flag = FALSE;
handle=LoadLibrary(DLL_NAME);
if(!handle)
{
printf(" load dll erro !");
exit(0);
}