这两周的SQL注入总结
SQL注入原理
SQL注入即是指web应用程序对用户输入数据的合法性没有判断,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
注入本质:
1 | 将用户提交的恶意代码和原本的SQL 语句进行拼接,将拼接后的语句带入数据库来执行恶意语句,从而达到非授权任意查询的效果。 |
注入漏洞有两个关键条件:
1 | 1.用户能控制输入的内容 |
SQL注入分类
根据数据库来分可以分为:
1 | 1.Mysql数据库注入 2. Mssql数据库注入 3.Oracle数据库注入 4.Access数据库注入 |
根据请求方式不同可以分为:
1 | 1.GET方式请求注入 2.POST方式请求注入 3.请求头注入 |
根据sql注入点的参数类型可以分为
1 | 1.整数型注入 2.字符型注入 |
根据sql注入点的反馈类型分
1 | 1.基于错误显示的sql注入 2.union类型的sql注入 |
注入过程
大体分为这几个主要步骤:
1 | 1.确定请求方式 2.确定数据库类型 |
确定请求方式
HTTP 定义了与服务器交互的不同方法,最基本的方法是 GET 和 POST。
GET方式在客户端通过URL提交数据,数据在URL中可以看到,例如在日常中订购服务:
1 | http://www.cnblogs.com/javame/index.htm?servId=2 |
POST方式数据放置在HTML HEADER内提交,数据在URL中看不到
GET只能传输比较少的数据,安全性较低,POST传输数据较多,安全性也比GET高。
确定数据库类型
获取数据时,每种数据库架构、语法、类型都是不一样的。
1 | and (select count(*) from MSysAccessObjects) > 0 |
返回正常则说明是Access
1 | and (select count(*) from sysobjects) > 0 |
返回正常说明是Mssql
1 | and length(user()) > 0 |
返回正常说明是MySQL
Mssql中可以调用 substring,Oracle 则可调用 substr
寻找注入点
精髓
1 | 只要和数据库交互的地方都有可能存在注入 |
一般就是在URL后面的?id=n 后面,网页搜索框中,登陆帐号,请求头。
判断注入点的参数类型
注入点参数类型主要分为:数字型、字符型。
判断数字型:
1 | 如?id=2 ,将2变为3。在?id=后面设置3-1。如果?id=3-1的页面和2的一样,那么就是数字型注入 |
判断字符型:
1 | 常规字符型有' 、"、')、")、))。在?id=2后面分别加入前面的符号。如果报错或者页面回显不正常,那么证明有注入。 |
判断截断符号
在我们确定是字符还是数字型之后,要判断他的截断符号是什么
数字型
1 | 直接在语句后面添加要注入的语句即可 |
字符型
1 | 在确定完截断符号之后不断尝试注释符号,直到找到拼接后让页面恢复正常的字符。 |
根据注入点的反馈类选择注入方法
当我们确定完注释符号和截断符号时就可以选择注入方法了。大致有六种:
1 | 1.基于错误显示的sql注入 2.union类型的sql注入 |
在这里分情况进行注入
有回显时:
1 | 可以选择union类型的sql注入和基于错误显示的sql注入 |
无回显时:
1 | 可以选择布尔类型的sql注入和基于时间的sql盲注 |
特殊情况:
1 | 情况满足可以使用多语句注入。当-- | 等注释符被过滤时可以使用内联注入 |
判断WAF过滤字符
当我们在注入时可能会遇到and select union等关键字符被WAF过滤的情况,这时候就要肠坏死绕过WAF了。常见的绕过方法如下:
HTTP参数控制:
1 | HPP(HTTP Parameter Polution)重复参数污染 |
白名单绕过:
1 | 基于IP地址的白名单,一般很难绕过 |
过滤掉and和or情况下的盲注:
1 | ?id=strcmp(left((select%20username%20from%20users%20limit%200,1),1),0x42)%23 |
加括号绕过:
1 | ?id=-1+union+(select+1,2,3+from+users)%23 |
等价函数与命令:
1 | 函数或变量: |
利用注释绕过:
1 | 普通注释: |
利用编码绕过:
1 | Unicode编码 |
用特殊字符代替空格:
1 | %09 tab键 |
特殊符号:
1 | 反引号`,select`version()` |
构建符合标准的注入语句
最后就是将截断符号,注释符,选择后的注入方式,绕过WAF 结合在一起。
注入时常用的函数
| 函数名称 | 函数功能 | 函数名称 | 函数功能 | |
|---|---|---|---|---|
| system_user() | 系统函数名 | count() | 返回执行结果的数量 | |
| user() | 用户名 | concat() | 没有分隔符的连接字符串 | |
| current_user() | 当前用户名 | concat_ws() | 含有分隔符的连接字符串 | |
| session_user() | 连接数据库的用户名 | load_file() | 读取本地的文件 | |
| database() | 数据库名 | into outfile() | 写文件 | |
| versionI | 数据库版本 | ascii() | 字符串的ASCII代码值 | |
| @@datadir | 数据库路径 | ord() | 返回字符串第一个字符的ASCII值 | |
| @@basedir | 数据库安装路近 | mid() | 返回一个字符串的一部分 | |
| @@version_compile_os | 操作系统 | substr() | 返回7一个字符串的一部分 | |
| length() | 返回字符串的长度 | if() | > select if (1>2,2,3); ->3 | |
| left() | 返回字符串左面的几个字符 | strcmp() | 比较字符串的内容 | |
| floor() | 返回小于或等于x的最大整数 | ifnull() | 假如参数1不为null,则返回值为参数1,否则返回值为参数2 | |
| rand() | 返回0和1之间的随机数 | exp() | 返回e的x次方 | |
| sleep() | 让此语句运行n秒钟 |
特殊注入方法
除去常见的注入方法之外还有这样的注入方法:
1 | 二次编码注入 |
在这里查漏补缺记一下偏移注入:
access偏移注入
[背景]
1 | 1.偏移注入指access偏移注入,主要是由于数据库结构的问题,其他数据库没办法利用 |
[偏移注入的特点]
1 | 1.看人品和技巧的注入方法,不是%100能成功 |
[利用条件]
1 | 1.已知管理表名 |
[影响偏移注入成功率的因素]
1 | 1.管理表的字段越少越好(最好就三个 1.id 2.帐号字段 3.密码字段) |
[偏移注入的流程]
1 | 1.判断字段数 |