GTFOBins 部署到 Windows 的 3 种简单方法
网站地址:GTFOBins
Github项目地址:GTFOBins/GTFOBins.github.io
前言
GTFOBins 是一个非常实用的网站,主要收录了许多 Linux 二进制程序在特定场景下的用法,例如 Shell、文件读取、文件写入、SUID、sudo、Capabilities 等。很多人在学习提权、渗透测试、CTF、系统安全时,都会经常用到它。
官方站点本身访问很方便,但也有一些用户希望把它部署到自己的 Windows 电脑上,本地使用、本地搜索,或者做一个自己专属的离线知识库。
我在 Windows 环境下实际部署 GTFOBins 的过程中,前后尝试了几种方法,踩了一些坑,最后总结出 3 种比较简单、比较实用的方案。
这篇文章就来详细讲一讲:
- 方法 1:正常方式,虽然会报一堆错误、要等几分钟,但最后也能正常访问
- 方法 2:改 Dockerfile,采用"先生成静态站,再秒开"的模式
- 方法 3:用两个
.bat脚本,把操作自动化,双击即可使用
一、准备工作
在开始之前,建议先准备好下面这些东西。
1. 操作系统
本文环境为:
- Windows 10 / Windows 11
- CMD / PowerShell
- Docker Desktop
2. 安装 Docker Desktop
因为 GTFOBins 官方仓库本质上是一个基于 Jekyll 的静态站点,而 Jekyll 这一套在 Windows 原生环境里折腾起来通常比较麻烦。
所以这里推荐最省事的方法:直接使用 Docker Desktop。
如果你还没有安装 Docker Desktop,先安装并启动它。
下载地址:Docker Desktop
3. 克隆 GTFOBins 仓库
先把仓库拉到本地,例如放在桌面:
CMD / PowerShell
powershell
cd C:\Users\你的用户名\Desktop
git clone https://github.com/GTFOBins/GTFOBins.github.io.git
cd GTFOBins.github.io

!TIP
后面所有操作,默认都在这个目录下完成。
二、方法 1:正常方式部署
这是最直接的一种方法。
优点是步骤比较"原始"、比较贴近官方仓库的默认用法;缺点也很明显:启动慢、报错多、每次都要等一阵子。
方法 1 的思路
核心思路就是:
- 先构建镜像
- 再在容器里运行 Jekyll
- 将本地目录挂载到容器中
- 通过 4000 端口访问
第一步:构建镜像
进入仓库目录后,运行:
CMD / PowerShell
powershell
docker build -t gtfobins-local .

如果 Docker Desktop 已正常启动,这一步一般可以顺利完成。
第二步:运行站点
直接运行下面这条命令:
PowerShell:
powershell
docker run --rm -it --entrypoint sh -p 4000:4000 -v "${PWD}:/GTFOBins/" gtfobins-local -lc "bundle install && bundle exec jekyll serve --host=0.0.0.0 --no-watch"
或者用CMD命令也行:
CMD:
bash
docker run --rm -it --entrypoint sh -p 4000:4000 -v "%cd%:/GTFOBins/" gtfobins-local -lc "bundle install && bundle exec jekyll serve --host=0.0.0.0 --no-watch"
!IMPORTANT
看到Error报错不要慌,报错完后等几分钟就好了
第三步:等待站点生成
执行后,终端里通常会出现以下几种情况:
1. 先安装 Ruby 依赖
会看到类似这样的内容:
text
Fetching gem metadata from https://rubygems.org/.........
Installing ...
Bundle complete!
这一步是在安装 Jekyll 所需的 gem 依赖。

2. 然后开始生成站点
接着会看到:
text
Configuration file: /GTFOBins/_config.yml
Source: /GTFOBins
Destination: /GTFOBins/_site
Generating...

