SQL注入前置知识及注入原理


前置知识

BurpSuite的及其拓展的安装及使用
SQLmap的下载及基本命令
了解少许PHP语言
不断尝试的热情!

相关知识

SQL注入原理

由于SQL语言是结构化查询语言(是操作数据库的语言,不懂的自己找我之前的文章)可以据库进行增、删、改、查等操作。
又因为程序员写的PHP代码不严谨,导致访问提交数据时,我们可以把代码提交到后台数据库,后台数据库处理这些数据时这些数据插入或拼接在一起形成了SQL语句命令,最后这个SQL语句可以被后台数据库作为恶意代码执行,从而达到你想达到的注入效果。

SQL注入三要素

未严格过滤(没开waf等防护)
允许恶意修改(具有一定权限)
执行语句(能够闭合并执行的合法SQL语句)

注入类型

按照注入时的表现来区分:

  1. 显注
  2. 盲注(无回显): 时间型、布尔型、报错型

按照注入点区分:
字符型
数字型

按照提交数据方式来区分:
GET注入
POST注入
Cookie注入
HTTP头部注入

危害
  1. 数据库信息泄露
  2. 网页篡改
  3. 网站被挂马,传播恶意软件
  4. 数据库被恶意操作
  5. 服务器被植入后门
  6. 破坏硬盘或者服务器等硬件设备
注入测试一般流程
(1)寻找注入点:可通过web扫描工具实现;
        是否存在注入并且判断注入类型
(2)利用注入点:尝试通过注入获得各种信息,越多越好;
(3)数据处理:猜解关键数据库表及其重要字段与内容;
        猜解SQL查询语句的字段数
        确定回显点
        查询数据库信息
        查询用户名,数据库名
(4)后续攻击:通过获取的用户信息,寻找后台登录并利用后台或了解的进一步信息。
        文件读取
        写入shell

一些杂七杂八的拓展知识

在MySQL5.0版本以后MySQL数据库中会默认存放一个information_schema的数据库,在该数据库中,我们需要记住三个表名,分别是schemata,tables,columns。
schemata表字段schema_name记录着数据库的库名;
tables表字段table_schema和table_nmae分别记录着数据库中的库名和表名;
columns表字段table_schema和table_name以及columns_name分别记录着数据库的库名、表名、字段名;

select 原始查询内容 union select 构造的内容
两者下一级的个数必须保持一致

select * from order by 你要按照排序的对象
对MySQL中查询结果按照指定字段名进行排序,左边第一个字段对应的索引是 1

limit 一个一个打印出来
group_concat 一次性全部打印

group_concat()函数
将同一组的列显示出来,相当于爆出该数据库的全部表

concat_ws(分隔符,str1,str2,……)函数
同时显示多个字段,并以分隔符分开

concat(str1,str2,str3,…)函数
同时显示多个字段,其中有一个字段为null,则返回null

SQL语句结尾加上limit 0,1
表示一个一个输出前面的语句的结果

0x20是空格

常用函数:
length()                # 返回字符串的长度
substring()                        
substr()                # 截取字符串
mid()
left()                    # 从左侧开始取指定字符个数的字符串
concat()                    # 没有分隔符的连接字符串
concat_ws()              # 含有分割符的连接字符串
group_conat()           # 连接一个组的字符串
ord()                    # 返回ASCII 码
ascii()    
hex()                    # 将字符串转换为十六进制
unhex()                    # hex 的反向操作
md5()                    # 返回MD5 值
floor(x)                # 返回不大于x 的最大整数
round()                    # 返回参数x 接近的整数
rand()                    # 返回0-1 之间的随机浮点数
load_file()                # 读取文件,并返回文件内容作为一个字符串
sleep()                    # 睡眠时间为指定的秒数
if(true,t,f)            # if 判断
find_in_set()            # 返回字符串在字符串列表中的位置
benchmark()                # 指定语句执行的次数

较难理解的注释语句

#和-- 表示注释,可以使它们后面的语句不被执行(--后有个空格)
get请求解释执行的时候,url中#号是锚点,所以HTTP请求中使用#闭合无法注释。
而-- 在传输过程中--与后面的单引号连接在一起,也无法形成有效的mysql语句。
那么要启动空格的作用就需要在--后面加上一点字符,比如+或'(因为+会被解释成空格)

当然,也可以使用--%20,把空格转换为urlencode编码格式,也不会报错。
同理把#变成%23,也不报错。

如果是post请求,则可以直接使用#来进行闭合。
常见的就是表单注入,如在后台登录框中进行注入。

另外#后面可以有空格,也可以没有(sql就是这么规定的,记住就行了)
如何进行SQL注入的防御
  1. 关闭应用的错误提示
  2. 加waf
  3. 对输入进行过滤
  4. 限制输入长度
  5. 限制好数据库权限,drop/create/truncate等权限谨慎grant
  6. 预编译好sql语句,python和php中一般使用?作为占位符。这种方法是从编程框架方面解决利用占位符参数的sql注入,只能说一定程度上防止注入。还有缓存溢出、终止字符等。
  7. 数据库信息加密安全(引导到密码学方面)。不采用md5因为有彩虹表,一般是一次md5后加盐再md5
  8. 清晰的编程规范,结对/自动化代码review,加大量现成的解决方案(PreparedStatement,ActiveRecord,歧义字符过滤, 只可访问存储过程balabala)已经让SQL注入的风险变得非常低了。
绕过技术:
  1. 关键字可以用%(只限 IIS 系列)。比如 select,可以 sel%e%ct
  2. 通杀的,内联注释,如 /!select/
  3. 编码,可两次编码
  4. multipart 请求绕过,在 POST 请求中添加一个上传文件,绕过了绝大多数 WAF
  5. 参数绕过,复制参数,id=1&id=1
  6. 组合法 如 and 可以用&&再 URL 编码
  7. 替换法,如 and 改成&&;=可以用 like 或 in 等
最后哔哔一句,如果你丫这都看不懂,那你别学了。

评论
  目录