JWT+python反序列化漏洞 [CISCN2019 华北赛区 Day1 Web2]ikun

JWT+python反序列化漏洞 [CISCN2019 华北赛区 Day1 Web2]ikun,第1张

前面的步骤不是很重要 (主要是这个题太魔性)

主要是一个去找lv6所在页面

import requests

url = "http://b9ac92ba-7b09-4b78-9ed8-540734732bff.node4.buuoj.cn:81/shop?page="
i=1
while True:
    r = requests.get(url + str(i))
    if 'lv6.png' in r.text:
        print (i)
        break
    i=i+1

因为太贵了 修改price发现没有用 于是修改了discount
为0.000001


到了这里发现只允许admin访问 所以需要伪造一个admin身份

再次访问这个页面 并且抓包 可以看到这里有一个jwt字段

JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。


该信息可以被验证和信任,因为它是数字签名的。


由于知识面太窄 所以以前不太懂这个东西

JSON Web Token由三部分组成,它们之间用圆点(.)连接。


这三部分分别是:
Header Payload Signature

Header header典型的由两部分组成:token的类型(“JWT”)和算法名称(比如:HMAC SHA256或者RSA等等)。



比如:

{
    'alg': "HS256",
    'typ': "JWT"
}

Payload JWT的第二部分是payload,它包含声明(要求)。


声明是关于实体(通常是用户)和其他数据的声明。


例如:

{
    "sub": '1234567890',
    "name": 'john',
    "admin":true
}

Signature
为了得到签名部分,必须有编码过的header、编码过的payload、一个秘钥,签名算法是header中指定的那个,然对它们签名即可。


HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

以上部分引用自这个链接
在这里 我们可以得到一个jwt 可以到jwt.io来破译


可以解出前面的信息 但无法破译密匙 想要伪造jwt需要得到密匙之后 再给wzk改为admin重新生成一个jwt发送过去

https://gitcode.net/mirrors/brendan-rius/c-jwt-cracker?utm_source=csdn_github_accelerator
可以使用这里面的工具去破解


可见密匙为1Kun 和我个人的博客1kun.xyz居然撞名了

成功发送并找到了藏在这里的源码 下载下来阅读
之后便是重点
这里用become参数来控制p的反序列化 之后并会送到form页面进行渲染
这里会进行回显 所以我们现在要去admin页面进行 *** 作

这里先对python的反序列化进行总结:
序列化:

pickle.dumps()

反序列化

pickle.loads()



可见成功完成了序列化与反序列化

import pickle
import os
class A(object):
    def __reduce__(self):
        return (os.system,('ls',))
a = A()
test = pickle.dumps(a)
print(test)

>>
cposix
system
p0//编号p0
(S'ls'
p1 
tp2
Rp3
.

在python中内置了__reduce__(self) 类 类似wake_up 在反序列化的时候会执行 可以利用它来执行命令。



reduce函数 返回一个元组。


这个元组包含2到5个元素,其中包括:一个可调用的对象,用于重建对象时调用;一个参数元素,供那个可调用对象使用;
比如return (os.system,(‘ls’,)) 就会执行os.system(‘ls’)

c:读取新的一行作为模块名module,读取下一行作为对象名object,然后将module.object压入到堆栈中。


(:将一个标记对象插入到堆栈中。


为了实现我们的目的,该指令会与t搭配使用,以产生一个元组。


t:从堆栈中d出对象,直到一个(被d出,并创建一个包含d出对象(除了()的元组对象,并且这些对象的顺序必须跟它们压入堆栈时的顺序一致。


然后,该元组被压入到堆栈中。


S:读取引号中的字符串直到换行符处,然后将它压入堆栈。


R:将一个元组和一个可调用对象d出堆栈,然后以该元组作为参数调用该可调用的对象,最后将结果压入到堆栈中。


.:结束pickle

cos
system
(S'ls'
tR.

反序列化 会成功执行

这里就相当于os.system(‘whoami’)

成功执行

所以我们可以构造一个需要我们执行的代码在reduce中,并序列化出它的结果然后进行抓包伪造,然后去执行该命令。


使用 commands.getoutput() 可以得到回显 才可以渲染到下一页中 方便我们查看

伪造become 发现成功 之后改为打开flag就可以 想反dshell 但是失败了 明天再试试。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/606984.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-14
下一篇 2022-04-14

发表评论

登录后才能评论

评论列表(0条)

保存