3. 中间会报出一大堆错误
例如:
text
Error: could not read file /GTFOBins/_gtfobins/bash: undefined method `split' for nil
Error: could not read file /GTFOBins/_gtfobins/tar: undefined method `split' for nil
Error: could not read file /GTFOBins/_gtfobins/zsh: undefined method `split' for nil
第一次看到这些报错时,很多人会以为部署失败了。
但实际上,在不少情况下,这些报错不会阻止站点最终启动。

4. 最后真正成功的标志
只要你最后看到了类似内容:
text
done in 158.xxx seconds.
Server address: http://0.0.0.0:4000
Server running... press ctrl-c to stop.
那就说明站点已经成功运行了。

这时在浏览器访问:
text
http://localhost:4000
就可以打开 GTFOBins 页面。
方法 1 的特点
优点
- 最接近"直接跑官方项目"的方式
- 不需要额外改动太多内容
- 能成功跑起来
缺点
- 每次启动前都可能重新安装依赖
- 会输出大量报错信息,看起来很吓人
- 从执行命令到真正能访问,往往要等几分钟
- 不够优雅,日常使用体验一般
方法 1 适合谁
这种方式适合:
- 想先验证"能不能跑起来"的人
- 想原样体验项目本地运行方式的人
- 暂时不在意启动速度的人
如果你只是想证明"这个站在 Windows 上确实能本地部署",那么方法 1 已经够用了。
三、方法 2:修改 Dockerfile,采用"先生成静态站,再秒开"的模式
方法 1 最大的问题,不是"不能用",而是"每次都慢"。
所以更推荐的方法是:把站点先生成成静态文件,然后再用轻量 Web 服务直接打开。
这样一来,Jekyll 的那一套构建过程只需要在生成时执行一次,后面访问站点时就不需要再跑 Ruby、Bundler、Jekyll 这些东西了。
方法 2 的核心思路
思路分成两步:
- **先生成
_site ** 静态目录 - 再用 Nginx 直接提供静态网页服务
这样做的好处是:
- 平时启动快
- 不用每次都重新跑 Jekyll
- 使用体验明显更好
第一步:修改 Dockerfile
找到项目目录中的 Dockerfile 文件,用记事本、VS Code 或其他编辑器打开。
bash
notepad Dockerfile
把原来的内容全部替换成下面这份:
dockerfile
FROM ruby:3.3.4
WORKDIR /GTFOBins/
COPY ./Gemfile ./Gemfile.lock ./
RUN bundle install
CMD ["sh"]

为什么要这样改
原来的 Dockerfile 在构建和运行逻辑上,更偏向"直接 serve"。
而我们现在想做的是:
- 把依赖提前安装好
- 让镜像变成一个可复用的构建环境
- 之后手动执行
jekyll build
这样可以避免每次启动网站都重新做很多事。
第二步:重新构建镜像
修改 Dockerfile 后,重新构建镜像:
CMD / PowerShell:
powershell
docker build --no-cache -t gtfobins-local .
这一步是为了让新的 Dockerfile 生效。
第三步:一次性生成静态站点
执行下面的命令:
PowerShell:
powershell
docker run --rm -it --entrypoint sh -v "${PWD}:/GTFOBins/" gtfobins-local -lc "bundle exec jekyll build"
或者用CMD命令:
bash
docker run --rm -it --entrypoint sh -v "%cd%:/GTFOBins/" gtfobins-local -lc "bundle exec jekyll build"
这一步会把 Jekyll 站点生成到本地目录中的 _site 文件夹里。
执行完成后,你会在项目目录中看到 _site 文件夹,这就是最终生成好的静态网站内容。
!IMPORTANT
这里依旧会报错Error,依旧要等几分钟


第四步:使用 Nginx 直接启动站点
当 _site 生成完成后,就可以直接运行:
PowerShell:
powershell
docker run --rm -p 4000:80 -v "${PWD}/_site:/usr/share/nginx/html:ro" nginx:alpine
或者用CMD命令:
bash
docker run --rm -p 4000:80 -v "%cd%\_site:/usr/share/nginx/html:ro" nginx:alpine

然后可以马上浏览器访问:
text
http://localhost:4000
此时页面打开通常会比方法 1 快很多,因为它只是单纯地在提供静态文件,不再需要走 Jekyll 的完整生成流程。
方法 2 的特点
优点
- 生成和访问分离,逻辑更清晰
- 平时打开站点明显更快
- 不需要每次都重新走完整构建流程
- 更适合长期本地使用
缺点
- 需要手动修改 Dockerfile
- 改完后要重新 build 镜像
- 如果你修改了源文件,就需要重新生成
_site
方法 2 适合谁
这种方式适合:
- 想把 GTFOBins 当作日常本地知识库使用的人
- 不想每次启动都等几分钟的人
- 希望部署方式更稳定、更清爽的人
如果你只想"用",而不是"研究 Jekyll 怎么跑",那方法 2 会比方法 1 更舒服。
四、方法 3:使用两个 .bat 文件,把操作自动化
如果说方法 2 已经解决了"打开太慢"的问题,那么方法 3 解决的就是另一个问题:
每次都要手动输入命令,还是有点麻烦。
所以第三种方法,就是把这些命令封装成两个批处理文件,也就是 .bat 文件。
这样以后基本只需要双击文件,不需要再手动敲命令。
方法 3 的核心思路
我们准备两个批处理脚本:
重新生成站点.bat启动网站.bat
分别负责:
- 重新生成
_site - 启动静态网站
先说明一个非常重要的点
很多人一看到 .bat 文件,就会以为以后是不是完全不需要 Docker 了。
答案是不是。
.bat 文件只是把你原本手动敲的命令自动化了,
所以:
- 你仍然需要安装 Docker Desktop
- 你仍然需要先启动 Docker Desktop
- 只是以后不需要自己手动输入那些命令了
也就是说,方法 3 的本质是:
"继续用 Docker,但把操作变成双击执行。"
第一个脚本:重新生成站点.bat
这个脚本的作用是:
- 检查 Docker 是否启动
- 检查镜像是否存在
- 如果镜像不存在,就自动 build
- 然后执行
jekyll build - 生成
_site
!IMPORTANT
双击重新生成站点.bat后会报错Error,等几分钟就好了


脚本内容如下:
bat
@echo off
setlocal
cd /d "%~dp0"
echo [1/3] Checking Docker...
docker info >nul 2>&1
if errorlevel 1 (
echo Docker Desktop is not running. Please start Docker Desktop first.
pause
exit /b 1
)
echo [2/3] Checking local image...
docker image inspect gtfobins-local >nul 2>&1
if errorlevel 1 (
echo Local image not found. Building gtfobins-local...
docker build -t gtfobins-local .
if errorlevel 1 (
echo Build failed.
pause
exit /b 1
)
)
echo [3/3] Generating static site...
docker run --rm --entrypoint sh -v "%cd%:/GTFOBins/" gtfobins-local -lc "bundle exec jekyll build"
if errorlevel 1 (
echo Static site generation failed.
pause
exit /b 1
)
echo.
echo Done. The static site has been generated into the _site folder.
pause
第二个脚本:启动网站.bat
这个脚本的作用是:
- 检查
_site是否存在 - 检查 Docker 是否启动
- 如果站点已经在运行,就直接打开浏览器
- 如果没在运行,就启动一个 Nginx 容器
- 打开
http://localhost:4000
脚本内容如下:
bat
@echo off
setlocal
cd /d "%~dp0"
if not exist "_site\index.html" (
echo _site\index.html was not found.
echo Please run "重新生成站点.bat" first.
pause
exit /b 1
)
echo Checking Docker...
docker info >nul 2>&1
if errorlevel 1 (
echo Docker Desktop is not running. Please start Docker Desktop first.
pause
exit /b 1
)
docker ps --format "{{.Names}}" | findstr /i /x "gtfobins-site" >nul
if not errorlevel 1 (
echo Site is already running: http://localhost:4000
start "" http://localhost:4000
exit /b 0
)
docker rm -f gtfobins-site >nul 2>&1
echo Starting site...
docker run -d --name gtfobins-site -p 4000:80 -v "%cd%\_site:/usr/share/nginx/html:ro" nginx:alpine >nul
if errorlevel 1 (
echo Failed to start the site container.
pause
exit /b 1
)
echo Site started: http://localhost:4000
start "" http://localhost:4000
这两个脚本应该放在哪里
建议把它们直接放到 GTFOBins 项目根目录,也就是:
text
C:\Users\你的用户名\Desktop\GTFOBins.github.io
因为脚本里默认就是按"当前脚本所在目录"查找项目文件、Dockerfile 和 _site。
方法 3 的正确使用方式
很多人最关心的就是这个问题:
以后我到底该怎么点?
很简单。
第一次使用
先双击:
text
重新生成站点.bat
它会生成 _site 目录。
生成完成后,再双击:
text
启动网站.bat
它会启动站点,并自动打开浏览器。
以后平时使用
如果你没有修改 GTFOBins 源码内容,那么以后只需要双击:
text
启动网站.bat
就够了。
什么时候需要再点"重新生成站点.bat"
只有在以下情况,才需要重新生成:
- 你修改了站点源码
- 你更新了 GTFOBins 仓库内容
- 你删除了
_site - 你想重新构建最新版本
方法 3 的特点
优点
- 最适合日常使用
- 双击即可操作,省去了手动敲命令
- 对不想记命令的人非常友好
- 基本相当于"图形化了一半"
缺点
- 本质上还是依赖 Docker
- 首次生成时仍然需要构建环境
- 如果 Docker Desktop 没开,脚本也无法正常工作
方法 3 适合谁
这种方式非常适合:
- 想长期保留一个本地 GTFOBins 站点的人
- 不想每次都复制粘贴命令的人
- 希望操作尽量简单的人
如果你已经确认方法 2 没问题,那再加上方法 3 的脚本自动化,基本就是最省心的组合了。
五、3 种方法怎么选
如果你是第一次接触,可以按照下面的思路选择。
1. 只想先验证能不能运行
选 方法 1
因为它最直接,虽然报错多、等待久,但最终能跑起来。
2. 想追求更好的使用体验
选 方法 2
因为它把"生成"和"访问"分开了,后续打开站点更快。
3. 想长期使用,而且不想记命令
选 方法 3
因为它建立在方法 2 的基础上,把操作自动化了,体验最好。
六、个人建议
如果只是临时试试,方法 1 够用。
如果你已经确定要长期在 Windows 本地使用 GTFOBins,那么我的建议是:
优先使用 方法 3 。
也就是:
第一次部署
- 安装并启动 Docker Desktop
- 克隆 GTFOBins 仓库
- 修改 Dockerfile
- 执行"
重新生成站点.bat" - 执行"
启动网站.bat"
后续日常使用
- 平时只点:
启动网站.bat - 修改内容后再点:
重新生成站点.bat
七、常见问题
1. 那些 undefined method 'split' for nil 的报错要不要紧?
如果最后能看到:
text
Server running...
或者你能正常访问 http://localhost:4000,那通常就不用太担心。
至少在实际部署中,这些报错很多时候并不会阻止站点最终运行。
2. .bat 文件是不是说明以后完全不用 Docker 了?
不是。
.bat 文件只是帮你自动执行 Docker 命令,所以 Docker Desktop 还是要装,还是要启动。
3. 我是不是只需要点一次"重新生成站点.bat"?
一般来说是的。
只要源码没变,后面平时想打开时,直接点击"启动网站.bat"就可以。
只有在你修改了内容、更新了仓库,或者删除了 _site 之后,才需要再点一次"重新生成站点.bat"。
4. 浏览器打不开 4000 端口怎么办?
先检查下面几点:
- Docker Desktop 是否已经启动
- 容器是否正常运行
_site是否已经成功生成- 4000 端口是否被其他程序占用
八、总结
把 GTFOBins 部署到 Windows 上,其实没有想象中那么难。
真正麻烦的地方主要有两个:
- Jekyll 在 Windows 环境下不算特别省心
- 初次看到一大堆报错时,容易误以为彻底失败了
但只要理清思路,其实很好解决