软件漏洞--优化ShellCode

通过TEB和PEB就可以找到一些关键dll文件的基址,也就是可以拿到dll中的API,通过IAT来处理

步骤

1 保存相关字符串

user32.dll,LoadLibraryA,GetProcAddress、MessageBoxA,Sna1lGo

2 通过fs寄存器获取kernel32.dll基址

mov esi,fs:[0x30];//PEB

mov esi,[esi+0xc];//把ldr地址给esi,LDR结构体地址

mov esi,[esi+0x1c]//这里得到的是初始化排序的dll的链表结构体的//第一个也就是InitalizationOrderMoudleList也就是初始化排序的dll,list结构体

mov esi,[esi];//通过链表指针指向了下一个DLL文件信息

mov ecx,[esi+0x8]//kernel32.dll基址

3 获取导出表 根据导出表查找需要的函数

MyGetProcAddress(imageBase,funName,strlen)

导出表在PE文件的PE头里面的可选PE头下的数据目录表的第0个位置

Nt头也就是PE头=ImageBase+0x3c

导出表(dataDirectory 第一项) = 可选PE头+0x78

EAT=导出表的首地址+0x1c 导出函数地址表

ENT=导出表+0x20 导出函数名称表

EOT=导出表+0x24 导出函数序号表

4 字符串比较函数

Repe cmpsb字符比较,edi与esi地址的值按字节进行比较,ecx为0或者比较结果不相同的时候停止DF循环(DF标志位为1就edi和esi自增,为0就自减),循环过程中将设置zf标志位,如果zf或cx为0则停止循环

5 payload函数:(stradd)

也就是攻击的代码通过调用以上各个功能实现输出 Sna1lGo

步骤实现

1 保存字符串

LoadLibraryA:4C 6F 61 64 4C 69 62 72 61 72 79 41 00 长度0xD

GetProcAddress:47 65 74 50 72 6F 63 41 64 64 72 65 73 73 00

长度:0xF

user32.dll:75 73 65 72 33 32 2E 64 6C 6C 00 长度0xB

MessageBoxA:4D 65 73 73 61 67 65 42 6F 78 41 00 长度:0xC

Sna1lGo:53 6E 61 31 6C 47 6F 00 长度:0x8

        //开始保存字符串从Sna1lGo保存到LoadLibraryA
push 0x006F476C
push 0x31616E53//保存的是Sna1lGo字符串
//保存MessageBoxA
push 0x0041786F
push 0x42656761
push 0x7373654D
//保存user32.dll字符串 75 73 65 72 33 32 2E 64 6C 6C       00
push 0x00006C6C
push 0x642E3233
push 0x72657375
//保存GetProcAddress:47 65 74 50 72 6F 63 41   64 64 72 65   73 73 00
push 0x00007373
push 0x65726464
push 0x41636F72
push 0x50746547
//保存LoadLibraryA:4C 6F 61 64 4C 69 62 72 61 72 79 41 00
push 0x00000000
push 0x41797261
push 0x7262694C
push 0x64616F4C

2 获取模块基址

也就是dll的基址

 

            mov esi,dword ptr fs:[0x30]//PEB指针
mov esi,[esi+0xc]//LDR结构体地址
mov esi,[esi+0x1C]//list
mov esi,[esi] //list的第二项 kernel32的地址
mov esi,[esi+0x8] //拿到对应的dll的imageBase
mov eax,esi       //返回值给eax

3 获取导出表 根据导出表查找需要的函数

MyGetProcAddress(imageBase,funName,strlen)

ImageBase+0x3C = NT头

EAT=导出表的首地址+0x1c 导出函数地址表

ENT=导出表+0x20 导出函数名称表

EOT=导出表+0x24 导出函数序号表

 

重点是写 MyGetProcAddress(imageBase,funName,strlen)这个函数这个函数的意思就是找到函数名和字符串长度都吻合的函数的地址

而且EAT和ENT还有EOT的数组序号是一样的