这次安利一个游戏。
游戏呢是给初学者设计的,新手刚好可以一边过关一边学习一些 Linux 的基本操作。
先说说这个游戏怎么玩吧:
我们这个游戏有27关,对应27对账号密码组合。开始的时候送我们一个第一关的账号密码:「bandit0」-「bandit0」。
我们需要使用这个账号登陆服务器并找到「bandit1」的密码,然后使用得到的密码登陆「bandit1」,再找到「bandit2」的密码……
咦,等一下,这游戏怎么有种……「你追我,如果你追到我,我就让你嘿嘿嘿」的感觉呢……
然而通关以后冰冷的现实告诉我:
……
游戏呢,是需要自己动手玩的,这篇文章只是记录了我的通关思路和过程,可以参考,但也别无脑拷。
下面的通关记录是在玩游戏的过程中边玩边记录的,所以比较正经,想上车的同学可以下车了~
前几关写的比较细,也是考虑到新手一上来就看不懂很闹心,然后又要浪费蛋白质,嗯你懂的:)
如果有好的思路,欢迎留言。
Bandit 游戏规则
强盗战争是针对绝对的初学者。它会教授需要能够玩其他战争游戏的基础知识。
……(剩下不翻译了,懒~
Level 0
两种姿势:1.终端直接 ssh 。2.看下面
Chrome 插件 「Secure Shell」

按上图配置好各项后按「Enter」或点击「连接」

输入页面中告诉我们的密码:bandit0
(输入密码时是隐式输入,光标不会动,不要以为卡了,正常输入后按回车等待反馈信息就好)

见到这个东西就证明我们使用 SSH 连接服务器成功了。我们就可以用手中的这台电脑操作这台服务器了。
Level 0 - 1
描述:下一级别的密码存储在位于主目录中的名为readme的文件中。使用此密码 SSH 登录到bandit1。
密码:boJ9jbbUNNfktd78OOpsqOltutMc3MY1
|
|
心路历程:借上图中的红框,「~」表明我们登陆后的当前位置是该用户的主目录,ls 列出当前目录下的文件,发现确实有这个「readme」文件。使用 cat 命令打印出文件的内容。
拿到这个所谓的密码之后,我们要使用 exit 命令退出这次登陆(直接刷新网页更快~)。
|
|
这时我们输入 C,然后配置新的连接,使用新的用户名「bandit1」和密码「boJ9jbbUNNfktd78OOpsqOltutMc3MY1」登陆就ok了。
提示:如果大家不知道去哪里查找命令的话,可以在终端中 man 命令,例如 man ls。天生英文抗性为负的朋友可以来这里查👉Linux 命令大全,但并不能完全取代 man 手册。
Level 1 - 2
描述:下一级别的密码存储在一个名为 - 位于主目录中的文件中。
密码:CV1DtqXWVFXTvM2F0k09SHz0YwRINYA9
|
|
心路历程:文件名是「-」,如果是其他名字直接 cat filename 就好了,然而如果是 cat - 的话,就有一些小问题,因为 bash 中会用「-」来接受命令行参数,未避免冲突,我们使用「./」来表示当前目录,那「-」文件就表示为「./-」。
Level 2 - 3
描述:下一级别的密码存储在位于主目录中的文件名含有「空格」的文件中
密码:UmHadQclWmgdLOKQ3YNgjWxGoRMb5luK
|
|
心路历程:这关使用 ls 后没办法确定文件的数量(1~4个),使用 ll 命令(ls -alF)查看一下发现是一个单独的文件(「.」开头的文件为隐藏文件,故之前没有显示)。这里的空格面临的情况跟之前的「-」差不多,避免混淆,使用「\ 」(斜线后跟空格表示空格)。
提示:ll 并不是 linux 的基本命令,而是「.bashrc」这个文件中的
这句话定义的。相当于对 ls -alF 这个命令起了一个别名。
因为这个别名的定义较为普遍,所以我没看这个文件内容之前就习惯性的试了下。
|
|
心路历程:进入「inhere」目录后使用 ls 命令看不到非隐藏文件,我们使用 ll 就ok了。
Level 4 -5
描述:下一级别的密码存储在inhere目录中唯一的人类可读文件中。提示:如果你的终端搞砸了,试试“重置”命令。
密码:koReBOKuIDDepwhWk7jZC0RTdopnAYKh
|
|
心路历程:因为描述中提到了这个文件是唯一人类可读的文件,大概率会与其他文件不太一样,我们选择使用 file 命令查看文件类型后发现只有一个 「ASCII text」文件,那基本就是它了。
Level 5 - 6
描述:下一级别的密码存储在inhere目录下的某个文件中,并具有以下所有属性: 人类可读,大小为1033字节,不可执行。
密码:DXjZPULLxYr17uwoI01bNLQbtFemEgo7
|
|
心路历程:第二个命令 cd inhere; ll 两个命令通过分号间隔,会分别执行。我们发现 inhere 目录下还有好多目录(文件夹)。这如果一个一个找就累死了。我们使用 find 命令查找一下。-type f指定文件类型为普通文件,-size 1033c 指定文件大小为 1033 bytes。具体可参考我上面给出的 Linux 命令大全
提示:ls -l 后每行开头的字符串中第一个字母是「d」表示为「directory」- 目录。我们使用的 ll 在 .bashrc 文件中被定义为 ls -alF 其中 a 是显示隐藏文件, l 是详细信息, F 是每条后面追加文件类型标识符,我们输出的每行内容尾部都有的「/」就表示这些都是目录。
Level 6 - 7
描述:下一级别的密码存储在服务器的某个位置,具有以下所有属性: 所属用户bandit7,所属用户组bandit6,拥有 33个字节的大小
密码:HKBPTKQnIay4Fw76bEy8PVxKEDQRKTzs
|
|
心路历程:描述中说「存储在服务器的某个位置」,我们使用「/」这个 linux 根目录作为我们搜索的最顶层。其中我们还用到了 Linux 下的「黑洞」,把错误输入全扔了进去。这样就只返回了正确结果。
如果把错误输出重定向到「黑洞」中,就是酱紫滴:
太多干扰信息不好观察。
提示:「2>/dev/null」中「2」表示错误输出,「>」是重定向符号表示把信息送到哪里,「/dev/null」是「Linux黑洞」。这里有篇文章供参考👉shell中>/dev/null 2>&1是什么鬼?
Level 7 - 8
描述:下一级的密码存储文件data.txt中 “millionth” 的下一个单词。
密码: cvX2JJa4CFALtqS87jk27qwqGhBM9plV
|
|
心路历程:我们查看文件详细内容时发现这个文件比较大,光靠肉眼找是没戏了。所以我们借助命令 grep 找到 「milionth」这个单词所在行的内容,后面跟着下一关的密码。(其实最开始我惯性的ls 然后 cat 了一下……发觉不太对赶紧 ctrl+c 终止, ll 看了眼大小……)
Level 8 - 9
描述:下一个级别的密码存储在文件data.txt中,并且是仅出现一次的文本行。
密码:UsvVyFSfZZWbi6wgC7dAFyFuR6jQQUhR
|
|
心路历程:又描述得知这是一个文本文件,里面有很多行字符串,我们需要找到其中仅出现一次的行。使用 sort 命令对文件排序后再对其结果进行 uniq -u 只显示其中的单一行。
提示:uniq -u 是上下相邻两行对比得到是否为单一行:
如例子中的前两行被认定为重复行,第二行与第三行不同,第三行与第四行不同,所以「2」被当作了唯一行。第四行中的「1」同理。
所以我们这里要先对文件排序:
然后再筛选唯一行:
Level 9 - 10
描述:下一个级别的密码存储在文件data.txt中的几个人类可读字符串之一,从几个“=”字符开始。
密码:truKLdjsbJ5g7yyJ2X2R0o3a5HQJFuLk
|
|
心路历程:描述中提到了几个人类可读字符,那我们用 strings 筛选一下(strings是在文件中查找可打印字符串并输出长度为4个或更多的字符串,遇到换行或空字符结束)。其中也提到从几个「=」符号开始,那我们用 grep 命令筛选 含有「==」的字符串看看。
Level 10 - 11
描述:下一级别的密码存储在data.txt文件中,该文件包含base64编码数据
密码:IFukwKGsFW8MOq3IRFqrxE1hxTNEbUPR
|
|
心路历程:题目告诉我们使用 base64 编码了数据,那我们解码就好了。
Level 11 - 12
描述:下一级的密码存储在文件data.txt中,其中所有小写(a-z)和大写(A-Z)字母已经被旋转了13个位置
密码:5Te8Y4drgCRfCx8ugdwuEX8KFC6k2EUu
|
|
心路历程:这里我们用到了 tr 命令,参数为两个字符集,把第一个字符集中的字符替换为第二个字符集中的对应字符。题目中说旋转了13个位置,相当于26个字母前十三个和后十三个换了个位置。按照这样的对应关系,调整给出的字符集。
提示:有人会写程序来做替换,但是对于这道题来讲 tr 会方便很多。虽然这个命令不常用,用起来还是很爽的。
Level 12 - 13
描述:下一级的密码存储在data.txt文件中,该文件是一个已被重复压缩的文件的十六进制转储文件。对于这个级别,可以在 /tmp 下使用 mkdir 创建一个工作的目录。例如:mkdir /tmp/myname123 。然后使用 cp 复制数据文件,并使用 mv 重命名(阅读manpages!)
密码:8ZjyCRiBWFYkneahHwxCv3wb2a1ORpYL
|
|
心路历程:这关比较恶心了……按照对应的加密方式解密就好,用 file 查看文件类型,mv 命令修改名字,还有bzip2 -d、gzip -d、tar -xvf以及xxd -r 这些解密解压方法。
Level 13 - 14
描述:下一级的密码存储在/etc/bandit\_pass/bandit14 中,只能由用户bandit14读取。对于这个级别,你不会得到下一个密码,但你会得到一个私人的SSH密钥,可以用来登录到下一个级别。注意:localhost是指您正在使用的机器的主机名
密码:4wcYUJFw0k0XLShlDzztnTBHiqxU3b3e
|
|
心路历程:告诉我们需要 ssh 登陆进去,自己去找密码,我们就登录一下好了。
Level 14 - 15
描述:通过将当前级别的密码提交到localhost上的端口30000,可以检索到下一级别的密码。
密码:BfMYroe26WYalil77FoDi9qh59eK5xNr
|
|
心路历程:我们使用 nc 命令来发送我们的密码,因为上一关我们已经知道密码在那放着了,刚好可以用到。
提示:什么?你想直接查看其他关的密码?不存在的……(权限啊老铁)
Level 15 -16
描述:可以通过使用SSL加密将当前级别的密码提交到本地主机上的端口30001来检索下一级别的密码。
密码:
|
|
心路历程:我们使用 openssl 的 s\_client SSL/TSL 客户端程序连接服务器,成功后复制粘贴我们本关的密码就能得到下一关的密码了。多看手册哦。
提示:
Level 16 -17
描述:可以通过将当前级别的密码提交到本地主机上31000到32000范围内的端口来检索下一级别的凭证。首先找出哪些端口有服务器正在侦听它们。然后找出哪些人说SSL和哪些不。只有一个服务器会提供下一个凭据,其他的只是发回你发给它的内容。
密码:xLYVMN9WE5zQ5vHacb0sZEVqbrp7nBTn
|
|
心路历程:这关把过程注释在了上面的代码中,帮助大家路顺思路,这里就不赘述了。
Level 17 -18
描述:homedirectory中有两个文件:passwords.old和passwords.new。下一级的密码是passwords.new中跟.old唯一不同的一行
密码:kfBf3eYk5BPBRzwjqutbbfE887SVc5Yd
|
|
心路历程:描述说的很清晰,这里直接 diff 就好了。
Level 18 -19
描述:下一级别的密码存储在家庭目录中的 readme 文件中。不幸的是,当你用SSH登录时,有人修改了.bashrc将你注销。
密码:IueksS7Ubh8G3DCwVzrTd8rAVOwq3M5x
这里就厉害了……
输入密码后,跟我说了句拜拜然后给我一脚……
卧槽忍不了。
常年看 man 手册的老司机表示年轻人要低调,密码我还是能拿到。
先看 man ssh 说了什么:
Secure Shell 中的配置页面也预留了 Command 配置:
配置好之后点连接,输入密码:
心路历程:如果事先不知道,卡住是正常的,但是如果之前用到 ssh 命令的时候仔细看看 man 手册,不知道吗?不存在的……
该反省的反省。
Level 19 - 20
描述:要访问下一个级别,您应该使用homeu目录中的setuid二进制文件。 不带参数的执行它找出如何使用它。 在使用setuid二进制文件后,可以在通常的地方(/etc/bandit_pass)找到这个级别的密码。
密码:GbKksEFF4yrVs6il55v6gwY5aVje5f0j
说实话我没抬读懂这个 setuid binary,不过不影响。大致意思就是告诉你 Home 目录下有个文件,先不带参数执行一下,他会告诉你怎么用。
|
|
心路历程:嗯,有种报复社会的感觉。
Level 20 -21
描述:homedirectory中有一个setuid二进制文件,它执行以下操作:它将连接 localhost:[命令行参数的上的端口]。然后从连接中读取一行文本,并将其与上一级(bandit20)中的密码进行比较。如果密码正确,将传送下一级密码(bandit21)。
注意:基础设施的变化使这一层面更加困难。您将需要找出在同一个Docker实例中启动多个命令的方法。
密码:gE269g2h3mw3pwgrj0Ha9Uoqen1c9DGr
这关的大意呢是告诉你,你的 Home 目录下有一个二进制文件(setuid又出现了……),你执行它,并提供给它端口号,它会请求这个端口并获取这个端口提供给他的数据,如果数据和 bandit20 的密码相同,他就会告诉你下一关的密码。
并且给了注意事项:Changes to the infrastructure。
注意事项中提到了他们的游戏是运行在 Docker 容器上的,默认会给每一次连接分配一个全新的环境,如果当你完成游戏需要开启两个终端 并会产生交互的话,可能需要一些特殊的手段(ssh -L localport:host:port),我们后面再讲这个操作,先分析下他要我们干什么。
他提到:这个程序会访问 localhost 的[你提供的端口号]来获取数据。这里我们需要处理两件事情:1.运行这个程序。2.创建一个监听事件并会回复这个程序当前关的密码。
监听端口与访问端口有可能用到两个终端,而且是存在交互的,这也是他给我们提示的初衷。
我们做这关呢,有两个解法。一个是本着学习的态度,走提示流程,一个是日常野路子解法。我们先说说提示的思路。
思路一:
这个跑在 Docker 容器内的游戏,每一次连接都是全新的环境,那我们一个监听,一个请求,需要保证两个终端能够通信,监听的一段正常监听,请求的一端再去请求。所以我们现在要创建两个能交互的终端。方法是借助 ssl -L 这个命令,先查一下这个命令。然后再看会好很多。
嗯……先给你3分钟查一查,不够的话再来3分钟也行……

拿实际例子来说,当我们这样配置并连接的时候,我们请求连接本地主机的 1234 端口时这个请求会转发到 bandit.labs.overthewire.org,它会来访问 localhost (此时,对于 bandit.labs.overthewire.org 来讲 localhost 是它自身)的 22 端口。
注意事项中告诉我们,这样就可以在提供 -L 参数的这个连接不关闭的情况下,通过本地端口转发,建立另一条连接并能够与前一个连接搞基。
那我们的第二个连接就是这样的:
我们在其中一个终端中创建一个发送本关密码的监听:
此时光标会在第二行等待,监听命令没有执行完毕退出。
我们在第二个终端中,我们来看看他所说的这个程序:
那我们再来看一眼监听的那一边:
思路二:
这个思路其实我之前叙述的时候已经透露出一些味道了,细心的应该已经不用我说了。
关键词「&」。
这道题创建两个终端去连接的根本原因是因为监听和执行会占用两个终端,那我们把监听扔到后台去跑不就解决了吗。
连接姿势为正常姿势不多说……算了还是多说个j8(图)吧:
|
|
心路历程:嗯,先说思路一的理由是我怕我先写思路二,再写的思路一可能没人看了。
Level 21 - 22
描述:一个程序从cron(基于时间的作业调度程序)定期自动运行。查看/etc/cron.d/中的配置并查看正在执行的命令。
密码:Yk7owGAcWjwMVRwrTesJEwB7WVOiILLI
|
|
心路历程:甚至不需要知道他所说的 cron 是干什么的,我们就能找到密码(当然,游戏放水也有很大因素)。不过该知道的还是要知道的,cron 是 Linux 的守护进程。通俗一点就是我们平时接触到的计划任务,按照规定时间安排定期执行动作的。其中的 cronjob_bandit* 就是提供给 cron 执行的文件。「* * * * * bandit22 /usr/bin/cronjob_bandit22.sh &> /dev/null」前面的「*」是每分钟执行一次,「bandit22」是用它的身份执行,「/usr/bin/cronjob_bandit22.sh」是被执行脚本,至于「&> /dev/null」 前面都有分别提到过,不说任性。
Level 22 - 23
描述:一个程序从cron(基于时间的作业调度程序)定期自动运行。查看/etc/cron.d/中的配置并查看正在执行的命令。 注意:查看其他人编写的shell脚本是非常有用的技巧。这个级别的脚本是故意易于阅读。如果您在理解它的功能时遇到问题,请尝试执行它以查看打印的调试信息。
密码:jc1udXuA1tiHqjIsL8yaapX5XIAI6i0n
|
|
心路历程:这里的定位思路与上一关没什么区别,最后会要你分析这个简单的代码。因为 cronjob_bandit23 文件中指定的用户是 bandit23,whoami 的结果也是这个,我们就直接赋值然后走流程就行了。
Level 23 -24
描述:一个程序从cron(基于时间的作业调度程序)定期自动运行。查看/etc/cron.d/中的配置并查看正在执行的命令。
注意:这个级别要求你创建你自己的第一个shell脚本。这是非常大的一步,当你击败这个级别时,你应该为自己感到骄傲!
注意2:请记住,你的shell脚本一旦执行就会被删除,所以你可能想保留一个副本…
密码:UoMYTrfrBFHyQXmg6gzctqAwOmw1IohZ
|
|
心路历程:我们定位脚本的思路不变,看脚本发现:该脚本会执行 /var/spool/bandit24 的脚本,60s 如果还没之行结束会强制kill掉,然后删除。所以我们写了一个把 /etc/bandit\_pass/bandit24/ 输出到 /tmp/bandit24_pass 的脚本到这个目录下,然后付了个权限。
Level 24 - 25
描述:一个守护进程正在监听端口30002,如果给出了bandit24的密码和一个秘密的数字4位pincode,将给你bandit25的密码。没有办法检索pincode,除非枚举10000个组合,称为蛮力。
密码:uNG9O58gUE7snukf3bvZ0rxhtnjzSGzG
|
|
心路历程:这关描述也很清晰(虽然我是机翻)。它开放了一个 30002 端口监听,你给他发 bandit24 的密码 +空格 + 四位数字,如果这个字符串正确它就会返回给你 bandit25 的密码。 Bandit24 的密码我们很容易得到,那问题就是这个4位数了。描述中说我们只能尝试暴力破解,那就从「0001」到「9999」都生成出来,分别与 bandit24的密码+空格连接,把这一万个组合都试一下。于是写了一个 python 脚本生成这个含有 10000 种组合的文件,并提交给 30002 端口,把返回的信息存放在文件中,然后筛选文件内正确信息。
Level 25 - 26
描述:从bandit25登录到bandit26应该相当简单…用户bandit26的shell不是/ bin / bash,而是别的。找出它是什么,它是如何工作的,以及如何摆脱它。
密码:5czgV9L3Xx8JPOyRbXh6lQbmIOWvPT6Z
|
|
我们先连接上去
然后我们使用 bandit25 这个用户带着 bandit26 的 privatekey 去连接 bandit26
more 命令像预期一样输出一屏后等待我们的动作:
我们看看手册,有没有能我们需要的东西:
这个v命令能让我们进入 vi 模式,虽然不常用 vi,但经常 vim 敲代码,经常使用「:sp」「:vsp」这种能打开其他文件的命令。
我们再去看看 vi 的 man 手册:
看起来就是我们需要的命令,那我们去试试。
在 more 的页面按v进入vi
然后使用命令 :ex! /etc/bandit_pass/bandit26 打开我们需要的密码文件:
心路历程:这关很有意思,刚好 more 与 vi 这两个命令我都不常用,查阅文档与测试了一番。诸如登陆时候的字符画与 more 这种小细节,透过终端似乎能在看到设计者的:)
Level 26 - 27
描述:这时候,27级还不存在
[Game Over]
嗯……游戏是结束了,我最后问一句: