Loading... [关注我](https://blog.csdn.net/m0_64696290?type=blog) 2025/6/23 23:23 # 找环境VM 由于关于这篇文章的环境搭建追根溯源的文章在csdn上已经删除了,官网有些历史版本已经不提供了,及其费劲艰辛才找到合适的FGT_VM64-v7.2.2.F-build1255-FORTINET.out.ovf.zip没想到最终在波斯人的一个Fortinet交流群才找到所有的历史版本[Telegram: View @Fortinetsolutions](https://t.me/Fortinetsolutions/1137) 2025-06-24 07:42 # 配置fortigate-vm ## 导入forigate-vm  同意,然后命名保存到一个文件夹。 将网络适配器都改为NAT  登录账号admin 密码初始为空 登录后自己设置密码;我是本地测试直接就设置admin;admin了。 ## 配置ip地址 查看网卡配置 ```shell show system interface ```  网卡ip配置: 为了后续方便调试,这里的ip设置为自己另一台ubuntu同段的ip 注意要设置在vm的dhcp设置范围内,这是我的网段,各位按照虚拟机自己的来  ```shell config system interface edit port1 set mode static set ip 192.168.245.148 255.255.255.0 set allowaccess http https ping ssh telnet end ```  配置好之后show一下port1  如果访问WebUI发现需要联网激活(没有离线license),则仍需通过命令行让FortiGate能够访问Internet。 本例中默认网关设置为`192.168.245.2`,并将`port1`设置为互联网访问接口。请根据需要修改。 ```shell config router static edit 1 set gateway 192.168.245.2 set device port1 end ```  让后就能访问登录admin;admin了。  ## 激活授权 未授权时,FortiOS GUI 允许您使用 FortiCare 帐户凭据从 FortiCare 下载永久 VM 试用许可证。在 FortiGate VM 许可证页面中,对于“_您将如何授权此 VM?”_,选择_“评估许可证”_。  等待重启完毕后admin登录,记得不要更新。 运行以下命令来检查永久虚拟机试用License是否有效: ``` get sys stat ```  # 配置 sslvpn 我们需要开启sslvpn的功能,需要对防火墙进行以下配置 1、SSLVPN_address | subnet_addres | ubuntu22  再添加一个用户  添加一个用户组,并把之前注册的用户添加进新的用户组  修改 vpn 门户  修改full-access  修改后选择保存 进入 vpn 设置,配置如下  接着修改防火墙配置策略  之后https访问4433端口即可  我的火狐发现访问不了。以下解决问题 用 curl 验证网站到底支持什么 TLS 版本 curl -Iv --tlsv1.0 https://192.168.245.148:4433/ ### 临时启用 Firefox 支持 TLS 1.0 / 1.1 ⚠️ 这有**安全风险**,只建议**临时访问一些老旧网站测试使用**。 #### 操作步骤: 1. 在地址栏输入:`about:config` 2. 搜索: `security.tls.version.min` 3. 把值从 `3` 改为 `1` (表示最小 TLS 版本降到 1.0) 4. 刷新你想访问的网站试试看 > 设置值说明: > > - `1` = TLS 1.0 > - `2` = TLS 1.1 > - `3` = TLS 1.2(默认) > - `4` = TLS 1.3 > ✅ 访问成功后,建议及时把这个设置改回 `3`,避免访问其他不安全网站时被攻击。 > 从中真的是问题不断; >  > [!火狐浏览器无法访问网页提示PR_CONNECT_RESET_ERROR的解决方法] 1、打开火狐浏览器,在浏览器右上方点击“打开菜单”图标,在弹出的火狐浏览器菜单窗口中点击“选项”; 2、在火狐浏览器的选项页面的“常规”设置页面中找到“网络设置”这一项,点击“设置”按钮; 3、在弹出的“连接设置”窗口中查看是否设置了代理,如果设置了代理则选择“不使用代理服务器”; 4、如果上面的方法无法解决我们的问题在还可以试一试关闭火狐浏览器的DNS预取功能,在火狐浏览器地址栏输入“about:config”并点击“接受风险并继续”按钮; 5、然后搜索“network.dns.disablePrefetch”,并点击切换按钮将它的值从“false”修改为“true”,最后重启火狐浏览器就可以解决network.dns.disablePrefetch问题了; > [!方式二:在 Firefox 里临时忽略证书错误(不推荐)] > 可以打开 `about:config`,**临时关闭证书验证** > 搜索: > > - `security.ssl.enable_ocsp_stapling` → 设为 `false` > - `security.ssl.require_safe_negotiation` → 设为 `false` > - `network.dns.disableIPv6` → 设为 `true`(可选) > 然后重新访问 `https://192.168.245.148:4433`,看看是否弹出安全警告提示页。 > ⚠️ **此方式有安全风险,只用于本地测试环境** 终于成功访问4433端口  这里可以备份一下设置后续也可以用备份文件快速搭建  ![[CVE-2023-27997环境搭建以及堆溢出复现_20250625_1.conf]] # GDB调试环境搭建 #### 提取固件 在虚拟机关闭的情况下,右键,打开 关闭防火墙   挂载之后,我们就可以拿到一整个文件系统的文件,包括内核 需要将flatkc复制下来进行分析 #### vmlinux-to-elf处理一下flatkc无符号的问题 ```shell sudo apt install python3-pip liblzo2-dev sudo pip3 install --upgrade lz4 zstandard git+https://github.com/clubby789/python-lzo@b4e39df sudo pip3 install --upgrade git+https://github.com/marin-m/vmlinux-to-elf ``` ``` vmlinux-to-elf flatkc flatkc-efl ``` 看看吧没有符号和有符号放到IDA里面差别还是蛮大的吧。  #### 赋权、解压rootfs.gz ```shell cd ~/Dekstop/fortios chmod 777 rootfs.gz gzip -d rootfs.gz sudo cpio -idmv < ./rootfs sudo chroot . /sbin/xz --check=sha256 -d /bin.tar.xz sudo chroot . /sbin/ftar -xf /bin.tar ``` shell命令的后半部分就是在把rootfs里面的bin压缩包也解压出来(因为我们后面要制作一个smartctl的后门,就在这里目录里替换)。 #### busybox编译 如果编译过程出错了,可以换个更高的busybox版本去编译,(此时我的电脑竟然无法访问busybox的官网,所以去github上下载了一个) > [!以下有两个方法,重点是menuconfig的功能配置] > [Busybox编译安装「建议收藏」-腾讯云开发者社区-腾讯云](https://cloud.tencent.com/developer/article/2103409) > [Busybox下载和编译 - SigmaStarDocs](https://wx.comake.online/doc/cd823hf8s9hd22-SSA330/customer/development/software/330/sys/busybox%E4%B8%8B%E8%BD%BD%E5%92%8C%E7%BC%96%E8%AF%91.html) > 官网busybox.net实在是太难访问了在我这里,所以我直接github上下载了 > [Tags · mirror/busybox · GitHub](https://github.com/mirror/busybox/tags) ```bash #方法一: curl http://busybox.net/downloads/busybox-1.23.2.tar.bz2 | tar xjf - mkdir -p obj/busybox cd busybox-1.23.2 make O=../obj/busybox defconfig #独立在新文件中进行相关配置 cd ../obj/busybox make menuconfig #方法二: wget https://busybox.net/downloads/busybox-1.36.1.tar.bz2 tar -xjvf busybox-1.31.0.tar.bz2 sudo apt-get install libncurses5-dev meke menuconfig #自定义你要编译的 busybox 功能 make -j6 #方法三 https://github.com//mirror/busybox/archive/refs/tags/1_36_1.zip #解压然后cd进入 meke menuconfig #自定义你要编译的 busybox 功能 make -j6 ``` #### 后门程序smartctl (后面飞塔开机后在命令行中执行 `diagnose hardware smartctl` 系统会执行 /bin/smartctl 程序;) 这里的话,因为我们要开启telnet服务作为shell,笔者的思路是将telnet开启然后开放在22端口,我们就可以利用这个端口作为一个shell,然后还要把telnet服务的给替换成我们的gdbserver调试端口,只需要关闭即可 ```bash #include <stdio.h> void shell(){ system("/bin/busybox ls", 0, 0); system("/bin/busybox killall sshd && /bin/busybox telnetd -l /bin/sh -b 0.0.0.0 -p 22", 0, 0); return; } int main(int argc, char const *argv[]) { shell(); return 0; } ``` /bin/busybox telnetd -l /bin/sh -b 0.0.0.0 -p 22 是在尝试用 BusyBox 启动一个 Telnet 服务器,监听 0.0.0.0:22 端口,并在用户连接时直接运行 /bin/sh 作为登录 shell。 需要给他静态编译一下 ```bash gcc smartctl.c -static -o smartctl ``` 替换rootfs下的bin目录下的smartctl #### gdbserver ```bash https://github.com/hugsy/gdb-static ``` 下载个gdbserver,编译后也放入rootfs/bin下 ```shell https://github.com/hugsy/gdb-static sudo cp ../gdbserver-7.10.1-x64 ./bin sudo chmod +x ./bin/gdbserver-7.10.1-x64 ``` #### 拷贝和重建sh 编译之后我,把gdbserver和busybox还有我们编译的后门程序smartctl放到bin目录底下  但是需要在rootfs/ bin 目录中放入后门,后门是替换的替换 smartctl 文件生成一个反弹shell, 以及我这里放入一个 busybox ,但是需要做一个软链接 `ln -sn /bin/busybox bin/sh` 设备中默认没有 bash (sh)文件 (或者说他的 sh 功能比较鸡肋), 我是直接到rootfs/bin里面的路径下运行的如图命令(但是注意测试发现我这里的是/bin/busyboxs所以用的可能是操作系统的busybox1.30.1而不是我编译好复制进来的busybox1.36.1),如果你的路径不同,ln时候的命令有可能不同,然后我在外层文件夹chroot测试了一下可以执行里面的sh了,如图。  方法二:(可以看一下可选可不选,了解一下原理) 在 rootfs 构建目录下运行: ``` # 假设你已经安装了 busybox 到 ubuntu系统的/bin/busybox cd rootfs/bin rm -f sh ln -s /bin/busybox sh ``` 或者一行搞定(在 rootfs 根目录): `ln -sf /bin/busybox ./bin/sh` 如果没有把busybox 到ubuntu操作系统的/bin/busybox,那就可以到rootfs/bin的目录里`ln -s busybox sh` 总之最后可以chroot本地先测试一下。 这样当系统调用 `/bin/sh` 时,实际上运行的是 `/bin/busybox sh`,它就进入了 BusyBox 提供的 `sh` 模式。 我的失误测试不用跟着操作(因为我的系统下的/bin/busybox是v1.30.1, 但是编译后拷贝到rootfs/bin的busybox是v1.36.1): 可以看到我的sh竟然是Busybox1.30.1的  所以后面我又重来了一便 rm -f sh ln -s busybox sh  这样子确保我的是v1.36.1  然后重新打包。 #### 反编译--逆向 ##### 寻找真正的启动函数 ###### 1.反编译内核文件flatkc-elf ```c void __fastcall __noreturn init_post_isra_0(__int64 a1, _UNKNOWN **a2) { char v2; // al __int64 v3; // rax int v4; // edx int v5; // ecx int v6; // r8d int v7; // r9d char v8; // [rsp-8h] [rbp-8h] v8 = v2; async_synchronize_full(); free_initmem(); dword_FFFFFFFF80A1D980 = 1; numa_default_policy(); v3 = *(_QWORD *)(__readgsqword(0xB700u) + 1048); *(_DWORD *)(v3 + 92) |= 0x40u; if ( !(unsigned int)fgt_verify() )//校验函数 { off_FFFFFFFF809BC2C0 = "/sbin/init"; a2 = &off_FFFFFFFF809BC2C0; kernel_execve("/sbin/init", &off_FFFFFFFF809BC2C0, off_FFFFFFFF809BC1A0); } panic( (unsigned int)"No init found. Try passing init= option to kernel. See Linux Documentation/init.txt for guidance.", (_DWORD)a2, v4, v5, v6, v7, v8); } ``` 我们注入后门程序之后,要开机也是需要断点断在fgt_verify() 函数,将返回值修改 (ps: 由于flatkc是被压缩成bzImage格式的,所以转化成elf之后是不能压缩回去的,所以这里我们只能gdb patch。) ```python import gdb class SetRaxBreakpoint(gdb.Breakpoint): def __init__(self, bp_expr, rax_value, temporary=False): gdb.Breakpoint.__init__(self, bp_expr, gdb.BP_BREAKPOINT, False, temporary ) # super(SetRaxBreakpoint, self).__init__(spec, temporary) self.rax_value = rax_value self.silent = True def stop(self): gdb.execute('set $rax = {}'.format(self.rax_value)) gdb.execute('set architecture i386:x86-64') gdb.execute('set pagination off') r1 = SetRaxBreakpoint('*0xffffffff807ac11c', 0) #过fgt_verify() 函数 r2 = SetRaxBreakpoint('*0x4518C9', 1) # fgtstum r3 = SetRaxBreakpoint('*0x277fccc', 1) # rootfs检查 ``` ``` 在代码中,我们能知道,启动的是sbin中的init文件,在IDA中分析sbin/init文件发现如图 ```c __int64 __fastcall main(__int64 a1, char **a2, char **a3) { char *argv[4]; // [rsp+0h] [rbp-20h] BYREF argv[3] = (char *)__readfsqword(0x28u);//`argv[3]` 这里赋值为读取 FS 段偏移 `0x28` 处的内容(通常是栈保护、canary 值),可能是为了兼容栈平衡,但这个值后续没用到,可视为反编译残留。 sub_4017D0(a1, a2, a3); unlink("/sbin/init.chk");//删除 `/sbin/init.chk` 文件,通常是某种“标志文件”。- 可能表示“系统已启动”--也可能是启动一次后删除,用于防止重复执行(典型后门行为) if ( (int)sub_401AD0("bin") >= 0 && (int)sub_401AD0("migadmin") >= 0 && (int)sub_401AD0("node-scripts") >= 0 ) sub_401AD0("usr"); argv[0] = "/bin/init"; argv[1] = 0; execve("/bin/init", argv, 0); return 0; } ``` 🕵️♂️ 总结:这段代码的用途大概率是 - `sub_401AD0()` 可能是一个类似 `access()` 的函数,返回值 `>= 0` 表示路径存在。 - 如果 `/bin`, `/migadmin`, `/node-scripts` 都存在,就额外执行对 `/usr` 的访问(可能是触发其他逻辑)。 | 功能 | 说明 | | ---------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | | 初始化 | 调用`sub_4017D0()` 进行初始化工作 | | 清理标志 | 删除`/sbin/init.chk`(或某种标志/锁文件) | | 检查目录 | 检查某些关键目录是否存在,可能与部署后门有关 | | 执行 init | 最后正常转交控制权给`/bin/init`(系统启动) | | 行为隐蔽 | 没有命令行参数、没有环境变量,降低被发现的可能性 | | 这说明它**伪装成“init 进程”执行,实际上提前做了一些“隐藏处理”或“清除行为”** | | |  | | 它最终启动的又是/bin/init,所以还再去逆向分析bin中的init文件,显然这个69,830,248 字节的init才是真正的init。IDA中分析,我直接根据文章提示,搜索字符串“do_halt”,找到关键函数 然后根据交叉引用,找到带有”main“字符串的main函数哈哈(也可以搜索字符串,或者根据提示的提示的错误信息搜索字符串)  ##### 绕过main-->sub_44F1A0的fgtstum校验 我们对init文件中校验逻辑进行patch,rootfs的/bin/init 程序 main 函数中首先会有几处校验,  首先校验fgtsum{`fgtsum` 是 Fortinet(防火墙 FortiGate 系统)固件中常见的 **文件完整性校验工具**。},如果校验失败就会调用 do_halt 重启系统(重启内核),我们需要把call do_halt的部分都nop掉(其实分析懂了程序校验逻辑之后,还有很多种的绕过方法,我采用的是修改字节码较少的,可以看我后面分析)我们进入sub_44F1A0分析一下:  ```c pid = fork(); if (pid == 0) { // 子进程校验 if ( !(unsigned int)sub_447D40() ) exit(0); // 校验失败,退出码 0 else exit(1); // 校验成功,退出码 1 } else { // 父进程中等待子进程退出,取退出码 return sub_44DF20(pid); // 例如 waitpid() + WEXITSTATUS } //那么如果 `sub_44DF20(pid)` 返回 `0`(子进程 `exit(0)`),那就是**校验失败**; //如果 `sub_44DF20(pid)` 返回 `1`(子进程 `exit(1)`),那就是**校验成功**。 ``` (方法二就是修改.text:000000000044F1B6 008 jnz short loc_44F1E0,,,变成jz或者jmp都可,我用的是改成jmp,最为精巧只需改一个字节)   结果如下:  `sub_447D40()` **正是用于校验 `fgtsum` 的逻辑函数**,继续跟踪可以分析: 该函数通过读取两个文件内容,执行 **RSA 公钥验签操作**,验证某个校验值是否有效。 简单来说:有一句 memcmp(ptr, &v19, v8); // 比较原文和解密后的摘要 - ✅ **返回 `1`**:说明签名验证通过(fgtsum 文件没有被篡改) - ❌ **返回 `0`**:校验失败(可能内容被改过,或签名错误) 🔐 **它验证了文件内容是否符合签名校验 —— 类似 `fgtsum` 文件是否被篡改的检测逻辑。** ##### 过sub_44F1F0-->sub_277FC20下的rootfs检查!  `rootfs`(Root Filesystem)是 Linux 系统的根文件系统,包含了系统启动最基本的所有组件(/bin、/sbin、/etc 等)。检查 root 文件系统是否完整、安全、合法。 ``` ┌─────────────────────────────────────────────────────┐ │ sub_277FC20(a1) │ │ ┌───────────────────────────────────────────────┐ │ │ │ 1. 加载内嵌 RSA 公钥(unk_35CECE0) │ │ │ └───────────────────────────────────────────────┘ │ │ ↓ │ │ ┌───────────────────────────────────────────────┐ │ │ │ 2. 校验 rootfs.gz 对应的 .chk 签名 │ │ │ │ └── 调用 sub_2745F70("/data/rootfs.gz", ...)│ │ │ └───────────────────────────────────────────────┘ │ │ ↓ 成功(返回 0) │ │ ┌───────────────────────────────────────────────┐ │ │ │ 3. 校验 flatkc 对应的 .chk 签名 │ │ │ └───────────────────────────────────────────────┘ │ │ ↓ 返回值 │ └─────────────────────────────────────────────────────┘ ``` (方法一:最小 patch 修改返回值逻辑.text:000000000044F22B 008 40 0F 94 C7 setz dil)  如果你不想动太多字节,也可以只改: `setz dil → nop nop mov dil, 0` 机器码: - `setz dil` 是 `40 0F 94 C7` - `mov dil, 0` 是 `B7 00` 所以你可以改: `40 0F 94 C7 → 90 90 B7 00`   > [!(方法二: sub_277FC20函数头修改不执行直接返回1)] > 如果你想更彻底控制 `rootfs 检查通过`,建议就 patch 掉 `sub_277FC20` 的返回值: > 📌 把函数开头改成: > `mov eax, 1 ret` > 机器码为: > `B8 01 00 00 00 C3` > 用 `IDA` → `Edit` → `Patch program` → `Assemble`,输入上面指令即可。 我是用的方法一结果如下,可以看只要成功创建子进程进行校验了都会exit(0):  ##### 总结 但是通过上面的修改可能只是过了两段检查,但是还有一些别的检查并没有过去,所以导致了我的fortigate现在开机无限重启,这是因为可看到IDA在bin的main函数96-109行之间不只是两个if判断进入了do_halt(sub__44F070),可能还有其它我们没有分析的,所以可以我们使用更简单的补丁,直接将 do_halt(sub__44F070) 函数的第一条指令改为 ret,这样就算无法通过验证,也不会执行重启操作。以上是我遇到无限重启问题借鉴于[搭建 FortiGate 调试环境 (一) | Catalpa's Site](https://wzt.ac.cn/2023/03/02/fortigate_debug_env1/#%E6%A4%8D%E5%85%A5%E5%90%8E%E9%97%A8%E5%B9%B6%E5%90%AF%E5%8A%A8) (方法二也可以全部nop掉96-109行之间的call sub__44F070; 借鉴于[VMWare安装破解FortiGate7.4.2](https://bbs.kanxue.com/thread-284794.htm#msg_header_h3_6))  #### 重打包+调试 看上面的截图可以知道因为我是用sudo用户最后解压的,所以文件上有把小锁,所以为了保险起见,我sudo chmod 777 -R fortios/ 然后替换掉原来的init,再重新打包,替换掉原来的rootfs.gz ```shell #压缩/bin文件 sudo chroot . /sbin/ftar -cf bin.tar bin sudo chroot . /sbin/xz --check=sha256 -e bin.tar #这里记得把/bin文件移出当前目录 sudo find ./ | cpio -H newc -o > ../rootfs.raw cd ../ sudo cat ./rootfs.raw | gzip > rootfs.gz # 进入挂载的硬盘目录 也就是fortios sudo rm ./rootfs.gz sudo cp ~/Desktop/rootfs.gz ./ ``` 在vm目录下的.vmx文件中添加下列信息  ``` debugStub.listen.guest64="TRUE" debugStub.listen.guest64.remote="TRUE" debugStub.port.guest64="12345" debugStub.listen.guest32="TRUE" debugStub.listen.guest32.remote="TRUE" debugStub.port.guest32="12346" ``` > [!升级pwngdb] > 我遇到一些问题原来安装的pwndbg插件在调试这个程序的时候不出现调试界面,所以我安装了最新的pwndbg > > ``` > #1. 克隆最新版源码 > git clone https://github.com/pwndbg/pwndbg.git ~/pwn_tools/pwndbg > cd ~/pwn_tools/pwndbg > #2. 安装并激活虚拟环境(推荐,避免污染系统) > python3 -m venv .venv > source .venv/bin/activate > #3. 更新 pip > pip install --upgrade pip setuptools > #4. 安装 Pwndbg 所需依赖 > pip install -r requirements.txt > #5. 初始化配置(会自动写入 ~/.gdbinit) > ./setup.sh > ``` 然后再 ```shell gdb file flatkc-efl target remote 192.168.245.1:12345 ``` 先在ubuntu准备好gdb,然后开启foritage,在如下booting the kernel界面出来1~2秒后,target链接。(注意这是你的物理主机的ip,要调试VM)   然后就可按c运行到0xffffffff807AC117的call fgt_verify的断点位置,按n运行到test的对比位置时候,修改rax的值为0 ```shell # 查看所有寄存器 (gdb) info register # 可以简写成 i r # 查看单个寄存器 (gdb) i r rax # 修改寄存器 (gdb) set $rax=3 ```  ok直接c执行,可以看到正常开机了(如果你的哪里拦住了就patch哪里,排查init文件看看哪里被拦住了,根据字符串搜索,需要对此处进行patch操作,直到正常启动) 在fortigate虚拟机admin(我的用户密码)登录后运行`diagnose hardware smartctl`会处罚我们前面修改打包进去的后门程序,此时只需要telnet 22端口即可连接。   启动gdbserver,并将其附加到 `sslvpnd` 进程上 ```shell # 给gdbserver运行权限 /bin/busybox chmod +x ./bin/gdbserver-7.10.1-x64 busybox ls -l /bin/gdbserver-7.10.1-x64 /bin/busybox kill -9 $(/bin/busybox pidof telnetd) && ./bin/gdbserver-7.10.1-x64 0.0.0.0:23 --attach $(/bin/busybox pidof sslvpnd) # killall telnetd && gdbserver :23 --attach sslvpn_pid ``` 不知都为啥我也一样,可能会报错、多试几次  然后起一个新的gdb终端,就可以连23端口正常调试了  就可以快乐的调试了,笔者是断在了jemalloc的位置 ```shell gdb b je_malloc if $rdi>0x1c00 && $rdi < 0x2000 target remote 192.168.245.148:23 ``` # poc ```shell git clone https://github.com/BishopFox/CVE-2023-27997-check cd CVE-2023-27997-check python3 -m venv venv source venv/bin/activate python3 -m pip install -r requirements.txt ``` 但是我这里遇到了一个问题,解决证书版本问题:默认的证书配置是tlsv1.0才能访问,而且但是现在的openssl觉得不安全,已经弃用了这个版本,所以我们可以用方案:修改配置文件,和代码,来降低安全等级,允许弱加密。 ### 方案一: 在/etc/ssl/openssl.cnf中修改: ``` [system_default_sect] MinProtocol = TLSv1 CipherString = DEFAULT:@SECLEVEL=0 ``` 使用`openssl s_client -connect 192.168.245.148:4433 -tls1`命令得知结果。 SECLEVEL=1 仍然会限制 512 位 RSA 密钥和 SHA1 签名,只有 SECLEVEL=0 才允许这些“极其不安全”的参数。 python的代码层面 增加 TLSv1Adapter: ```python import requests import ssl from requests.adapters import HTTPAdapter from urllib3.poolmanager import PoolManager class TLSv1Adapter(HTTPAdapter): def init_poolmanager(self, connections, maxsize, block=False): ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) ctx.set_ciphers('DEFAULT:@SECLEVEL=0') # 降低安全等级,允许弱加密 ctx.verify_mode = ssl.CERT_NONE ctx.check_hostname = False self.poolmanager = PoolManager(num_pools=connections, maxsize=maxsize, block=block, ssl_context=ctx) ``` 然后把所有创建 Session 的部分替换成:: ```python s = requests.Session() s.mount('https://', TLSv1Adapter()) ``` > [!说明解释] > > - 自定义 `TLSv1Adapter`,强制使用 TLS 1.0 并设置安全级别为 0,允许服务器使用弱加密和证书。 > - `s.mount('https://', TLSv1Adapter())` 让这个 Session 对所有 HTTPS 请求都用该适配器。 > - 其他请求的写法不变,继续用 `verify=False` 忽略证书校验。 > - 这样你的脚本就能适配只支持 TLS 1.0 的 FortiGate 设备,避免 SSL 错误。 最后成功运行,证明有漏洞  # 感谢 参考资料:[VMWare安装破解FortiGate7.4.2](https://bbs.kanxue.com/thread-284794.htm) CVE-2023-27997漏洞检测工具:高效、安全的FortiGate SSL VPN漏洞评估:[GitHub - BishopFox/CVE-2023-27997-check: Safely detect whether a FortiGate SSL VPN instance is vulnerable to CVE-2023-27997 based on response timing](https://github.com/BishopFox/CVE-2023-27997-check) [CVE-2023-27997 FortiGate SSLVPN 堆溢出漏洞分析与利用](https://www.cnblogs.com/L1nyun/articles/18421524 "发布于 2024-09-19 22:42") [搭建 FortiGate 调试环境 (一) | Catalpa's Site](https://wzt.ac.cn/2023/03/02/fortigate_debug_env1/#%E6%A4%8D%E5%85%A5%E5%90%8E%E9%97%A8%E5%B9%B6%E5%90%AF%E5%8A%A8) [VMWare安装破解FortiGate7.4.2](https://bbs.kanxue.com/thread-284794.htm#msg_header_h3_6) [CVE-2022-42475-FortiGate-SSLVPN-HeapOverflow](https://bestwing.me/CVE-2022-42475-FortiGate-SSLVPN-HeapOverflow.html) [使用vmware workstation+gdb调试虚拟机的启动过程\_vmware gdb-CSDN博客](https://blog.csdn.net/weixin_52111404/article/details/131509203) 借鉴:[CVE-2023-27997环境搭建以及堆溢出复现 | 1uckyc's blog](https://1uckyc.github.io/2024/04/22/CVE-2023-27997%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA%E4%BB%A5%E5%8F%8A%E5%A0%86%E6%BA%A2%E5%87%BA%E5%A4%8D%E7%8E%B0/) 最后修改:2025 年 07 月 07 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 8 如果觉得我的文章对你有用,请随意赞赏
1 条评论
乙太师傅您好,我是一名大学在读pwner,也想尝试复现这个漏洞,但是我没办法获取到fortigate7.2.4版本。使用7.0.0版本尝试复现时,在重打包rootfs.gz回虚拟机的启动盘时出现了”cp: 写入 './rootfs.gz' 时出错: 设备上没有空间“的报错。如果师傅还有这个镜像的话,能劳烦您通过邮件分享一份吗,谢谢。