概述
Protein Cookies是来自于HTB(hackthebox.com)的一个容易级密码学挑战,完成该挑战所需要掌握的知识点在于针对哈希函数的长度扩展攻击。
题目分析
相关的任务文件包括一个Web应用的源代码, 重要的部分包括:
* blueprints/routes.py
定义了所有的Web访问路径, 从中我们得知访问Web路径/program可以获取flag.pdf,而访问该路径需要通过session cookie的登录校验
* models.py
定义了用于session cookie的生成和校验的方法。 session cookie由两部分组成,第一部分是格式为username={}&isLoggedIn={}的payload,第二部分是对第一部分的签名,其实现为sha512(secret + payload), secret是长度为16的随机串。 两部分都使用base64编码以生成最终的cookie字串。
初始化的session cookie,其payload为username=guest&isLoggedIn=False, 而访问/program路径则需要cookie中包括&isLoggedIn=True,同时其签名部分也必须与服务器端生成的签名相符。
#解题过程
以上签名方法使用sha512哈希函数,且知道secret的长度, 因此对其可使用长度扩展攻击。
哈希函数长度扩展攻击指的是, 对于hash(secret + message) = h1而言,如果我们知道secret的长度,message的值,h1的值,已知hash方法的具体实现,那么我们可以计算出``hash(secret + message + padding + attack)的返回值。 其中padding取决于hash方法,而attack`则可以是任意的字串。
哈希函数长度扩展攻击的具体实现可以通过hash_extender(github.com/iagox86/has…
访问在线程序后,我们得到如下的cookie
login_info:"dXNlcm5hbWU9Z3Vlc3QmaXNMb2dnZWRJbj1GYWxzZQ==.OGFkZjFlMTU5OTE2MDYwYWYzNTg5MWE4YWY0OTQ3NjJjMzNiZWIyNGRkMzFlZDAxOGIzZjE3YjlkNjA3M2I2YTFmOTk2NzdlZDBkYjVhYmNkMTg0ZDIxNzllNmExMGYyOWY1Yzg1MTAxNGYwZGYwZjU5YTMxY2U1MGQ0YzUyYjg="
第一部分的payload值为dXNlcm5hbWU9Z3Vlc3QmaXNMb2dnZWRJbj1GYWxzZQ==, base64解码后为b'username=guest&isLoggedIn=False'
第二部分的签名值为OGFkZjFlMTU5OTE2MDYwYWYzNTg5MWE4YWY0OTQ3NjJjMzNiZWIyNGRkMzFlZDAxOGIzZjE3YjlkNjA3M2I2YTFmOTk2NzdlZDBkYjVhYmNkMTg0ZDIxNzllNmExMGYyOWY1Yzg1MTAxNGYwZGYwZjU5YTMxY2U1MGQ0YzUyYjg=, base64解码后为8adf1e159916060af35891a8af494762c33beb24dd31ed018b3f17b9d6073b6a1f99677ed0db5abcd184d2179e6a10f29f5c851014f0df0f59a31ce50d4c52b8
然后使用hash_extender对payload进行添加并生成相应的padding和哈希值
./hash_extender --data 'username=guest&isLoggedIn=False' --secret 16 --append '&isLoggedIn=True' --signature 8adf1e159916060af35891a8af494762c33beb24dd31ed018b3f17b9d6073b6a1f99677ed0db5abcd184d2179e6a10f29f5c851014f0df0f59a31ce50d4c52b8 --format sha512
New signature: 0c6532cffa86f84b816496e11247c61cfa5a615fca82ed7046a076920285d9ebdf3ef0b77ce6a5ed882baeff221022b0980891d85651fd20362398d0907e4101
New string: 757365726e616d653d67756573742669734c6f67676564496e3d46616c73658000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001782669734c6f67676564496e3d54727565
然后对以上的结果分别进行base64编码就可生成新的cookie值
import base64
new_payload=bytes.fromhex("757365726e616d653d67756573742669734c6f67676564496e3d46616c73658000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001782669734c6f67676564496e3d54727565")
## b'username=guest&isLoggedIn=False\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01x&isLoggedIn=True'
b1 = base64.b64encode(new_payload)
new_signature = b"0c6532cffa86f84b816496e11247c61cfa5a615fca82ed7046a076920285d9ebdf3ef0b77ce6a5ed882baeff221022b0980891d85651fd20362398d0907e4101"
b2 = base64.b64encode(new_signature)
new_cookie = b1 + b"." + b2
## b'dXNlcm5hbWU9Z3Vlc3QmaXNMb2dnZWRJbj1GYWxzZYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABeCZpc0xvZ2dlZEluPVRydWU=.MGM2NTMyY2ZmYTg2Zjg0YjgxNjQ5NmUxMTI0N2M2MWNmYTVhNjE1ZmNhODJlZDcwNDZhMDc2OTIwMjg1ZDllYmRmM2VmMGI3N2NlNmE1ZWQ4ODJiYWVmZjIyMTAyMmIwOTgwODkxZDg1NjUxZmQyMDM2MjM5OGQwOTA3ZTQxMDE='
将生成的cookie值植入浏览器后,访问/program路径就可以获取flag.pdf。