• pikachu-SQL注入漏洞


    一、SQL Inject 漏洞原理概述

    1.1 什么是数据库注入漏洞

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

    1.2 SQL Inject漏洞的攻击流程

    (1)第一步:注入点检测

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

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

    (2)第二步:信息获取-通过注入点取期望得到的数据

        环境信息:数据库的类型、版本,操作系统的版本,用户信息等;

        数据库信息:数据库名称,表,字段,字段内容(加密内容的破解)

    (3)第三步:获取权限

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

    1.3注入点类型及常见注入类型讲解

    (1)数字型:user_id=$id

    (2)字符型:user_id='$id'

    (3)搜索型:text LIKE '%{$_GET['search']}%'"

    1.4 演示:SQL Inject-数字型注入

    1、来到pikachu平台数字型注入(post)模块,先测试一下页面的功能,我们在下拉框内选择1,点击查询。

    2、我们猜想整个页面的逻辑是什么样的?

    3、我们可以通过PHP Study 打开我们的数据库终端。执行命令:show databases;

    显示我们所有的数据库。

    4、在数据库命令行工具内执行:show tables;查看pikachu数据库内的所有表

    5、在命令内执行:select username,email from member where id=1; 查询id=1的用户名和对应的邮箱。

    6、通过上边在命令行里边的一同操作,我们猜想:如果系统后台正如我们所想象一样,将获取的id的值直接拼接到查询语句后边而不加处理,那么我们是不是可以通过抓包、数据重放的方式获取所有的用户名和对应的邮箱?下边我们先去看一下后台代码。

    7、我们先打开burp suite,然后选择一次id值,查询。将抓到的数据包发送到重放模块。

    1.5 演示:SQL Inject-字符型注入

    1、来到pikachu平台字符型注入(get)模块,我们先看一下整个模块的功能。

    2、现在我们猜想一下后台的处理逻辑。

    3、现在我们构造闭合语句

    lucy' or 1=1-- '

    首先在lucy后边加一个单引号进行闭合,然后加上or 1=1,后边的单引号我们用注释符—注释掉。

    4、将构造语句复制到查询框,点击查询。就会拿到我们所有的信息。

    5、最后我们来看一下代码

    1.6 演示:SQL Inject-搜索型注入

    1、我们先来看源码

    2、将构造语句填入搜索框

    1.7 演示:SQL Inject-xx型注入

    1、我们来看源码:

    2、将构造的源码输入到查询框

    1.8 总结

        到现在为止,可能会有人疑问,我们做的演示都是在知道源码的情况下构造语句,那么在真实的环境里我们是不知道源码的,那么我们该如何构造语句呢?

    1. 第一种是我们可以根据报错的办法,例如:lucy',如果这个时候报错,说明存在单引号包裹;
    2. 第二种是我们可以利用and or 等,判定我们的构造语句是否参与了运算。
    3. 总之,还是要有经验,这个是一个积累的过程~~大家加油!

    二、注入方式get&post的区别

    GET方式中使用URL提交注入数据;

    POST方式中使用抓包工具修改POST数据部分提交注入。

    不管是GET还是POST,都有可能出现SQL注入漏洞,本质上是一样的!

    三、SQL Inject漏洞手工测试

    3.1 基于union联合查询的信息获取(select)

    1、我们使用pikachu的字符型注入模块。

    首先使用构造语句:lucy' order by [number]判断表存在几列。

    2、然后使用union关键字查询信息

    说明:user() database() 都是SQL语句里边的函数,具体的讲解可以参考我的关于sqli-libs 的博客。在这里我就不多说了。

    3.2基于报错的信息获取(select/delete/update/insert)

    由于我在我关于sqli-labs的博客中对报错查询做了详细的讲解。这里只是粗略的讲一下,如想深层次了解,请移步我的关于sqli-labs的博客。

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

    updatexml():对XML文档数据进行查询和修改的XPATH函数

    extractvalue():对XML文档数据进行查询的XPATH函数

    floor():用来取整的函数

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

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

    我们同样利用字符型注入(get)来进行演示

    (1)、select 语句:

    (2)、insert 语句

    构造语句:xxx' or updatexml(1,concat(0x7e,database()),0) or '

    (3)、update 语句:

    和insert是一模一样的,大家可以试一下。

    (4)、delete语句:

    构造闭合语句:1 or updatexml(1,concat(0x7e,database()),0)

    3.3操作系统权限获取

    这里我们讲"一句话木马"这个概念

    1、一句话木马是一种短小而精悍的木马客户端,隐蔽性好,且功能强大

    2、我们可以通过SQL注入漏洞写入恶意代码

    例如我们结合into outfile向后台写入:select 1,2 into outfile "/var/www/html/1.txt"

    3、写入的前提条件:

        (1)需要知道远程目录,我们作为测试者是一开始是不知道的

        (2)需要走远程目录有写入的权限

        (3)需要数据库开启了secure_file_priv

    4、请看到这里的童鞋移步我的关于sqli-labs的博客,对于一句话配合中国菜刀工具控制操作系统有着详细的介绍。

    四、SQL注入漏洞-盲注

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

    这种情况下的注入,称为"盲注"。

    4.1(boolian base)类型的盲注

    我们直接来看构造语句:

    kobe' and ascii(substr(database(),1,1))>113--

    布尔类型的回显结果只有两种,正确还是错误。

    我们首先用substr()函数取出database()的第一个字母,然后进行ascii编码,最后采用二分法判断,知道找到一个值可以使之输出正确的结果,得到第一个字母到底是什么,然后取出database()里边的第二个字母,以此类推……

    4.2(time base)类型的盲注

    布尔盲注还有正确和错误两种情况输出,但是在时间盲注类型下,就一种输出,无论正确与否,都是一种输出。

    我们直接来看构造语句:

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

        这个构造语句的作用是,首先判断数据库的第一个字母是不是p,如果是就延迟5秒,表现出来就是网页一直显示在等待加载的状态,五秒后在返回结果页面,如果不是,就立即返回结果页面。

    五、基于 http header的注入

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

    下面就这个场景下的SQL注入做演示。

    1、我们来到pikachu的"http header"注入模块,打开burp suite抓包工具,开启浏览器代理,执行下图中的操作。

    2、打开burp suite,将截取到的数据包发送到重放模块。

    3、构造报错注入语句:firefox' or updatexml(1,concat(0x7e,database()),0) or '

    4、除了在user agent处存在注入点,我们还猜想系统是否会对http header当中的cookie进行分析,验证用户名和密码。

    5、我们执行上图的操作后,会在右侧的输出栏的底部发现报错,说明我们的猜想是正确的。我们同样构造注入语句:admin ' and updatexml(1,concat(0x7e,database()),0)—

    六、SQL注入表列名猜解-暴力破解在SQLI上的应用

    当我们没有权限读information_schema这个数据库的时候,或者我们面对的数据库不是MySQL的时候,那么我该如何获得列名和表名?

    这个时候我们考虑采用暴力破解的方式。

    首先我们得有一个构造好的语句:kobe' and exists(select * from aa)#

    这个语句的作用是,aa作为变量,用exists()函数判断我们要查询的数据库是否存在,若存在就会返回一个正确的结果。

    1、我们利用pikachu字符注入模块,开启burp suite,然后将构造好的语句输入。

    2、来到burp suite将抓到的数据发送到暴力破解模块。

    3、执行破解后,我们来看结果

    七、使用SQL-map进行SQL Inject漏洞测试

    1、我们利用布尔类型的盲注模块做演示:在模块里边的查询框内随便输入一个值,点击查询。

    2、打开sqlmap工具

    -D pikachu -T users –columns查询users表内的字段

    -D pikachu -T users -C username,password –dump查询字段内容

    这里就不展示了。

    八、SQL注入漏洞常见的防控措施

    1、代码层面

    (1)对输入进行严格的转义和过滤

    (2)使用预处理和参数化(Parameterized)

    实例:

    2、网络层面

    (1)通过WAF设备启用防SQL注入策略(类似的防护系统)

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

  • 相关阅读:
    爬虫第二弹之http协议和https协议
    爬虫第一弹之py爬虫的相关概念
    Flask第十四篇- Flask-Session组件、WTForms组件、数据库连接池(POOL)
    Flask第十三篇- flask请求上下文源码解读、http聊天室单聊/群聊(基于gevent-websocket)
    Flask第十二篇- flask中的CBV、werkzeug+上下文初步解读、偏函数和线程安全
    Flask第十一篇装饰器的坑及解决办法、flask中的路由/实例化配置/对象配置/蓝图/特殊装饰器(中间件、重定义错误页面)
    Flask第十八篇 Flask-Migrate
    Flask第十七篇 Flask-Scrip
    Flask第十六篇 Flask-SQLAlchemy
    Flask第十篇 before_request after_request
  • 原文地址:https://www.cnblogs.com/Feng-L/p/12371890.html
Copyright © 2020-2023  润新知