1. 先聊聊Wargames和Bandit到底是个啥
如果你在Linux学习和安全入门的圈子里混过一段时间,大概率会听到过OverTheWire这个平台,而Bandit正是它最出名、也最适合新手的一个Wargame系列。所谓Wargames,直译过来是“战争游戏”,说白了就是给你一个故意留了漏洞或谜题的真实环境,让你通过动手操作来一步步攻破关卡。它不是看视频课,也不是读文档,而是真刀真枪地连上一台远程Linux服务器,用命令解决实际问题。
Bandit这个项目做的事情其实非常简单直接:SSH登录到远程服务器,每过一关就能拿到下一关的密码,然后继续登录下一关。每一关都会引入一类Linux操作知识,从最基础的ls、cat,到文件权限、查找过滤、文本处理、编码解码、压缩解压、定时任务、Git版本控制,一路铺到网络服务交互和简单的漏洞利用思维。总共33关,走完一遍,你对Linux命令行的熟悉程度会有一个质的飞跃。
写这篇文章的初衷,是因为我发现很多新手朋友拿到这个题之后,第一反应是去搜通关攻略,照着抄密码。这其实浪费了这个项目最大的价值。我建议你把它当成一本“动手实践的Linux教材”来刷,每一关都自己先试,卡住了再来看思路。这篇文章我会按照我的实际通关经验,把整个项目的机制、关键关卡的解法思路、我踩过的坑和一些排查技巧都整理出来,适合刚接触Linux、想找项目练手,或者在准备CTF入门的读者参考。
2. 环境准备:连接Bandit前你需要搞清楚的几件事
2.1 SSH客户端的选择与基本用法
玩Bandit的核心操作就是SSH远程登录,所以你需要一个能用的SSH客户端。Linux和macOS用户直接在终端里敲ssh命令就行,自带的OpenSSH完全够用。Windows用户的话,我强烈建议装一个Windows Terminal加OpenSSH,或者用WSL,而不是依赖某些图形化工具,理由后面说。
第一次连接的命令长这样:
ssh bandit0@bandit.labs.overthewire.org -p 2220拆开解释一下:bandit0是用户名,bandit.labs.overthewire.org是服务器域名,-p 2220指定端口。Bandit不用默认的22端口,而是用2220,这个细节很多人第一次就栽了——不写端口直接连,直接超时。
输入这条命令后,系统会提示你确认服务器指纹,输入yes回车即可。然后会让你输密码,第一关的密码就是用户名本身:bandit0。输密码的时候终端不会显示任何字符,这是正常的,不是键盘坏了,我见过好几个朋友在这卡住以为输入没生效。
2.2 为什么必须自己动手,而不是直接看密码表
Bandit整个项目的密码是半公开的,网上随便一搜就能找到全部密码。但你要是直接抄,那就真的白玩了。这个项目的核心价值在于让你在真实环境里反复练习Linux命令的操作手感。就像学游泳,你看再多教程,不下水永远学不会。
每一关的难度递增设计得相当合理:最开始只是让你找一个readme文件,后面会让你处理带空格甚至以短线开头的文件名,再后来要你用find在几万个文件里定位目标,最后甚至涉及Git仓库历史里的敏感信息泄露。这些问题在真实的工作场景中都会遇到,尤其是文件名处理、权限排查、日志分析这些,练熟了直接用在工作里。
我的建议是:每题至少独立思考15分钟,实在没思路再看提示,不要直接拉到底部看密码。你自己推出来的那个密码,比看十遍攻略都值钱。
2.3 一个小技巧:把密码存在本地文件里
通关过程中你会拿到一大堆密码,每关的密码都是一串随机字符串,记在脑子里不现实。我习惯的做法是:本地建一个文本文件,比如pass.txt,每拿一个新密码就追加进去。这样后面关卡需要回头用旧密码的时候,直接查文件就行。
但这里有个坑:很多关卡需要你把密码作为输入传给某个程序,这时候你可能会想要复制粘贴。在终端里复制粘贴的操作方式和图形界面不太一样,Windows下一般是右键粘贴,Linux下是Ctrl+Shift+V,macOS是Cmd+V。如果不生效,看看你的终端软件设置里是否开启了剪贴板集成。另外有些关卡需要用ssh带命令直接连接,密码没法交互式输入,那时候就需要配合sshpass之类的工具,后面具体关卡部分我会详细说。
3. 核心玩法拆解:Bandit在考你什么
3.1 找密码-登录-过关的循环机制
Bandit的基本循环是:当前关卡的环境里藏着一个文件或服务,里面存着下一关的SSH密码。你登录到当前关卡后,用各种命令找到这个密码,然后退出SSH会话,用新密码登录下一关。整个项目就是这样一个接一个的递进链条。
这个设计有个很妙的地方:它强迫你在每一关都切换到“探索者”的心态。你不能只靠记忆,因为每关的环境都不一样,你必须学会先观察环境,再决定用什么工具。我通关到后面回头复盘,发现这个观察-假设-验证的过程,其实就是渗透测试和故障排查的通用方法论。
每一关开始前,我推荐先跑三个命令:
ls -la pwd whoamils -la看当前目录有什么文件和隐藏文件,pwd确认你在哪个路径,whoami确认当前用户身份。虽然Bandit的用户名就是关卡编号,但养成这三个命令的习惯,对后面处理复杂场景非常有帮助。
3.2 文件操作类关卡的常见套路
Bandit前10关绝大部分考的是文件操作,而且每一关都在针对一个“反直觉”的边界情况。比如文件名是一个短横线-、文件名里带空格、文件是隐藏文件(以点开头)、文件不是普通文本而是二进制、文件散落在几百个子目录里。这些情况在真实Linux使用中不常见,但一旦遇到就会让你抓狂。
我挑几个典型的说一下解法思路,你通关的时候心里就有底了:
- 文件名是
-:直接cat -会被解释成读取标准输入,你需要用cat ./-或者cat -- -来强制把它当文件名处理。 - 文件名带空格:用引号包起来,或者用反斜杠转义空格,比如
cat "file name"或cat file\ name。Tab键自动补全这时候特别好用。 - 隐藏文件:普通
ls看不到,必须ls -la才能看到以点开头的文件。 - 海量文件中找指定文件:先用
file命令批量识别文件类型,再用find按大小、权限、所有者过滤。
这些操作看起来琐碎,但都是实打实的工程经验。我之前在一台真实的生产服务器上排查问题,就遇到过日志文件名以-开头导致脚本报错的场景,当时立刻想起Bandit里的这一关,用同样的方法解决了。
3.3 文本处理、编码和加密的基础认知
Batch中段开始引入文本处理和编码解码,这是很多人觉得“一下子变难”的转折点。其实核心就是在考几个Linux文本处理命令的组合使用:grep过滤、sort排序、uniq去重、strings提取字符串、base64解码、tr字符替换。
举个例子,其中一关的data.txt文件内容是一堆无序文本,其中只有一行是唯一的,其他行都重复出现。解法就是用管道把命令串起来:
sort data.txt | uniq -u这行命令的意思是:先按字典序排序,然后把重复的行合并,-u参数只输出那些没有重复的行。思路清楚后就是一秒钟的事,但如果你不熟悉管道和这两个命令,就会觉得无从下手。
另一个让我印象深刻的关卡是把一段文本做过ROT13加密(凯撒密码的一个变种,字母位移13位)。解法是用tr命令做字符映射:
tr 'A-Za-z' 'N-ZA-Mn-za-m' < data.txt第一次看到这个命令的人都会觉得像魔法,其实原理很简单:A-Z映射到N-Z再回到A-M,大写和小写分别映射,正好完成13位循环位移。
到了中后段,有一关会给你一个数据文件,里面是十六进制转储,你需要先反过来恢复成原始二进制文件,然后连续多次解压(gzip、bzip2、tar),每次文件类型都不一样。这关非常考验耐心和脚本思维,也是我第一次意识到“可以用循环自动解压”的地方。
3.4 网络交互与系统机制类关卡
从Level 14开始,题目从纯本地文件操作扩展到了网络服务交互。你需要用nc(netcat)连接本机的某个端口,把密码发送过去换取下一关的密码;后面还有一关要求你用openssl s_client建立SSL加密连接,这就涉及加密通信的基础概念。
再往后还有定时任务(cron)相关的关卡:系统里有一个定时脚本每隔一段时间运行一次,你需要搞清楚它在干什么、运行身份是什么、读什么文件,然后顺着这条链路找到可利用的点。这类题目已经非常贴近真实的系统维护和权限提升场景了,逻辑就是:定时任务以更高权限运行,如果你能控制它读取的文件,就能借它的手做事情。
还有一关利用了setuid机制——某个二进制文件在执行时会以文件所有者的身份运行,而不是执行者的身份。这在Linux上是很经典的一种权限提升手段。你不需要理解内核细节,但至少要知道ls -l输出中那个s标志位意味着什么,以及find -perm怎么去找这些特殊权限的文件。
到最后的几关,你会遇到Git仓库相关的题目:通过git log查看提交历史、用git branch -a查看分支、用git tag查看标签、甚至要往远程仓库推送一个指定内容的文件。这些是对版本控制系统基础操作的实际检验,做一遍比看十篇Git教程都记得牢。
4. 实战拆解:从Level 0到Level 5的手把手过程
4.1 Level 0:建立你的第一个SSH连接
Level 0的任务描述只有一句话:用SSH连接到服务器,用户名是bandit0,密码是bandit0。你连接成功之后,就算完成了第一关。实战命令:
ssh bandit0@bandit.labs.overthewire.org -p 2220输入密码bandit0,成功登录后你会看到类似下面这样的欢迎界面:
Welcome to OverTheWire! ... bandit0@bandit:~$看到这个提示符,说明你已经进了游戏。此时敲ls -la看看目录里有什么,你会看到一个readme文件,里面存着下一关的密码。用cat readme读出来,记下来,然后exit退出登录。接着用新密码登录bandit1,第二关就开始了。
这关虽然简单,但它把整个项目的操作范式教给你了:观察环境(ls)、读取文件(cat)、提取关键信息(密码)、切换目标(SSH登录下一关)。四步循环,贯穿全程。
4.2 Level 0到Level 1:第一个“陷阱”文件
Level 1的密码藏在主目录下一个名叫-的文件里。很多新手直接敲cat -,然后发现光标停在那里,好像卡死了——其实是因为-被当成了标准输入的特殊标记,cat在等你从键盘输入东西。按Ctrl+C或者Ctrl+D退出,然后像我前面说的,用cat ./-读取。
这关让我印象特别深,因为我第一次玩的时候也卡了一会儿,当时的反应是先怀疑是不是环境坏了,后来才意识到是文件名的问题。从此之后我养成了一个习惯:凡是操作看上去不符合预期,先怀疑文件名和路径,而不是怀疑题目出错。
4.3 Level 2:处理带空格的文件名
这一关的文件名里有空格,比如叫spaces in this filename。如果你直接cat spaces in this filename,系统会把它拆成四个参数,然后报错说找不到spaces这个文件。解决办法是用引号包住完整文件名:
cat "spaces in this filename"或者用反斜杠转义每个空格:
cat spaces\ in\ this\ filename我个人推荐引号方式,尤其在文件名很长的时候。另一个偷懒的办法是敲几个开头字符后按Tab键自动补全,终端会帮你处理好转义。这关给你的启发是:在命令行中,空格是参数分隔符,文件名里的空格必须显式处理,这个坑在写Shell脚本时尤其常见。
4.4 Level 3:找隐藏文件
第三关的密码藏在一个叫inhere的目录里。进去看一眼:
cd inhere ls你会发现目录是空的。原因很简单,文件是以点开头的隐藏文件。用ls -la就能看到全部内容,然后cat读取即可。这里我想多提一句:ls -la的a参数就是all的意思,显示所有文件包括隐藏文件;l参数是long format,显示详细属性。这两个参数合在一起是你日常排查环境信息的高频用法。
4.5 Level 4:用file识别文件类型
到了Level 4,inhere目录下有一堆文件名以-开头(-file00到-file09)的文件,密码藏在其中唯一一个人类可读的文本文件里。这一关的关键是不要一个个打开试,而是用file命令批量识别类型:
cd inhere file ./*输出里大部分是data类型,只有一个是ASCII text,那里面就是密码。读取时记得文件名用./前缀,比如:
cat ./-file07这关教会你的核心技巧是:遇到大量需要分类的文件,学会用工具批量判断,而不是肉眼逐个排查。真实工作中,分析日志目录、识别上传文件的安全类型,用的都是同一个思路。
4.6 Level 5:用find按属性精确定位
这一关的inhere目录下有几十个子目录,每个子目录里又有各种大小和权限的文件。密码藏在一个“1033字节大小、不可执行”的文件里。手动翻目录翻到你怀疑人生,正确做法是直接find:
find ./ -type f -size 1033c ! -executable解释一下:./表示当前目录递归查找,-type f只找普通文件,-size 1033c表示大小是1033字节(c表示字节),! -executable表示不可执行。执行之后会输出那个文件的路径,然后去读取就好。
如果你注意到,find在这一关发挥的作用是“按属性筛选”,这比ls和file都更精确。之后的Level 6更是把范围扩大到整个文件系统,你需要在/下找“所有者是bandit7、所属组是bandit6、大小33字节”的文件:
find / -user bandit7 -group bandit6 -size 33c 2>/dev/null这里我特别加了一句2>/dev/null,把大量“权限拒绝”的错误信息屏蔽掉,只保留正常输出。不加的话,刷屏的Permission denied会把真正的结果淹没。这也是一个非常实用的经验:在系统级查找时,学会过滤噪声。
5. 中段关卡的思维升级:文本处理、编码和网络交互
5.1 文本筛选:grep、sort、uniq与strings的组合拳
从Level 7开始,题目不再藏在一个路径明确的文件里了,而是躲在某个大文件的内容中。Level 7的文件data.txt里有一大堆键值对,密码紧跟在millionth这个单词后面。解法就是grep:
grep millionth data.txt小知识:grep默认是输出包含关键词的整行。输出结果一般长这样:millionth <密码>,两个字段之间用Tab分隔。
接踵而至的Level 8就是前面提到的sort | uniq -u,它考的是你对管道和文本流处理的直觉。这里我多说一句:sort本身不会修改原文件,它只是把内容排序后输出到标准输出;uniq默认只会合并相邻的重复行,所以必须先排序再去重,这个顺序不能反。如果你先uniq再sort,重复行不相邻,去重就不生效。
Level 9的data.txt文件里有大量不可读的二进制内容,密码夹杂在一些可打印字符串里,而且前面跟着几个=号。解法是把可打印的字符串提取出来再过滤:
strings data.txt | grep "="strings命令的作用就是从二进制文件里抽取连续的、看起来像文本内容的片段。这个命令在处理未知文件、分析恶意样本时也非常有用,值得好好掌握。
5.2 编码解码:base64和ROT13不再神秘
Level 10的密码藏在data.txt里,但文件内容被base64编码过。你不需要去理解base64的编码算法细节,只要知道它是一套用64个字符表示二进制数据的编码方案,并且Linux自带了编解码工具:
base64 -d data.txt-d就是decode的意思。编码方向则用base64不带参数,效果是把文件内容编码后打印出来。
Level 11则用了ROT13,解法是tr字符映射,把字母循环位移13位:
tr 'A-Za-z' 'N-ZA-Mn-za-m' < data.txt这里分享一个思考技巧:遇到看不懂的文本,先判断“它是加密还是编码”。如果输出里只有字母和数字,看起来乱但有一定规律,通常是编码;如果是完全无规则的乱码,可能是加密。就Bandit这个项目而言,它只考编码和弱加密(如ROT13),不涉及真正的加密算法破解,所以可以用暴力尝试的心态去套常见的编码方式。
5.3 压缩包连环:xxd、gzip、bzip2和tar的配合
Level 12是很多人觉得最难的一关,我在这关来回折腾了半个多小时。流程是这样的:
首先,data.txt是一个十六进制转储(hex dump)文件,你需要先把它逆转换回二进制文件:
xxd -r data.txt > dataxxd默认把文件以十六进制形式显示,-r参数是反向操作,把十六进制文本恢复成原始二进制。
接下来用file命令看看这个data是什么类型,你会发现它是gzip压缩包。改成对应的正确扩展名,然后解压:
mv data data.gz gzip -d data.gz解压之后又是一个新文件,再用file确认类型,发现又变成bzip2压缩包,继续解压……这样反复好几次,中间还穿插着tar归档格式。由于可能来回多次,手动敲命令非常累,我写了一个简单的循环脚本,用file的输出动态判断该用哪个解包工具。
具体的脚本不贴了,因为每个人环境不同,我当时的做法很笨拙——就是反复执行三件套:file看类型、mv改扩展名、调用对应工具解压。重要的是思维:面对层层嵌套的压缩格式,不要慌,每次都重建“识别类型-选择工具-解压”的循环,最多七八次就能拿到密码。
5.4 网络端口交互:nc与openssl的初体验
从Level 14开始,你会发现眼前的文件不再直接包含密码,而是一个“服务”在等你去交互。
Level 14的任务:把当前密码发送到本地服务器的30000端口。工具是nc(netcat):
nc localhost 30000连接成功后,粘入当前密码,回车,服务端会返回下一关的密码。注意:连接对话后,对方的回复不会自动加换行,看起来可能有些挤在一起,属正常现象。
Level 15更进一步,要求你建立SSL/TLS加密连接(服务端口30001),普通nc不行了,必须用:
openssl s_client -connect localhost:30001同样,连接后输入当前密码,回车,拿到下一关密码。这两关的本质是让你理解“网络服务是有入口的”,端口号就是服务的门牌号,而nc和openssl s_client就是你敲门的手。之后Level 16甚至让你在31000到32000这100个端口里自己扫描哪个端口开着SSL服务——我教大家一个最简单的办法,写个循环依次用openssl s_client去连,判断哪个端口返回了非常规内容:
for port in {31000..32000}; do timeout 1 bash -c "echo | openssl s_client -connect localhost:$port 2>/dev/null" | grep -q "BEGIN RSA" && echo "found: $port" done这个扫描思路就是后来学习端口扫描工具前的“手工原版”。这里我提醒一句:测试自己本机的合法教学环境没问题,但不要拿这套手法去扫描不属于你的机器,那是违法行为,学技术的同时也要懂得边界。
6. 高频问题与排查技巧实录
6.1 SSH连接失败怎么办
连不上服务器是新手最常遇到的第一个障碍。按照我的经验,按以下顺序排查:
- 确认端口写没写:
-p 2220必须带上,漏了就是连接超时。 - 确认密码对没对:注意区分大小写,Bandit密码都是手工输入的,最容易出问题的是把
1和l、0和O看混。 - 确认网络通不通:先
ping bandit.labs.overthewire.org看域名能不能解析。有些网络环境下SSH的2220端口会被防火墙拦,换个网络环境试试是最后的办法。 - 留意“Too many authentication failures”报错:如果你本机SSH配置里挂了太多密钥,服务端可能会拒绝。加
-o IdentitiesOnly=yes或者用-o PubkeyAuthentication=no强制走密码认证。
6.2 提示Permission denied是怎么回事
在Bandit后续关卡中,经常会在find全盘搜索时看到一堆Permission denied。这通常是当前用户对其他目录没有读权限,属正常现象,不是环境坏了。用2>/dev/null把这个错误流丢弃就行了。
但有一种情况需要警惕:当你明明知道某个文件存在却cat不出来的“Permission denied”,那可能是这个文件对当前用户不可读,题目很可能要求你换一种方式(比如利用setuid程序、通过定时任务间接读取),这是后面关卡的核心考点。
6.3 文件找到了但内容没有密码
有几次我find出来的文件用cat打开,看到的是乱码,当时以为找错了,反复确认路径。直到学会先file看类型,才意识到有些文件是二进制,需要strings提取可读字符串,或者直接按某种编码解码。所以我的经验是:拿到任何文件,第一件事永远是file,而不是cat。这个习惯在Bandit里能帮你省下大量试错时间。
6.4 复制粘贴的坑:多出来的换行符
最后一个高频问题:你在终端里复制密码的时候,经常会把结尾的换行符一起带进去。有些关卡的程序会因此判断密码错误。解决办法是粘完后手动把末尾多余的换行删掉,或者用命令行的方式精确读取:如果你把密码存在了本地文件里,可以用类似cat pass.txt | nc localhost 30000的方式,避免手动复制粘贴带来的误差。
这里我也顺便提一下,在Bandit的后段关卡中,有一关会给你一个SSH私钥文件让你直接登录。这时候你用ssh -i 私钥文件 bandit14@localhost来连接,注意私钥文件权限必须足够严格(比如600),否则SSH会拒绝使用它。我当时卡在“Permission denied”上,查了才发现是chmod 600没做,这是个非常经典的小坑。
7. 关于Bandit这趟旅程的个人体验
刷完Bandit全部33关,我最大的感受是:它教会我的不是某个具体的漏洞利用技巧,而是一整套“在陌生环境里高效探索”的方法论。每进入一个新关卡,先看当前目录、看用户身份、看可访问的文件;遇到看不懂的内容,用file判断类型;定位不到目标,用find按属性搜;处理超大文本,用管道组合grep、sort、uniq、strings。这套流程在之后处理任何一台陌生服务器时都在发挥作用。
如果你刷到某一关彻底卡住、想放弃的时候,我建议你回头看一下这一关到底在考哪个命令的哪个特性,然后针对性地去查手册(man命令是你的好朋友)。Bandit的每一关其实都只围绕一个或两个核心命令展开,戳破那层窗户纸之后,后面就是一马平川。我个人卡得最久的一关反而是Level 12的连环解压,不是因为难,而是因为我太想一次性把命令敲对,结果越急越乱。后来静下心,把“解压循环”拆成一步一步,最终也就十几分钟的事。
走完整个项目之后,你可以继续挑战OverTheWire平台上的其他Wargame(比如Leviathan、Narnia),它们会更偏向二进制漏洞利用和系统机制。但如果你只是想打好Linux命令基础,Bandit这一个项目就足够你练上两周了。把这篇文章里的方法吃透,剩下的就是你自己坐到终端前面,一关一关地敲命令、试错、顿悟。这个过程,才是这个游戏真正值钱的地方。