• 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网站卫士,阿里云盾)

  • 相关阅读:
    python 字典
    python set集合
    python封装和解构
    python 内置数据结构 切片
    CPU 上下文切换及案例分析
    怎么理解linux的平均负载及平均负载高后的排查工具
    Linux性能优化
    python 内置数据结构 字符串
    python内置数据结构
    python GC、分支、循环
  • 原文地址:https://www.cnblogs.com/renletao/p/13284255.html
Copyright © 2020-2023  润新知