目录
1.CSRF和XSS区别
CSRF(跨站请求伪造)
攻击方式:CSRF攻击利用用户已经登录的身份,诱导用户在不知情的情况下执行恶意操作。例如,攻击者可能会诱导用户点击一个恶意链接,从而在用户不知情的情况下执行转账操作。
目标:CSRF的目标是利用用户的身份执行未授权的操作,通常是对服务器端的操作。
依赖条件:需要用户已经登录目标网站,并且在攻击发生时保持登录状态。
防御措施:常见的防御措施包括使用CSRF令牌、验证Referer头、使用SameSite Cookie属性等。
XSS(跨站脚本攻击)
攻击方式:XSS攻击通过在网页中注入恶意脚本,利用浏览器执行这些脚本。攻击者可以通过输入表单、URL参数等方式注入恶意代码。
目标:XSS的目标是窃取用户数据、劫持用户会话、修改网页内容等,主要是对客户端的攻击。
依赖条件:不需要用户登录,只要用户访问包含恶意脚本的页面即可。
防御措施:常见的防御措施包括对用户输入进行严格的验证和过滤、使用内容安全策略(CSP)、对输出进行编码等。
主要区别
攻击方向:CSRF是单向攻击,攻击者只能发起请求,不能获取响应;XSS是双向攻击,攻击者可以获取并利用响应数据。
依赖用户状态:CSRF需要用户处于登录状态,而XSS不需要。
攻击目标:CSRF主要针对服务器端操作,而XSS主要针对客户端操作。
2.CSRF攻击步骤
1. 用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;
2.在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;
3. 用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;
4. 网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;
5. 浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。
3.CSRF手工构造POST型页面方法
1. 确定目标URL和参数
首先,需要确定目标网站的URL以及需要在POST请求中提交的参数。这通常需要使用浏览器开发者工具(如Chrome的DevTools)或网络抓包工具(如Burp Suite)来捕获和分析HTTP请求。
2. 编写恶意表单
根据分析得到的目标网站的POST请求信息,编写一个HTML表单。表单的action属性应设置为目标网站的URL,method属性应设置为POST。表单内部应包含与目标POST请求相匹配的输入字段,并预设好攻击者希望提交的数据。
<form id="csrfForm" action="http://example.com/target" method="POST">
<input type="hidden" name="param1" value="value1">
<input type="hidden" name="param2" value="value2">
<!-- 更多隐藏字段 -->
</form>
3. 隐藏表单元素
为了增加欺骗性,可以将表单中的输入字段设置为hidden类型,这样用户就看不到这些字段,但表单提交时仍会包含这些数据。
4. 自动提交表单
为了确保表单在用户不知情的情况下自动提交,可以在页面中添加一段JavaScript代码,自动触发表单提交。
<script type="text/javascript">
document.getElementById('csrfForm').submit();
</script>
5. 诱骗用户访问该页面
将构造好的HTML页面发布到恶意网站上,或通过电子邮件、社交媒体等方式发送给目标用户。诱骗用户点击表单中的提交按钮,用户一旦点击,就会在不知情的情况下向目标网站发送包含恶意数据的POST请求。
###实例
<!DOCTYPE html>
<html>
<head>
<title>CSRF Attack</title>
</head>
<body>
<form id="csrfForm" action="http://example.com/target" method="POST">
<input type="hidden" name="param1" value="value1">
<input type="hidden" name="param2" value="value2">
<!-- 更多隐藏字段 -->
</form>
<script type="text/javascript">
document.getElementById('csrfForm').submit();
</script>
</body>
</html>
4.说明token类CSRF利用方法
1. 利用XSS漏洞
如果目标网站存在XSS(跨站脚本)漏洞,攻击者可以利用该漏洞获取受害者的CSRF Token。具体步骤如下:
1)攻击者在目标网站注入恶意脚本。
2)当受害者访问包含恶意脚本的页面时,脚本会在受害者的浏览器中执行,并读取页面中的CSRF Token。
3)恶意脚本将Token发送给攻击者的服务器。
4)攻击者使用获取到的Token构造并发送恶意请求,从而绕过CSRF防护。
2. 弱随机性或可预测的Token
如果CSRF Token的生成算法存在弱点或不够随机,攻击者可能能够预测或推测出合法的Token。例如:
1)某些系统可能会使用时间戳、用户ID等可预测的信息来生成Token。
2)攻击者通过分析这些规律,构造出有效的CSRF Token,从而绕过防护。
3. Token泄露
1)通过Referer头泄露:如果Token被包含在URL中,Referer头可能会将Token泄露给第三方。
2)日志文件泄露:Token可能会被记录在服务器日志中,攻击者可以通过访问日志文件获取Token12。
4. 双重提交Cookie漏洞
有些防御措施会将CSRF Token存储在Cookie中,并要求在请求中双重提交Cookie。然而,如果Cookie不设置为HttpOnly,攻击者可以通过JavaScript(例如XSS攻击)读取Token值,从而绕过防护。
###防御措施
1.严格过滤和转义用户输入,防止XSS漏洞。
2.使用强随机性算法生成CSRF Token,确保Token不可预测。
3.避免在URL中包含Token,并设置Cookie为HttpOnly,防止Token泄露。
4.定期审计和监控,及时发现和修复安全漏洞。
5.SSRF常用伪协议
1.file://
用于读取服务器上的本地文件。例如:
file:///etc/passwd 读取密码文件
file:///etc/hosts 显示当前操作系统网卡的IP地址
file:///proc/net/arp 显示ARP缓存表,寻找内网其他主机
2.dict://
字典服务协议,可以用于端口扫描和获取内网信息。例如:
dict://ip:6739/info 访问字典资源
3.ftp://
用于访问FTP服务器上的文件,可以进行目录扫描和文件读取
4.http:// 和 https://
常规URL形式,允许通过HTTP方法访问文件或资源。例如:
http://www.baidu.com/file.php?var1=val1&var2=val21
5.gopher://
利用范围较广,可以用于GET提交、POST提交、Redis、FastCGI、SQL等。例如:
gopher://<目标IP>:<端口>
/_GET%20/name.php%3fname=123%20HTTP/1.1%0d%0AHost:%20172.250.250.4%0d%0A
6.SSRF pikachu靶场通关
SSRF(curl)
打开页面,只有一个链接,点击试试
这里出现了404报错,因为一般默认都是80端口,而我设置了一个8888端口,所以我们只需将后面的127.0.0.1加上一个8888即可
观察URL,发现可以把URL改成其他的地址和端口
这里我们修改为www.baidu.com,出现了百度的搜索框
也可以将其修改为本地文件的地址
修改端口号
SSRF(file_get_content)
点击读诗
file_get_content可以对本地和远程文件进行读取
比如我们可以在这里读上一首诗,将info2.php改为info1.php,就出现了上一关的内容
再读个本地的文件
读取成功
7.SSRF靶场通关时根据源代码说明漏洞成因
SSRF(curl)
源代码
1.未过滤的用户输入:代码直接使用用户输入的 URL 参数 ($_GET['url']) 来初始化 curl 请求,而没有进行适当的验证或过滤。
2.支持多种协议:curl 支持多种协议(如 HTTP、HTTPS、FTP、FILE 等),攻击者可以利用这些协议访问不应公开的资源。例如,我上面使用 file:///D:/11.txt 。
3.返回请求结果:代码将 curl_exec 的结果直接返回给前端,攻击者可以通过构造恶意请求来获取服务器上的敏感信息
SSRF(file_get_content)
源代码
1.未过滤的用户输入:代码直接使用用户输入的 file 参数 ($_GET['file']) 来读取文件内容,而没有进行适当的验证或过滤。
2.支持多种协议:file_get_contents 函数不仅可以读取本地文件,还可以通过 URL 读取远程文件。攻击者可以利用该函数访问不应公开的资源。例如,file=file:///D:/11.txt
3.返回请求结果:代码将 file_get_contents 的结果直接返回给前端