zoukankan      html  css  js  c++  java
  • pikachu---SQL注入(2)

    http header注入
    有些时候,后台开发人员为了验证客户端头信息(比如cookie验证)
    或者通过http header获取客户端的一些信息,比如useragent,accept字段等
    会对客户端的http header信息进行获取并使用SQL进行处理,如果此时并没有足够的安全考虑
    则可能会导致基于 http header 的 SQL 注入漏洞
    首先打开pikachu,http header登陆,登录账号:admin / 123456

    登陆后我们可以发现会记录我们的信息,根据这个功能,我们知道后台会获取 http header 里的数据,比如 user agent 等。那么这样它有对数据库操作吗?
    下面我们看一下BurpSuite抓包内容

    把 User-Agent 后面改为一个单引号,抓包看看后台处理的结果

    这个时候我们发现直接报了 SQL 语法错误,这说明存在 SQL 注入漏洞,后台可能会 insert 到数据库中,这样我们可以构造payload。
    1' or updatexml(1, concat(0x7e, database()), 0) or '

    这样我们就可以获取数据库名,后面的操作就是一样的了。
    还有 cookie 也是可以注入的,后端可能会取得我们的 cookie,后端通过拼接 SQL 语句进行验证
    我们可以在用户名后面加一个'

    我们可以发现直接报了 SQL 语法错误这说明存在 SQL 注入漏洞,我们可以构造下面的 payload
    admin' or updatexml(1, concat(0x7e, database()), 0)#

    这样我们就可以获取数据库名,后面的操作就是一样的了
    盲注
    在有些情况下,后台使用了错误屏蔽方法屏蔽了报错
    此时无法根据报错信息来进行注入的判断
    这种情况下的注入,称为“盲注”
    based on boolean
    基于真假的盲注主要特征
    没有报错信息
    不管是正确的输入,还是错误的输入,都只有两种情况(可以看做 0 or 1)
    在正确的输入下,后面跟 and 1=1 / and 1=2 进行判断
    我们在皮卡丘平台一进行实验,输入下面的测试语句
    kobe' and 1=1#

    kobe' and 1=2#

    发现一条正确执行,一条显示用户名不存在,说明后台存在 SQL 注入漏洞
    因为这里的输出只有 用户名存在 和 用户名不存在 两种输出,所以前面基于报错的方式在这不能用。
    我们只能通过 真 或者 假 来获取数据,所以手工盲注是很麻烦的。

    我们可以先用 length(database()) 判断 数据库名称的长度
    kobe' and length(database())>...#(...为任意整数)
    通过用户名存在 和 用户名不存在 两种输出可能来判断数据库长度是否正确
    这一种方法可以确定当前数据库的长度
    再用 substr() 和 ascii() 判断数据库由哪些字母组成(可以用二分法)
    kobe' and ascii(substr(database(), 1, 1)) > ...#(...为任意整数)
    kobe' and ascii(substr(database(), 1, 1)) = ...#(...为任意整数)
    不断重复,然后取得数据库名。
    再和 information_schema 和 length 猜测 表名 的长度。
    当然我们可以用下面的 SQL 语句替代上面的 database()
    (select table_name from information_schema.tables where table_schema=database() limit 0,1)
    同样的方法去猜解列名、数据,就是麻烦,我们可以用工具会方便些。
    based on time
    基于真假的盲注可以看到回显的信息,正确 or 错误
    基于时间的注入就什么都看不到了,我们通过特定的输入,判断后台执行的时间,从而确定注入点,比如用 sleep() 函数
    在皮卡丘平台一,无论输入什么,前端都是显示 “I don't care who you are!”
    首先我们点击F12打开控制台,选到网络

    然后我们输入下面的 payload 进行测试
    kobe' and sleep(5)#(sleep是让5秒才会返回执行结果)
    如果存在注入点,后端就会 sleep 5秒才会返回执行结果

    看到上图这说明这里存在SQL漏洞。
    接下来我们先构造一个payload
    kobe' and if((substr(database(), 1, 1))='p', sleep(5), null)#
    这个payload的意思是,如果当前数据库如果第一个字母是p就5秒才会返回执行结果,否则立即返回。
    当然我们也可以像真假注入是一样的了,替换 database()
    (select table_name from information_schema.tables where table_schema=database() limit 0,1)
    表(列)名的暴力破解
    我们之前都是通过 information_schema 去获取的信息,很多时候我们没有权限去读取里面内容,也可能是别的数据库,没有 information_schema
    常用的方法就是用暴力破解的方式去获得表名和列名
    kobe' and exists(select * from aa)#
    上面的 payload,遍历我们字典中的表名,把拦截的数据包发到 BurpSuite 中的Intruder中暴力破解 表名即可

    表名不存在时,会提示 doesn't exist,我们匹配这句话


    这时候就爆破出一个表名了——users

    然后同样的思路爆破列名
    kobe' and exists(select aa from users)#
    后面的操作都是大同小异。
    宽字节注入
    当我们输入有单引号时被转义为’,无法构造 SQL 语句的时候,可以尝试宽字节注入。
    GBK编码中,反斜杠的编码是 “%5c”,而 “%df%5c” 是繁体字 “連”。
    在皮卡丘平台中,将利用 BurpSuite 截获数据包,发送到 Repeater 中,在里面写入 payload
    当我们用通常的测试 payload时,是无法执行成功的,下面的payload会报错
    kobe' or 1=1#

    因为在后台单引号会被转义,在数据库中执行时多了个反斜杠。我们可以用下面的payload,在单引号前面加上 %df,让单引号成功逃逸
    kobe%df' or 1=1#

    当然这里还有转义函数比如escape。。。
    SQL注入防范措施
    代码层面
    对输入进行严格的转义和过滤
    使用预处理和参数化(Parameterized)
    网路层面
    通过WAF启用防范SQL Inject
    云端防护(360网站卫士,阿里云盾)

  • 相关阅读:
    86. Partition List
    2. Add Two Numbers
    55. Jump Game
    70. Climbing Stairs
    53. Maximum Subarray
    64. Minimum Path Sum
    122. Best Time to Buy and Sell Stock II
    以场景为中心的产品设计方法
    那些产品经理犯过最大的错
    Axure教程:如何使用动态面板?动态面板功能详解
  • 原文地址:https://www.cnblogs.com/renletao/p/13284255.html
Copyright © 2011-2022 走看看