Web漏洞
一、Sql注入
sql注入漏洞的成因是由于后端数据库查询语句没有做过滤导致了前端输入字符串可以直接拼接到语句而获取数据库信息。
1.类型
数字型和字符型
区分:数字型可以进行加减运算,id=1+1会获取id=2的信息,而字符型只会获取1的数据
2.方法
(1)联合查询
使用union select 联合查询,通过mysql的information_schema数据库中的columns表和tables表获取
#使用联合查询之前要使用order by看看数据的列数,再联合查询相应的列数
#此时假设有3列数据,联合查询先用1,2,3看看页面回显是哪个数据1还是2还是3的位置
union select 1,2,3;
#知道数据回显位置,比如2,3在页面某个位置出现回显,那么就可以再2或者3上进行数据查询,从而回显到页面,先查询数据库获取当前数据库
union select 1,database(),3
#获取数据库名后应该需要获取表名 如何获取?
#mysql数据库存在一个information_schema数据库,有所有的数据库,表,字段名的信息,可以通过这个已知的数据库以及已知的表都存放在tables表里来进行查询,否则你不知道当前数据库的表有哪些,也无法查询。
union select 1,group_concat(table_name) from information_schema.tables where table_schema="当前数据库名",3;
#获取表名以后,就要看看这个表里都有什么字段名,可以通过columns表
union select 1,group_concat(column_name) from information_schema.columns where table_schema="当前数据库名" and table_name="想查询表名",3;
#知道了数据库名表名和字段名就可以直接通过select语句进行查询
union select [字段名] from 数据库.表名
(2)报错注入
使用函数extractvalue()函数,由于有些函数的优先级高,会优先执行函数里的内容再返回,使用该函数来实现报错,然后利用concat来进行语句的查询。先执行函数里的内容然后使用concat来执行
extractvalue():函数只有两个参数
extractvalue(xml_document, xpath_string) 通常sql报错注入的语句放在第二个参数位置,因为第一个参数是xml文档,不是合法 XML就会报错,也会执行语句但是局限较大。第二个参数使用concat可以进行拼接等操作,灵活性比较大
#爆破数据库,concat输入特殊字符报错,使用database查询,查询语句同联合查询类似。
select extractvalue(1,concat(~,database(),~))#注意点:这个函数以及updatexml函数都最多返回32个字符多余的会被截断,因此会采用截取子字符串的方法最后拼接来获取整个数据信息
#用法如下:
select extractvalue(1,concat(~,substr(database(),1,32),~))
(3)布尔盲注
连接符使用and
substr(str, pos, len)
str:要截取的字符串
pos:起始位置(从 1 开始计数,不是 0!)
len:截取的长度(可省略,如果省略则取到末尾)
利用了页面注入正确有回显,注入错误无回显,来判断注入情况,获取信息,因此可以单个字符判断
#1.获取数据库长度使用length()一个个试
length(database())=n;
#2.猜数据库名,有回显说明ascii值对应的字母是正确的,再猜测下一个
ascii(substr(database(),1,1))= [ascii值]
(4)延时盲注
sleep():使用sleep函数来让页面延迟响应通过响应时间判断正确与否
if(ascii(substr((database()), i, 1)) = N, SLEEP(5), 0)
(5)宽字节注入
由于后端使用转义字符导致的宽字节注入,即使用gbk编码,将转义字符与一个大于255的编码组合起来会自动当作gbk编码为一个汉字或其他语言的字,即需要两个字节,相当于把后端带的转义字符与注入的合并起来导致转义字符无效。
#吞掉后使用联合查询一样正常查询
id=-1 %df' union select 1,2,3 --+
(6)堆叠注入
堆叠注入即有些数据库支持多条语句输入,即可以使用分号结束语句并在后面执行其他语句也可以成功执行。
1'; insert into [表名] value(值);
(7)二次注入
由于数据库对已经确认过的数据过于信任没有进行二次验证导致出现了二次注入的漏洞
比如创建了一个admin’#用户 而数据库已经存在admin用户,那么再修改密码时没有验证用户身份而是直接找到这个用户进行修改,修改过程中’#有其他特殊含义,导致后面的原始密码被注释可以直接修改密码且修改的密码用户是admin,因为’#有特殊含义
3.防御
(1)使用预编译/参数化查询
把sql语句和数据分开处理,避免拼接。
预编译:即先告诉数据库这条 SQL 的“结构”(有两个 ?
占位符)。数据库编译并优化语句结构。再把参数安全地绑定进去。
**PHP (PDO):**是 PHP 提供的数据库访问抽象层。
支持 预编译,防 SQL 注入。
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt->execute([$username, $password]);
**Java (JDBC):**是 Java 的数据库连接 API,用于操作各种数据库。
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE username=? AND password=?"
);
stmt.setString(1, username);
stmt.setString(2, password);
ResultSet rs = stmt.executeQuery();
(2)使用Web应用防火墙(WAF)
对常见的sql注入payload进行拦截
二、XSS漏洞
1.类型
(1)反射型
经过服务器未经过滤直接返回到页面。一次性的
出现位置:搜索框
(2)存储型
上传存储到数据库,每次访问的时候都会加载,由于数据库没对前端输入的代码进行过滤
出现位置:留言板,评论区
(3)DOM型
没有经过服务器直接在前端执行,JS 直接拼接用户输入进 DOM。
出现位置:前端 JS 对 DOM 的处理
2.绕过方法
1.直接注入
<script>alert(/1/)</script>
2.大小写绕过
可能黑名单限制了script一些相关字符的输入,但是却忘记忽略大小写,因此可以尝试将关键字大小写修改尝试
<Script>alert(/1/)</Script>
3.双写绕过
可能对字符串进行过滤,但是替换为空字符而不是下划线之类的符号,导致可以使用双写绕过
<Scrscriptipt>alert(/1/)</Scscriptript>
4.img标签报错绕过
让img标签报错,报错时执行, 因此可以手动设置错误的图片路径导致报错响应
<img src=1 onerror='alert(1)'>
5.闭合标签绕过
如果使用了input标签可以尝试使用闭合绕过,不过要查看源码看看闭合方式
<--最简单的一种,也可以使用闭合+img/a/伪协议/大小写/双写 结合绕过 !-->
'> <script>alert(/1/)</script>
6.onclick绕过
input标签,可以使用闭合+onclick,实现点击弹窗,不用
' onclick='alert(1) <-后面应该有原有的闭合->
7.a标签伪协议绕过
JavaScript伪协议绕过,比如识别<script但是没有识别javascript时可以使用伪协议绕过
<a href=javascript: alert('1')>
8.a标签编码特殊绕过方式
有a标签存在时,可以用实体编码绕过,因为a标签的特殊性:可以将实体编码上传到数据库在点击标签时才进行解析并且会自动将编码解析
javascript:alert('1') #将sc使用实体编码编码
3.防御方法
1.黑名单限制
限制关键字,script,on,error
2.白名单限制
只允许一些类型通过
3.忽略大小写
使用strtolower同一转换为小写
4.使用编码
将所有输入的内容当作文本显示,没有特殊含义
三、文件上传漏洞
1.绕过方式
1.大小写绕过
后缀有黑名单限制但是忘记忽略大小写
.pHp .PHP .PhP .PHp
2.双写绕过
由于将匹配的字符串转为空字符,因此可以使用双写绕过
.ph(php)p #将括号中的php匹配成功替换为空字符了
3.php3,phtml绕过
php无法使用但是可能没有禁止php3后缀,所以可以使用备用类型绕过
.php3
4.空格绕过
首尾空格字符在文件中最后解析会把空格自动清掉,但是输入空格可能不会被过滤,从而绕过
.php
5.mime类型绕过
浏览器会读取文件的 扩展名 / 系统注册信息,然后决定 MIME
可以抓包看到一个content-type字段,后端仅验证content-type,因此可以直接修改数据包为需要的类型然后上传
6.前端绕过
前端进行验证,可以直接将前端的验证代码删除或者修改.
7. .htaccess区域解析配置文件绕过
由于限制了大多数类型文件,但是没有限制这个特殊文件.htaccess类型,这个文件配置后会解析同目录下的文件为设置的类型
1.解析所有文件为php:
SetHandler
SetHandler application/x-httpd-php
2.指定后缀名解析为php: AddHandler
指定的后缀名用空格隔开放在最后
AddHandler application/x-httpd-php .php .phtml .html
8. 00截断绕过
00截断,在文件名后加一个可以通过的类型使用%00连接,解析时会把00后面的内容删掉,也就是解析hello.php按照php类型解析
file=hello.php%00.jpg
2.防御方法
1.使用strtolower函数防止大小写
2.使用白名单限制
3.使用waf限制
四、CSRF和SSRF
1.CSRF(跨站请求伪造)
- 与XSS的区别
CSRF是跨站请求伪造。它伪造了用户的请求,并不是用户的真实意愿,而是通过诱导用户点击一些恶意链接使用用户的cookie信息等去执行一些用户并没有想执行的操作。
XSS是跨站脚本攻击。在用户浏览器执行恶意代码,直接窃取数据或劫持用户。
二者本质区别 csrf是在用户登陆的前提下使用用户的cookie信息执行一些转账或者发信息、修改信息其他的类似操作。而xss是用来窃取用户的cookie信息,只需要用户点击
- CSRF的应用场景
修改密码,转账,修改个人信息等操作
- CSRF漏洞利用
抓取数据包,找到表单信息,修改表单信息提交到服务器看看是否成功,成功则说明存在CSRF漏洞
- 成因
Web 应用只依赖 Cookie / Session 里的认证信息来识别用户身份,而没有验证请求本身的来源和合法性
2.SSRF(服务器端跨站请求伪造)
- 成因
由于服务器提供了从其他服务器获取数据的功能,比如翻译的软件,可以自动从其他服务器下载并获取数据。
比如从翻译软件翻译一个查ip的网页,会发现ip不是本机的,实际可能是服务器的,因为这个加载过程是服务器完成的。
3.CSRF与SSRF的区别
最大的区别就是
CSRF是客户端的,也就是用户受骗,“莫名不自觉”执行了自己没想执行的操作
SSRF是服务器端的,也就是服务器受骗,按着攻击者的想法执行一些危险操作。
五、文件包含和文件读取漏洞
1.区别
文件包含漏洞可以解析文件执行文件,而文件读取只会对文件的内容进行读取,不进行解析。
2.示例
文件读取,无法解析phpinfo文件,页面空白,看源码可以看到
<?php$file=$_GET['file'];
echo fgets(fopen($file,"r"));?>
且源码写了多行也只看的见一行.
同一个文件,使用文件包含可以执行解析.
<?php$file=$_GET['file'];
echo include $file;?>
行文件,而文件读取只会对文件的内容进行读取,不进行解析。
2.示例
文件读取,无法解析phpinfo文件,页面空白,看源码可以看到
<?php$file=$_GET['file'];
echo fgets(fopen($file,"r"));?>
[外链图片转存中…(img-l96bh0Un-1756297342382)]
且源码写了多行也只看的见一行.
[外链图片转存中…(img-SGRDaUnS-1756297342383)]
同一个文件,使用文件包含可以执行解析.
<?php$file=$_GET['file'];
echo include $file;?>
[外链图片转存中…(img-ffHaA7Pl-1756297342383)]