python实现的php序列化
就单纯想推销一下libphpserialize
如何用Python实现PHP的序列化
- 脑补
- 写代码
如何使用libphpserialize
安装
1 | pip3 install libphpserialize |
使用
1 | from phpserialize import serialize |
非常银杏方便
为什么不用php自己的serialize?
- 不用在你的电脑上安装php
- python有requests/httpx,php没有
- 简化做题流程
想象一下这样的场景:
你在打一个比赛,在做一道反序列化相关的题目。你启动了一个定时销毁的容器,这个容器限时一个小时。你在第50分钟的时候找到了合适的pop链,并用5分钟用python写出了触发反序列化的python poc。
你慌忙地打开了一个新的文件,将类的定义拷贝了过来,给他们赋了各种属性,然后echo serialize($obj);
,结果发现有个private属性,于是又慌忙地改成了 echo urlencode(serialize($obj));
,又在命令行中 php generate.php
,复制,粘贴进python脚本,执行脚本,最后发现题目里头的反序列化入口处他 base64_decode
了一下,于是又回头去将 urlencode
改成 base64_encode
,复制,粘贴,执行python脚本,运行,502,你很愤怒,用浏览器去访问了一下这个链接,发现容器已经过期了。你人麻了。
再想象一下这样的场景:
你已经成功地构造好了pop链,但是这个链非常长,而且需要精巧地构造属性值。你觉得用python构造这样的属性最简单,但是又不得不print出来然后粘贴到php代码里。你构造好了 system('cat /flag');
的payload,结果发现出题人在 disable_functions
中禁用了system函数。你不得不重新来一遍整个流程,构造属性,复制粘贴,生成序列化串,将序列化串粘回到python脚本里,请求。可是你突然发现你构造出来的序列化后的串突然用不了了,你找了10分钟,最后发现由于终端输出的字符数量限制,你只复制了一半。你非常气愤,直接在python脚本里 payload = input()
,然后直接用管道符运行 php generate.php | python3 exp.py
,结果发现仍然打不通。你又找了半天,发现php代码里用于调试的几个var_dump没有删。你一怒之下关闭了vscode,打开了LOL,找几个憨批进行一个人的祖安,还破坏了他人的游戏体验。
再想象一下:
你的队友找到了一条pop链,但是二话不说给你发过来这样一串谜语
1 | ?r=site%2Fabout&message=TzoyMzoieWlpXGRiXEJhdGNoUXVlcnlSZXN1bHQiOjE6e3M6MzY6IgB5aWlcZGJcQmF0Y2hRdWVyeVJlc3VsdABfZGF0YVJlYWRlciI7TzoxNzoieWlpXHdlYlxEYlNlc3Npb24iOjE6e3M6MTM6IndyaXRlQ2FsbGJhY2siO2E6Mjp7aTowO086MzI6InlpaVxjYWNoaW5nXEV4cHJlc3Npb25EZXBlbmRlbmN5IjoxOntzOjEwOiJleHByZXNzaW9uIjtzOjIzOiJldmFsKCRfUkVRVUVTVFsiYW50Il0pOyI7fWk6MTtzOjE4OiJldmFsdWF0ZURlcGVuZGVuY3kiO319fQo=&ant=phpinfo(); |
你的眼睛都要看瞎了,可是你访问了这个url,竟然真的打通了。你接下来想继续往进探一探,于是打开了hackbar,痛苦地一个字符一个字符地去改。你题做完了,眼睛也废了。结果你的憨批队友又不想写wp,想让你来写。你想打游戏,于是也贴了这么一大长串。评论区生气了,说你这谁**看得懂。
如果你有类似的经历,那你可以用libphpserialize来拯救你快乐的一天。
示例
1 | from phpserialize import serialize |
这道题需要解析php源码的ast,并且进行搜索,去掉不可用的假链,找到唯一的一条真链。
这道题是一道比较常规的框架反序列化,payload需要base64_encode后发送
WIP