考点:对于RS256弱公钥生成的jwt可以伪造(非对称加密)
网鼎杯 Web1 改编自这道国际赛的题 有空来复现一下 解题 WP :https://ctftime.org/writeup/30541
主页访问直接返回源码
from flask import Flask, request
import jwt, time, os
app = Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(24)
private_key = open('priv').read()
public_key = open('pub').read()
flag = open('flag.txt').read()
@app.route("/get_token")
def get_token():
return jwt.encode({'admin': False, 'now': time.time()}, private_key, algorithm='RS256')
@app.route("/get_flag", methods=['POST'])
def get_flag():
try:
payload = jwt.decode(request.form['jwt'], public_key, algorithms=['RS256'])
if payload['admin']:
return flag
except:
return ":("
@app.route("/")
def sauce():
return "
%s
" % open(__file__).read()
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
os.urandom(24)
生成24字节的密钥
session密钥不可爆破 虽然本题没有用上
访问 /get_token
可以获取通过RS256 私钥加密的jwt
通过jwt伪造 篡改admin为true 就可以拿到flag
通过 两个单独生成的 JWT中获取公钥 密码学的相关脚本在wsl中跑
https://github.com/silentsignal/rsa_sign2n
python jwt_forgery.py eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhZG1pbiI6ZmFsc2UsIm5vdyI6MTczMDI5MjE2Ni4xNzU4MzE4fQ.DV2gnUApzu3vc61unXTqYDAxIkmoaRDDQ5u1XhmYl_LcKQBm6ty9x4dRBL9v_-Q3LuiTVTaouZgncMHJ4p75Vog-0F05ybrCTT5FeI6KHlsjLdQHLp3xnry7xnCPF7JEUQ eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhZG1pbiI6ZmFsc2UsIm5vdyI6MTczMDI5MjQ3Mi4yNTg1MDEzfQ.BFcuO-C82OSEXKaS4aCdsgSXBuGslCbc44XMSVADlIvfhWTS1nTW3mFQNjfVFeIYISRsFuUWU9fsU0wFwpXSwAG2rXt_cr9p9K6ISzoOQ_QvbZErz3Osmfc8jkmocnehyQ
生成了不止一个的公钥 存在一定概率
拿一个试试
1b6275b9f55291c0_65537_x509.pem
https://github.com/Ganapati/RsaCtfTool
生成公钥对应的私钥
不行就换一个最后发现这个可以
python RsaCtfTool.py --publickey 10.pem --private
-----BEGIN RSA PRIVATE KEY-----
MIIB+wIBAAJhEIt8da7h4rnfNpKizFSxANERACGT68nDz1deSxb1lcwo2bR6ZdHz
d0qj2wVkkIVYkjD+I7/MLvh2tBNNr95EhNe96Mm4ABbZya7VOgM0rjSDzIMzdDAe
GngppfWACnk4AwIDAQABAmEKpfUIG6wBMAOtnv0vdki0XiDfW6KTMDRDvdcjryUd
sIi8WaAV8ZW9z9XWw/v8U/4DrOzW5nJwm2BwMRfpIfKlS/QW0gX/TR+btntJc6P8
wnks0vynK8S9A+l4kegxYrSxAmEAkg0einG4Xq9r0BdE1shPeffCNh+VXzu3s5B+
LO38Vnz+rfKQwJ5230Nxe8WstSZdUSM/Bp0cGjkPCX5D24bGyaVx9Uz3LO0G9F+g
5aC2jw1fU/jyWe9iBCS/Gh7l4N6fAgEdAmBhCOJfrQqHrhj9WlhcMx3KtTeNahJ+
AVkdrkSGaV+bvtQekehmcWIdF9wQFdeXS3P4cmhvZnbDXWGGNyOyeKseUhOSnJ4k
dR6HwflOVyaziHjre5zY79i5VAi7vAeTDZUCAQUCYG7MKNL1KsNqmGjlg6vEGPts
ga15EDaXO+lTIe0eeM7aaO3kJzEFdKlfTUNp0nfE1AiWUx+AA6n2UgczpjybNbN0
rroXE8nOS+WGVr/bBhQ/HC4MTevzZNcBZNYFyN+OZw==
-----END RSA PRIVATE KEY-----
查看公钥 public.key
-----BEGIN PUBLIC KEY-----
MHwwDQYJKoZIhvcNAQEBBQADawAwaAJhEIt8da7h4rnfNpKizFSxANERACGT68nD
z1deSxb1lcwo2bR6ZdHzd0qj2wVkkIVYkjD+I7/MLvh2tBNNr95EhNe96Mm4ABbZ
ya7VOgM0rjSDzIMzdDAeGngppfWACnk4AwIDAQAB
-----END PUBLIC KEY-----
正确的公私钥对 可以实现成功伪造
生成 admin为true的jwt
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhZG1pbiI6dHJ1ZSwibm93IjoxNzMwMjkyMTY2LjE3NTgzMTh9.D5lGYl8VXqDzb4s68gF7n9cIklE8qvQEa-GydRDDFKP0gE2F_4877cE2azMbyKVBt5TSv4TW5pR6rO28eSrqt3refFmksgAnSqal2-1SFw2sb6xlUEiMbRWPEV8Tz26QmA
可以成功拿到flag
DUCTF{json_web_trickeryyy}