前言

先说说写这篇文章的目的,算是对自己所学sql注入的一个总结,也方便以后sql注入类的渗透测试思路更清晰,不至于盲目的测试单引号不报错就草草了事。

如何发现sql注入?

其实利用的话网上一大堆骚操作,但其实漏洞挖掘往往发现是最难的。

个人分析一下Web网站可能存在sql注入的功能点:

  • 登录框

  • 注册框(注册是否对单引号转义但数据库未处理可能导致二次注入),修改密码框

  • 信息搜索框

  • 以一个动态的索引号显示的不同功能页面(例如学校的jwc,不同id会显示不同的课程内容)

    在测试以上功能点的时候,特别是像找回密码这种框框,不一定每一个功能点都过滤严格。因而可以每一个都尝试一下,如果单引号被过滤严格,可以考虑bool盲注等方法,以及二次注入。

    那么如何判断其存在sql注入呢?

    1.单引号就不说了

    2.其次是and判断。假如网站采用的是数字型,然后使用

    1 and 1=1 //页面返回正确

    1 and 1=2//页面返回错误,出现这种情况就存在sql注入

    同样如果是字符:’ and ‘1’=’1//页面返回正确而’ and ‘1’=’2返回错误那么也存在sql注入

    跟and同理的or,||,^都可用于测试,还有xor.

    3.减号判断:?id=10-1与id=9页面返回相同则存在sql注入,由于+在Url中会被处理成空格,因而极有可能无法正确判断

    4.对于搜索框如果加上’出错则极大概率存在注入,如果再加上%正常返回就更有可能存在注入了。

    使用:%’ and 1=1 and ‘%’=’%

    ​ %’ and 1=2 and ‘%’=’%

    其中将and 1=1换成注入语句即可。

    说一哈为什么用%,搜索框采用的查询语句一般是模糊查询例如like,而like的通配符就是%因而使用%可以判断搜索框中是否存在注入。

    这里还需要注意一下服务端返回错误的形式:

    • 错误直接回显在页面上(几乎现在不存在了)

    • 错误隐藏在页面源代码中

    • 检测到错误跳转到另一个页面(可能就是WAF)

    • 返回http错误代码500或重定向302

    • 适当处理错误结果,常显示一个通用错误页面

判断数据库类型

根据一个统计,国内的网站使用ASP+ACCess或SQLserver的占百分之70以上,PHP+MysqL占百分之20其他不足%10

常见的数据库有Oracle、Mysql、SQL server、Access、 MSSQL、mongodb等

以上都属于关系型数据库,除此之外还有非关系型数据库例如:Nosql、cloudant

那么到底如何判断数据库类型呢?

总的有这么几种方法:

1.通过该数据库特定的函数进行注入,如果出错则不为某某数据库,以此排除。

2.通过辅助符号判断,例如注释符,多语句查询符等

3.是否可以编码查询

4.是否存在某些数据库特性辅助判断

5.通过数据库的特定报错信息

1.1 数据库特定函数

例如len和length,在mssql和mysql以及db2内,返回长度值是调用len()函数,oracle和INFORMIX通过length()来返回长度值

因此如果注入中使用了len函数页面返回正常则可能是mssql,mysql,db2反之就是oracle和informix.

还有@@version和version(),mysql中两种均可使用,相比起mssql,mssql只能使用@@version来判断版本信息。因而如果@@version正确,version()出错,则可能是mssql.

同理还有substring和substr,mssql中可以调用substring.oracle则只可调用substr.

2.1 对于辅助符号判断

/*是mysql中的注释符,如果出错则注入点数据库不是mysql。继续提交–,如果正常则是oracle或mssql.反之则继续提交”;”

;是子句查询标识符而oracle不支持多行查询,因而如果出错则不是oracle.

继续在注入点后加;–如果页面返回正常则是MSSQL(MSSQL中,;和–都是存在的,其中;用来分离两个语句,而–是注释符,后面语句都不执行)

因而出错了的话就肯定是ACCESS数据库了。

and exists (select count(*) from sysobjects)
and exists (select count(*) from msysobjects)

上面两句如果都不正常那就是access了,如果第一条正常就为mssql.

3.1基于报错判断:

如果错误提示为Microsoft JET DATAbase Engine错误‘80040e14’则表明是ACCESS数据库(ACCESS数据库通过JET引擎连接数据库),如果出现ODBC则是MSSQL数据库。

利用以上的这种排除思路即可准确找出注入的数据库类型。

SQL注入注意事项

我们经常用#作为注释符放在sql语句的后面来截断后面的查询语句,然后#还有另外一个身份,那就是url的锚,关于锚的定义(知道是个定位符就行)。因而这很容易导致查询语句失效,没有截断后面的语句。

因而还是使用– +比较好。

还有就是经常测试存在sql仅仅使用单引号,很多时候系统极有可能是int型的注入并用了双引号包裹保护这时候可以用逻辑1 and 1=1以及1 and 2=1进行回显判断。还有就是联合查询一定要让前面的id出错。

例如id=1存在的,就不要一直使用id=1 union了。使用id=-1或者不存在的id=0进行联合查询。

因为这两句是并行的,如果使用正确的进行Union这仅仅需要在正确的基础上查询,也就是id=1 union就只查询id=1的了。而如果id=-1出错,则只执行union后面的语句因而就可以达到全部查询了。

参考文章:sql注入-数据库判断