完结篇:OverTheWire Bandit Writeup (20-33)

本文为原创文章,转载请注明出处!

OverTheWire 是一个 wargame 网站。其中 **Bandit** 是一个适合学习Linux指令的游戏,主要是考察一些基本的 Linux 命令行操作 。规则是每一关利用提供的主机加端口和上一关得到的密码通过ssh进入指定的环境,按照要求拿到指定的key,而得到的key又作为下一关的密码。 网站: http://overthewire.org/wargames/bandit/

前面我们分享了[OverTheWire Bandit Writeup (1-10)](https://www.jianshu.com/p/6ddc7c077cbc)

[OverTheWire Bandit Writeup (11-20)](https://www.jianshu.com/p/bbf5e70bb22a)

上回我们已经到了Level 20,得到的密码是 `GbKksEFF4yrVs6il55v6gwY5aVje5f0j`让我们继续,这部分的难度是中等偏困难。

Level 20 → Level 21

描述:用户家目录下有一个具有SUID的程序,用它执行如下操作:用它连接到本机 `localhost`的任意端口,然后它从连接的端口读取一行文本,并将其与 `bandit20`的密码进行比较,如果比对结果一致,它将传输下一级别的密码(bandit21)。可能用到的命令: `ssh,nc,cat,bash,screen,tmux,Unix‘job control’(bg,fg,jobs,&,CTRL-Z,…)`我们来试试吧,先看看怎么使用这个程序

 `bandit20@bandit:~$ ls -l`2.  `total 8`3.  `-rwsr-x---  1 bandit21 bandit20 8044  Dec  28 2017 suconnect`4.  `bandit20@bandit:~$ ./suconnect 1222`5.  `ERROR:  Can't connect`6.  `bandit20@bandit:~

直接加端口好像不行,为什么?因为本机没有开启这个端口啊,那怎么办?监听一个呗,我们使用 `nc`命令监听一个端口,新开一个终端。

`bandit20@bandit:~$ nc -l 1222`

然后再试试

 `bandit20@bandit:~$ ./suconnect 1222`

好像不对劲啊!!啥也没有啊~~有点懵,当我把端口停掉后,发现返回这么一串提示:

`bandit20@bandit:~$ ./suconnect 1222`

`Read:`

  `ERROR:  This doesn't match the current password!`

再看看题目描述,发现我们在监听端口的时候,没有把当前的密码加入进去。再试试,这次我们把当前密码加进去

`bandit20@bandit:~$ echo "GbKksEFF4yrVs6il55v6gwY5aVje5f0j"  | nc -l 1222`

然后在另一个终端连接

 `bandit20@bandit:~$ ./suconnect 1222`

 `Read:  GbKksEFF4yrVs6il55v6gwY5aVje5f0j`

 `Password matches, sending next password`

再看 `nc`监听这边,秒返回密码。

  `bandit20@bandit:~$ echo "GbKksEFF4yrVs6il55v6gwY5aVje5f0j"  | nc -l 1222`

 `gE269g2h3mw3pwgrj0Ha9Uoqen1c9DGr`

Level 21 → Level 22

描述:有一个程序被加入到了任务计划( `cron`)并定期执行,从 `/etc/cron.d/`中找到这个程序,就能找到进入下一关的密码。可能会用到的命令: `cron,crontab,crontab(5)(use“man5crontab”to accessthis)`。这里考察的是 `linux`的任务计划先看看 `/etc/cron.d`下有哪些任务计划

 `bandit21@bandit:~$ ls /etc/cron.d`

`cronjob_bandit22  cronjob_bandit23  `

emm~~这个 `cronjob_bandit22`很可疑啊。看看它配置了什么任务计划?

 `bandit21@bandit:~$ cat /etc/cron.d/cronjob_bandit22`

  `@reboot bandit22 /usr/bin/cronjob_bandit22.sh &>  /dev/null`

 `*  *  *  *  * bandit22 /usr/bin/cronjob_bandit22.sh &>  /dev/null`

可以看出,这条任务计划是,以 `bandit22`这个用户的身份一致在执行 `/usr/bin/cronjob_bandit22.sh`这脚本。让我们看看这个脚本的内容

  `bandit21@bandit:~$ cat /usr/bin/cronjob_bandit22.sh`

  `#!/bin/bash`

  `chmod 644  /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv`

`cat /etc/bandit_pass/bandit22 >  /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv`

看起来这个脚本是把 `bandit22`的密码读取出来,然后存到 `/tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv`文件中。那我们查看这个文件,就能看到密码了

`bandit21@bandit:~$ cat /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv`

  `Yk7owGAcWjwMVRwrTesJEwB7WVOiILLI`

Level 22 → Level 23

描述:有一个程序被加入到了任务计划( `cron`)并定期执行,从 `/etc/cron.d/`中找到这个程序,就能找到进入下一关的密码。提示:你需要阅读 `shell`脚本,然后根据里面给出的信息,以正确的姿势运行脚本才行。这一关考察的是基本的 `shell`编写能力。先和前一关一样找到这个程序吧

 `bandit22@bandit:~$ ls -l /etc/cron.d`

`total 16`

 `-rw-r--r--  1 root root 120  Dec  28 2017 cronjob_bandit22`

`-rw-r--r--  1 root root 122  Dec  28 2017 cronjob_bandit23`

  `-rw-r--r--  1 root root 120  Dec  28 2017 cronjob_bandit24`

`-rw-r--r--  1 root root 190  Oct  31 2017 popularity-contest`

`bandit22@bandit:~$ cat /etc/cron.d/cronjob_bandit23`

`@reboot bandit23 /usr/bin/cronjob_bandit23.sh  &>  /dev/null`

  `*  *  *  *  * bandit23 /usr/bin/cronjob_bandit23.sh  &>  /dev/null`

看看这个脚本的内容:

  `bandit22@bandit:~$ cat /usr/bin/cronjob_bandit23.sh`

 `#!/bin/bash`

  `myname=$(whoami)`

 `mytarget=$(echo I am user $myname | md5sum | cut -d ' '  -f 1)`

 `echo "Copying passwordfile /etc/bandit_pass/$myname to /tmp/$mytarget"`

 `cat /etc/bandit_pass/$myname >  /tmp/$mytarget`

很简单的代码了,读取 `whoami`返回的值,计算其 `md5`值,然后读取用户的密码存到 `/tmp/用户名的md5值`这个文件中。`whoami`是干嘛的?是返回当前登录用户的用户名。

 `bandit22@bandit:~$ whoami`

`bandit22`

再看这个任务计划,是由 `bandit23`执行的。所以我们只需要计算出 `bandit23`的md5值,是不是就能得到 `bandit23`的密码呢?

`bandit22@bandit:~$ echo I am user bandit23 | md5sum | cut -d ' '  -f 1`

 `8ca319486bfbbc3663ea0fbe81326349`

查看文件:

 `bandit22@bandit:~$ cat /tmp/8ca319486bfbbc3663ea0fbe81326349`

`jc1udXuA1tiHqjIsL8yaapX5XIAI6i0n`

Level 23 → Level 24

描述:同样的描述,找到任务计划。不过给了两个提示:1、要自己写一个 `shell`脚本读取密码,2、你写的脚本运行后会被删除,所以你最好做一个备份。同样的先找到执行的任务计划

`bandit23@bandit:~$ ls -l /etc/cron.d/`

`total 16`

  `-rw-r--r--  1 root root 120  Dec  28 2017 cronjob_bandit22`

  `-rw-r--r--  1 root root 122  Dec  28 2017 cronjob_bandit23`

 `-rw-r--r--  1 root root 120  Dec  28 2017 cronjob_bandit24`

 `-rw-r--r--  1 root root 190  Oct  31 2017 popularity-contest`

`bandit23@bandit:~$ cat /etc/cron.d/cronjob_bandit24`

  `@reboot bandit24 /usr/bin/cronjob_bandit24.sh &>  /dev/null`

  `*  *  *  *  * bandit24 /usr/bin/cronjob_bandit24.sh &>  /dev/null`

  `bandit23@bandit:~$ cat /usr/bin/cronjob_bandit24.sh` 

 `#!/bin/bash`

 `myname=$(whoami)`

  `cd /var/spool/$myname`

  `echo "Executing and deleting all scripts in /var/spool/$myname:"`

 `for i in  *  .*;`

 `do`

  `if  [  "$i"  !=  "."  -a "$i"  !=  ".."  ];`

 `then`

  `echo "Handling $i"`

 `timeout -s 9  60  ./$i`

  `rm -f ./$i`

  `fi`

  `done`

 `bandit23@bandit:~

我们可以看到任务计划是以 `bandit24`用户执行的。这个脚本的作用每隔一分钟删除 `/var/spool/bandit24/`目录下所有的脚本。所以结合这一关的提示来看,我们需要把获取脚本放在 `/var/spool/bandit24/`目录中,但是不能直接在这个目录中编辑,不然会被很快删除,比如下面这样是不行的。

 `bandit23@bandit:~$ vim /var/spool/bandit24/getpass.sh`

 `bandit23@bandit:~$ chmod 777  /var/spool/bandit24/getpass.sh`

我们可以在 `/tmp`目录中编辑好,然后复制过去

`bandit23@bandit:~$ mkdir /tmp/getpass/`

`bandit23@bandit:~$ cd /tmp/getpass/`

 `bandit23@bandit:/tmp/getpass$ vim getpass.sh`

`bandit23@bandit:/tmp/getpass$ chmod 777 getpass.sh`

`bandit23@bandit:/tmp/getpass$ cat getpass.sh`

`#!/bin/bash`

`cat /etc/bandit_pass/bandit24 >>  /tmp/getpass/pass`

 `bandit23@bandit:/tmp/getpass$ cp getpass.sh /var/spool/bandit24/`

  `bandit23@bandit:/tmp/getpass$ ls /var/spool/bandit24/getpass.sh`

`/var/spool/bandit24/getpass.sh`

等一会儿,等到这个脚本被删除,然后查看是否获取到密码:

 `bandit23@bandit:/tmp/getpass$ ls /var/spool/bandit24/getpass.sh`

 `ls: cannot access '/var/spool/bandit24/getpass.sh':  No such file or directory`

  `bandit23@bandit:/tmp/getpass$ ls -l`

  `total 4`

  `-rwxrwxrwx 1 bandit23 bandit23 84  Aug 9  16:33 getpass.sh`

  `bandit23@bandit:/tmp/getpass

好像没有,突然想到我刚刚创建目录的是 `bandit23`用户的权限,我们试试把目录全改成 `777`,然后再试试`bandit23@bandit:/tmp/getpass$ chmod 777  .`

`bandit23@bandit:/tmp/getpass$ cp getpass.sh /var/spool/bandit24/`

 `bandit23@bandit:/tmp/getpass$ ls /var/spool/bandit24/getpass.sh`

 `ls: cannot access '/var/spool/bandit24/getpass.sh':  No such file or directory`

但是等了许久并没有看到返回密码。我又试试了用 `nc`命令发送密码

`#!/bin/sh`

  `cat /etc/bandit_pass/bandit24 | nc localhost 1222`

但是依然没有得到密码!!!这是为什么呢?难道复制过去后,文件权限不对了?我们复制过去后,看看权限

`bandit23@bandit:/tmp/getpass$ cp getpass.sh /var/spool/bandit24/`

`bandit23@bandit:/tmp/getpass$ ls -l /var/spool/bandit24/getpass.sh`

`-rwxrwx---+  1 bandit23 bandit23 63  Aug 9  17:26  /var/spool/bandit24/getpass.sh`

果然,权限被改了,这样的权限对于 `bandit24`来说是没权限的。怎么办,复制过去后,再改一次权限试试吧

 `bandit23@bandit:/tmp/getpass$ cp getpass.sh /var/spool/bandit24/`

 `bandit23@bandit:/tmp/getpass$ chmod 777  /var/spool/bandit24/getpass.sh`

 `bandit23@bandit:/tmp/getpass$ ls -l /var/spool/bandit24/getpass.sh`

 `-rwxrwxrwx+  1 bandit23 bandit23 63  Aug 9  17:28  /var/spool/bandit24/getpass.sh`

再看看,密码获取到了没

  `bandit23@bandit:/tmp/getpass$ cat pass`

 `UoMYTrfrBFHyQXmg6gzctqAwOmw1IohZ`

终于获取到密码了。这里最大的坑就是权限这里,如果不注意这里的话,就掉坑里了。

Level 24 → Level 25

描述:有一个程序监听了 `30002`端口,向这个端口发送当前密码和一个秘密的4位数字密码,程序比对后,如果相同,就把进入下一关的密码返回。但是这个秘密的4位数是一个0000到9999之间的某个值,所以有10000种可能。我们来分析一下,我们首先要做的是,把这10000个数都列出来,然后依次把当前的密码和一个4位数字一同发送给 `30002`端口,直到符合要求,就会得到密码。这肯定得编程实现了。其实也很简单,一个小小的 `shell`脚本就能搞定了

 `bandit24@bandit:~$ cd `mktemp -d`  //建立一个临时目录`

`bandit24@bandit:/tmp/tmp.CLTfF8xHy5$ vim getlevel25pass.sh`

  `bandit24@bandit:/tmp/tmp.CLTfF8xHy5$ chmod +x getlevel25pass.sh`

 `bandit24@bandit:/tmp/tmp.CLTfF8xHy5$ cat getlevel25pass.sh`

 `#!/bin/bash`

 `level24pass="UoMYTrfrBFHyQXmg6gzctqAwOmw1IohZ"`

 `for i in  {0..9}{0..9}{0..9}{0..9}`

`do`

 `echo $level24pass' '$i >> output.txt`

 `done`

  `cat ./output.txt | nc localhost 30002  >>  ./level25pass.txt`

`tail -n 5  ./level25pass.txt`

 `bandit24@bandit:/tmp/tmp.CLTfF8xHy5$  ./getlevel25pass.sh`

 `Wrong!  Please enter the correct pincode.  Try again.`

`Correct!`

  `The password of user bandit25 is uNG9O58gUE7snukf3bvZ0rxhtnjzSGzG`

`Exiting.`

OK,很快就得到密码了!

Level 25 → Level 26

描述:从 `bandit25`登录到 `bandit26`应该很容易,但是 `bandit26`的 `shell`不是 `/bin/bash`,你要找出它是什么,并搞清楚它怎么工作的,然后绕过它。既然它说很容易,应该是存在密钥之类的东西,先看看

`bandit25@bandit:~$ ls`2.  `bandit26.sshkey`3.  `bandit25@bandit:~

果然有,我们来登录试试,如果能登录,管它bash是啥呢

 `bandit25@bandit:~$ ssh -i bandit26.sshkey bandit26@localhost`

 `Could  not create directory '/home/bandit25/.ssh'.`

 `The authenticity of host 'localhost (127.0.0.1)' can't be established.`

  `ECDSA key fingerprint is SHA256:98UL0ZWr85496EtCRkKlo20X3OPnyPSB5tB5RPbhczc.`

  `Are you sure you want to continue connecting (yes/no)? yes`

 `Failed to add the host to the list of known hosts (/home/bandit25/.ssh/known_hosts).`

 `....`

  `Connection to localhost closed.`

 `bandit25@bandit:~

提示链接被关闭。我们想起之前我们也碰到过这种情况,要不我们试试 `-T`参数,无需分配伪终端默认。这种方式看似链接上了,但是输入任何命令都没反应。还是老实去找找 `bandit26`用的什么 `shell`吧。要想知道一个用户的 `shell`可以查看用户数据文件 `/etc/passwd`。

 `bandit25@bandit:~$ cat /etc/passwd | grep "bandit26"`

 `bandit26:x:11026:11026:bandit level 26:/home/bandit26:/usr/bin/showtext`

我们看到 `bandit26`的 `shell`是 `/usr/bin/showtext`,看看这个是什么东西

 `bandit25@bandit:~$ cat /usr/bin/showtext`

 `#!/bin/sh`

 `export TERM=linux`

`more ~/text.txt`

`exit  0`

难怪我们连接上去会被关闭,因为这个脚本,使用 `more`查看一个文本文件,当执行完,就执行了 `exit0`退出执行,所以我们的连接也会被断开。所以要先想办法让 `more`别执行完。`more`命令有一个特性,当输出的内容行数多于终端行数的时候会停下来,等你去翻页,所以我们缩小终端窗口试试。当然这个要尝试,当我们把终端的高度缩小到差不多4行左右,显示如下:

 `--More--(66%)`

这次没有断开了,停下来了。然后就利用 `more`可以使用 `v`调用 `vi`编辑器的特点,然后用 `vi`编辑器就能打开文件了和获得`shell`了,按 `v`进入 `vi`编辑器模式,然后就可以读取密码文件

  `:r /etc/bandit_pass/bandit26`

  `...`

  `5czgV9L3Xx8JPOyRbXh6lQbmIOWvPT6Z`

Level 26 → Level 27

描述:获得一个 `shell`,然后找密码。上一关,我们进了 `vi`编辑器模式了,这就很容易获得一个 `shell`了,因为 `vi`编辑器中是可以打开一个 `shell`的

  `:set shell sh=/bin/sh`2.  `:sh`3.  `[No write since last change]`4.  `

然后执行其他命令

  `$ ls -l`2.  `total 12`3.  `-rwsr-x---  1 bandit27 bandit26 7408  Jul  22  14:46 bandit27-do`4.  `-rw-r-----  1 bandit26 bandit26258  Dec  28 2017 text.txt`5.  `

发现一个具有 `suid`权限的程序,用它去查看 `bandit27`的密码吧

 `$ ./bandit27-do cat /etc/bandit_pass/bandit27`

`3ba3118a22e93127a4ed485be72ef5ea`

Level 27 → Level 28

描述:有一个 `git`仓库,位置在:ssh://bandit27-git@localhost/home/bandit27-git/repo,所使用的密码和用户 `bandit27`的密码一致,克隆这个仓库,并找到下一关的密码。Tips:从这一关开始都是关于 `GIT`的内容,很有意思。这比较简单,使用 `git clone`命令就行

 `bandit27@bandit:~$ cd `mktemp -d ``

`bandit27@bandit:/tmp/tmp.6YwPn6ll84$ git clone ssh://bandit27-git@localhost/home/bandit27-git/repo`

  `Cloning  into  'repo'...`

  `Could  not create directory '/home/bandit27/.ssh'.`

  `....`

  `Are you sure you want to continue connecting (yes/no)? yes`

`Failed to add the host to the list of known hosts (/home/bandit27/.ssh/known_hosts).`

`This  is a OverTheWire game server.  More information on http://www.overthewire.org/wargames`

`bandit27-git@localhost's password:`

 `remote: Counting objects: 3, done.`

 `remote: Compressing objects: 100% (2/2), done.`

  `remote: Total 3 (delta 0), reused 0 (delta 0)`

 `Receiving objects: 100% (3/3), done.`

 `Checking connectivity... done.`

然后找密码

  `bandit27@bandit:/tmp/tmp.6YwPn6ll84$ ls -l`

 `total 4`

  `drwxrwxr-x 3 bandit27 bandit27 4096  Aug 9  19:14 repo`

  `bandit27@bandit:/tmp/tmp.6YwPn6ll84$ cd repo/`

 `bandit27@bandit:/tmp/tmp.6YwPn6ll84/repo$ ls`

  `README`

  `bandit27@bandit:/tmp/tmp.6YwPn6ll84/repo$ cat README` 

 `The password to the next level is:  0ef186ac70e04ea33b4c1853d2526fa2`

  `bandit27@bandit:/tmp/tmp.6YwPn6ll84/repo

Level 28 → Level 29

描述:克隆仓库 ssh://bandit28-git@localhost/home/bandit28-git/repo,密码和当前用户密码一样,然后找密码???黑人???和前一关一样?先 `git clone`吧,然后再看看有什么文件

 `bandit28@bandit:/tmp/tmp.m8mlHhXvGx$ ls -l repo/`

  `total 4`

 `-rw-rw-r--  1 bandit28 bandit28 111  Aug 9  19:20 README.md`

 `bandit28@bandit:/tmp/tmp.m8mlHhXvGx$ cat repo/README.md`

 `# Bandit Notes`

  `Some notes for level29 of bandit.`

 `## credentials`

  `- username: bandit29`

  `- password: xxxxxxxxxx`

  `bandit28@bandit:/tmp/tmp.m8mlHhXvGx

继续????黑人????,这什么鬼,登录 `bandit29`试试?

 `bandit28@bandit:/tmp/tmp.m8mlHhXvGx$ ssh bandit29@localhost`

 `Permission denied, please try again.`

 `bandit29@localhost's password:`

这明显不对啊让我们使用 `git log`命令看看,看看提交历史吧,说不定能发现什么

`bandit28@bandit:/tmp/tmp.m8mlHhXvGx/repo$ git log`

  `commit 04e2414585ba775805a49b78d662d0946d08f27a`

  `Author:  Morla  Porla`

  `Date:  Sun  Jul  22  14:47:13  2018  +0200`

  `fix info leak`6.  `commit 196c3edc79e362fe89e0d75cfeef079d8c67beef`

  `Author:  Morla  Porla`

  `Date:  Sun  Jul  22  14:47:13  2018  +0200`

  `add missing data`

  `commit 80383714fa509a363756866425b0b697e87824a0`

  `Author:  Ben  Dover`

  `Date:  Sun  Jul  22  14:47:13  2018  +0200`

  `initial commit of README.md`

`git log` 会按提交时间列出所有的更新,最近的更新排在最上面。每次更新都有一个 SHA-1 校验和、作者的名字和电子邮件地址、提交时间,最后缩进一个段落显示提交说明。 我们发现了三次提交。然后我们可以使用 `git show`, `git show` :显示各种类型的对象,这些对象包括 `blobs,树,标签和提交`。对于提交,它显示日志消息和文本差异。 它还以 `git diff-tree--cc`生成的特殊格式呈现合并提交。所以我们来看看 `196c3edc79e362fe89e0d75cfeef079d8c67beef` 这一次的提交,因为这一次的提交说明是 `add missing data`,看起来可能有写入密码什么的。

 `bandit28@bandit:/tmp/tmp.m8mlHhXvGx/repo$ git show 196c3edc79e362fe89e0d75cfeef079d8c67beef`

  `commit 196c3edc79e362fe89e0d75cfeef079d8c67beef`

 `Author:  Morla  Porla`

  `Date:  Sun  Jul  22  14:47:13  2018  +0200`

 `add missing data`

  `diff --git a/README.md b/README.md`

  `index 7ba2d2f..3f7cee8  100644`

  `--- a/README.md`

  `+++ b/README.md`

  `@@  -4,5  +4,5  @@  Some notes for level29 of bandit.`

  `## credentials`

  `- username: bandit29`

  `-- password:`

 `+- password: bbc96594b4e001778eee9975372716b2`

Bingo,得到密码了~因为对 `git`命令不是很熟悉,所以这一关卡了很久。然后去翻 `git`的文档.....![image.gif]

Level 29 → Level 30

描述:使用和用户 `bandit29`一样的密码,克隆 `ssh://bandit29-git@localhost/home/bandit29-git/repo`仓库里面的内容,找到密码

 `bandit29@bandit:~$ cd `mktemp -d``

`bandit29@bandit:/tmp/tmp.sRpgdX8JqF$ git clone ssh://bandit29-git@localhost/home/bandit29-git/repo`

老套路先走一波

 `bandit29@bandit:/tmp/tmp.sRpgdX8JqF$ cd repo/`

 `bandit29@bandit:/tmp/tmp.sRpgdX8JqF/repo$ ls`

 `README.md`

 `bandit29@bandit:/tmp/tmp.sRpgdX8JqF/repo$ cat README.md` 

  `# Bandit Notes`

 `Some notes for bandit30 of bandit.`

 `## credentials`

  `- username: bandit30`

 `- password:`

 `bandit29@bandit:/tmp/tmp.sRpgdX8JqF/repo$ git log`

  `commit 279d73d37ee7abbe68a3ec3655ef47bdd0d2ebf2`

 `Author:  Ben  Dover`

  `Date:  Sun  Jul  22  14:47:23  2018  +0200`

  `fix username`

 `commit 0ffeba0f812ef30dcd949a3aae1575270b9a7b06`

  `Author:  Ben  Dover`

  `Date:  Sun  Jul  22  14:47:23  2018  +0200`

  `initial commit of README.md`

  `bandit29@bandit:/tmp/tmp.sRpgdX8JqF/repo$ git show 279d73d37ee7abbe68a3ec3655ef47bdd0d2ebf2`

  `commit 279d73d37ee7abbe68a3ec3655ef47bdd0d2ebf2`

  `Author:  Ben  Dover`

  `Date:  Sun  Jul  22  14:47:23  2018  +0200`

  `fix username`

  `diff --git a/README.md b/README.md`

  `index 2da2f39..1af21d3  100644`

 `--- a/README.md`

 `+++ b/README.md`

  `@@  -3,6  +3,6  @@  Some notes for bandit30 of bandit.`

  `## credentials`

  `-- username: bandit29`

  `+- username: bandit30`

  `- password:`

  `bandit29@bandit:/tmp/tmp.sRpgdX8JqF/repo

提示 `nopasswordsinproduction!`,说明不在当前分支里面。看看其他分支吧,先查看当前分支

`bandit29@bandit:/tmp/tmp.sRpgdX8JqF/repo$ git branch`

`* master`

当前分支是 `master`,然后看一下其他分支

`bandit29@bandit:/tmp/tmp.sRpgdX8JqF/repo$ git branch -a`

 `* master`

`remotes/origin/HEAD -> origin/master`

 `remotes/origin/dev`

  `remotes/origin/master`

 `remotes/origin/sploits-dev`

 `bandit29@bandit:/tmp/tmp.sRpgdX8JqF/repo

发现有 `dev`, `sploits-dev`分支,我们 `checkout`这两个分支看看。

`bandit29@bandit:/tmp/tmp.sRpgdX8JqF/repo$ git checkout -b remotes/origin/dev`

  `Switched to a new branch 'remotes/origin/dev'`

`bandit29@bandit:/tmp/tmp.sRpgdX8JqF/repo$ ls`

 `README.md  code`

  `bandit29@bandit:/tmp/tmp.sRpgdX8JqF/repo$ cd code/`

  `bandit29@bandit:/tmp/tmp.sRpgdX8JqF/repo/code$ ls`

  `gif2ascii.py`

 `bandit29@bandit:/tmp/tmp.sRpgdX8JqF/repo/code$ git log` 

  `commit 77ec80e97de5f88f035911a8d0fce1982dc7da05`

  `Author:  Morla  Porla`

 `Date:  Sun  Jul  22  14:47:23  2018  +0200`

 `add data needed for development`

  `commit 0ced92a1b87e29e4225f45f3f6b803b1343aa8bb`

 `Author:  Ben  Dover`

 `Date:  Sun  Jul  22  14:47:23  2018  +0200`

  `add gif2ascii`

 `commit 279d73d37ee7abbe68a3ec3655ef47bdd0d2ebf2`

  `Author:  Ben  Dover`

  `Date:  Sun  Jul  22  14:47:23  2018  +0200`

  `fix username`

 `commit 0ffeba0f812ef30dcd949a3aae1575270b9a7b06`

  `Author:  Ben  Dover`

  `Date:  Sun  Jul  22  14:47:23  2018  +0200`

  `initial commit of README.md`

 `bandit29@bandit:/tmp/tmp.sRpgdX8JqF/repo/code$ git show 77ec80e97de5f88f035911a8d0fce1982dc7da05`

  `commit 77ec80e97de5f88f035911a8d0fce1982dc7da05`

  `Author:  Morla  Porla`

  `Date:  Sun  Jul  22  14:47:23  2018  +0200`

 `add data needed for development`

  `diff --git a/README.md b/README.md`

  `index 1af21d3..39b87a8  100644`

  `--- a/README.md`

  `+++ b/README.md`

 `@@  -4,5  +4,5  @@  Some notes for bandit30 of bandit.`

  `## credentials`

  `- username: bandit30`

  `-- password:`

  `+- password:  5b90576bedb2cc04c86a9e924ce42faf`

  `bandit29@bandit:/tmp/tmp.sRpgdX8JqF/repo/code

成功得到密码了~~哈哈!

Level 30 → Level 31

描述:同上一关一样,仓库地址 `ssh://bandit30-git@localhost/home/bandit30-git/repo`,密码同 `bandit30`的密码。克隆这一步,就不重复演示了

`bandit30@bandit:/tmp/tmp.jZFFwUNp0R$ ls -al repo/`

 `total 16`

  `drwxrwxr-x 3 bandit30 bandit30 4096  Aug  10  03:26  .`

`drwx------  3 bandit30 bandit30 4096  Aug  10  03:26  ..`

  `drwxrwxr-x 8 bandit30 bandit30 4096  Aug  10  03:26  .git`

 `-rw-rw-r--  1 bandit30 bandit30 30  Aug  10  03:26 README.md`

  `bandit30@bandit:/tmp/tmp.jZFFwUNp0R$ cat repo/README.md` 

 `just an epmty file... muahaha`

  `bandit30@bandit:/tmp/tmp.jZFFwUNp0R

返回一句提示,说这是个空的仓库,你上当了~~~不要方,接着来

  `bandit30@bandit:/tmp/tmp.jZFFwUNp0R$ cd repo/`

 `bandit30@bandit:/tmp/tmp.jZFFwUNp0R/repo$ git log`

  `commit 1791c9d4a559bffa4e6e89c15f7723167da10bb8`

  `Author:  Ben  Dover`

  `Date:  Sun  Jul  22  15:49:42  2018  +0200`

 `initial commit of README.md`

`bandit30@bandit:/tmp/tmp.jZFFwUNp0R/repo$ git branch -a`

  `* master`

  `remotes/origin/HEAD -> origin/master`

  `remotes/origin/master`

  `bandit30@bandit:/tmp/tmp.jZFFwUNp0R/repo

WTF~真没有吗?我们知道 `git clone`还会创建一个神奇的 `.git`的目录,这个目录下包含了所有 git 正常工作所需要的信息 。包括对象存储,配置文件,分支和标签,HEAD文件等。我们来看看这些文件

`bandit30@bandit:/tmp/tmp.jZFFwUNp0R/repo$ ls -al ./.git`

`total 52`

`drwxrwxr-x 8 bandit30 bandit30 4096  Aug  10  03:26  .`

  `drwxrwxr-x 3 bandit30 bandit30 4096  Aug  10  03:26  ..`

 `-rw-rw-r--  1 bandit30 bandit30 23  Aug  10  03:26 HEAD`

  `drwxrwxr-x 2 bandit30 bandit30 4096  Aug  10  03:26 branches`

 `-rw-rw-r--  1 bandit30 bandit30276  Aug  10  03:26 config`

`-rw-rw-r--  1 bandit30 bandit30 73  Aug  10  03:26 description`

  `drwxrwxr-x 2 bandit30 bandit30 4096  Aug  10  03:26 hooks`

  `-rw-rw-r--  1 bandit30 bandit30137  Aug  10  03:26 index`

  `drwxrwxr-x 2 bandit30 bandit30 4096  Aug  10  03:26 info`

  `drwxrwxr-x 3 bandit30 bandit30 4096  Aug  10  03:26 logs`

 `drwxrwxr-x 4 bandit30 bandit30 4096  Aug  10  03:26 objects`

 `-rw-rw-r--  1 bandit30 bandit30165  Aug  10  03:26 packed-refs`

`drwxrwxr-x 5 bandit30 bandit30 4096  Aug  10  03:26 refs`

通过查找相关资料,如果 `commit`丢失或者被删除,是可以这里面的东西进行恢复的。首先我们使用 `git reflog` 工具。【当你 (在一个仓库下) 工作时, `Git` 会在你每次修改了 HEAD 时悄悄地将改动记录下来。当你提交或修改分支时,reflog 就会更新】

  `bandit30@bandit:/tmp/tmp.jZFFwUNp0R/repo$ git reflog`

`1791c9d HEAD@{0}: clone:  from ssh://bandit30-git@localhost/home/bandit30-git/repo`

只有一条,好像没有找到有用的东西。我们再试试用 `git show-ref`看看吧,它的作用是显示本地存储库中可用的引用以及关联的提交ID。此外,它可以用来测试一个特定的ref是否存在。

 `bandit30@bandit:/tmp/tmp.jZFFwUNp0R/repo$ git show-ref`

 `1791c9d4a559bffa4e6e89c15f7723167da10bb8 refs/heads/master`

 `1791c9d4a559bffa4e6e89c15f7723167da10bb8 refs/remotes/origin/HEAD`

`1791c9d4a559bffa4e6e89c15f7723167da10bb8 refs/remotes/origin/master`

 `f17132340e8ee6c159e0a4a6bc6f80e1da3b1aea refs/tags/secret`

我们看看它创建时提交的元数据,使用 `git show`

 `bandit30@bandit:/tmp/tmp.jZFFwUNp0R/repo$ git show f17132340e8ee6c159e0a4a6bc6f80e1da3b1aea`

`47e603bb428404d265f59c42920d81e5`

所以密码是`47e603bb428404d265f59c42920d81e5`。这一步的坑主要在于,你要搞清楚 `GitReferences`。这一关,一开始我以为是 `commit`被删除,需要恢复,后来才注意到是需要找到“引用”。

Level 31 → Level 32

描述:克隆仓库`ssh://bandit31-git@localhost/home/bandit31-git/repo`,密码同 `bandit31`用户密码一致,然后找到密码。克隆这一步,就不重复演示了

 `bandit31@bandit:/tmp/tmp.DBV43tK30K/repo$ ls -al`

  `total 20`

  `drwxrwxr-x 3 bandit31 bandit31 4096  Aug  10  05:01  .`

 `drwx------  3 bandit31 bandit31 4096  Aug  10  05:01  ..`

 `drwxrwxr-x 8 bandit31 bandit31 4096  Aug  10  05:01  .git`

  `-rw-rw-r--  1 bandit31 bandit316  Aug  10  05:01  .gitignore`

 `-rw-rw-r--  1 bandit31 bandit31147  Aug  10  05:01 README.md`

`bandit31@bandit:/tmp/tmp.DBV43tK30K/repo$ cat README.md  `

  `This time your task is to push a file to the remote repository.`

  `Details:`

 `File name: key.txt`

  `Content:  'May I come in?'`

 `Branch: master`

`bandit31@bandit:/tmp/tmp.DBV43tK30K/repo$ cat ./.gitignore` 

  `*.txt`

  `bandit31@bandit:/tmp/tmp.DBV43tK30K/repo

仓库里面给出了两个文件,其中有一个提示,提示说,需要把 `key.txt`PUSH给远程仓库,内容是 `MayI comein?`。还有一个是 `.gitignore`文件,这是一个特殊的文件,如果你在弄项目的时候,某些文件不想提交,就把要忽略的文件名填进去,Git就会自动忽略这些文件 。我们看到规则是忽略了 `*.txt`文件,所以如果直接提交 `key.txt`,这个文件会被被忽略掉了,这会导致我们提交不成功。先新建一个 `key.txt`,然后提交

  `bandit31@bandit:/tmp/tmp.DBV43tK30K/repo$ echo "May I come in?"  > key.txt`

  `bandit31@bandit:/tmp/tmp.DBV43tK30K/repo$ git add .`

.  `bandit31@bandit:/tmp/tmp.DBV43tK30K/repo$ git add key.txt`

 `The following paths are ignored by one of your .gitignore files:`

 `key.txt`

  `Use  -f if you really want to add them.`

 `bandit31@bandit:/tmp/tmp.DBV43tK30K/repo

没成功吧,提示你可以试试 `-f`参数,如果你对 `linux`命令较为熟悉的话, `-f`代表的应该是强制的意思

 `bandit31@bandit:/tmp/tmp.DBV43tK30K/repo$ git add -f key.txt`

 `bandit31@bandit:/tmp/tmp.DBV43tK30K/repo$ git commit`

`Unable to create directory /home/bandit31/.nano:  Permission denied`

  `It  is required for saving/loading search history or cursor positions.`

  `Press  Enter to continue`

这里会打开 `nano`编辑器,然后输入一些提交说明,然后保存即可,会返回提交信息

 `[master 2532497]  Add file!!`

 `2 files changed,  1 insertion(+),  1 deletion(-)`

  `delete mode 100644  .gitignore`

  `create mode 100644 key.txt`

  `bandit31@bandit:/tmp/tmp.DBV43tK30K/repo

然后执行 `git push`

`bandit31@bandit:/tmp/tmp.DBV43tK30K/repo$ git push`

  `warning: push.default  is unset; its implicit value has changed in`

 `Git  2.0  from  'matching' to 'simple'.  To squelch this message`

  `...`

  `ECDSA key fingerprint is SHA256:98UL0ZWr85496EtCRkKlo20X3OPnyPSB5tB5RPbhczc.`

 `Are you sure you want to continue connecting (yes/no)? yes`

`Failed to add the host to the list of known hosts (/home/bandit31/.ssh/known_hosts).`

  `This  is a OverTheWire game server.  More information on http://www.overthewire.org/wargames`

  `bandit31-git@localhost's password:` 

  `Counting objects: 3, done.`

  `Delta compression using up to 4 threads.`

  `Compressing objects: 100% (2/2), done.`

  `Writing objects: 100% (3/3), 287 bytes | 0 bytes/s, done.`

  `Total 3 (delta 0), reused 0 (delta 0)`

 `remote: ### Attempting to validate files... ####`

  `remote:` 

  `remote: .oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.`

 `remote:`

  `remote: Well done! Here is the password for the next level:`

 `remote: 56a9bf19c63d650ce78e6ec0354ee45e`

  `remote:` 

  `remote: .oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.`

 `remote:` 

  `To ssh://bandit31-git@localhost/home/bandit31-git/repo`

  `! [remote rejected] master -> master (pre-receive hook declined)`

  `error: failed to push some refs to 'ssh://bandit31-git@localhost/home/bandit31-git/repo'`

  `bandit31@bandit:/tmp/tmp.DBV43tK30K/repo

成功得到下一关的密码!

Level 32→ Level 33

描述:Good Luck我们先是找到这么一个脚本 `uppershell`

`bandit32@bandit:~$ ls -l`

  `total 8`

  `-rwsr-x---  1 bandit33 bandit32 7668  Jul  22  18:59 uppershell`

这个脚本有 `SUID`权限,我们试试能不能通过它去调用 `cat`呢?

  `bandit32@bandit:~$ ./uppershell cat /etc/bandit_pass/bandit33`

  `WELCOME TO THE UPPERCASE SHELL`

 `>>`

直接进入一个 `shell`看看能不能执行命令

  `>> ls`

  `sh:  1: LS:  not found`

 `>>  ?`

  `sh:  1:  ?:  not found`

  `>> cat /etc/bandit_pass/bandit33`

 `sh:  1: CAT:  not found`

 `>>`

好像什么都干不了啊。提示找不到相应的命令。为什么了,因为命令都被转为大写字母了。我们知道,在 `Linux`系统中,大小写严格区分的。所以我们看出来了,这个程序只能执行大写字母的命令。那我们是不是换一个思路,我们写一个脚本,脚本名字用大写字母,脚本内容执行一个 `shell`,然后运行这个脚本是不是可以呢?先在 `tmp` 目录中,新建一个临时目录,用来放写好的脚本

  `bandit32@bandit:/tmp/tmp.bvfaHIDns3$ vim GETSHELL`

 `bandit32@bandit:/tmp/tmp.bvfaHIDns3$ chmod 777 GETSHELL`

  `bandit32@bandit:/tmp/tmp.bvfaHIDns3$ cat GETSHELL`

  `#!/bin/bash`

  `bash`

先执行脚本 `uppershell`,再调用我们写好的脚本试试

  `bandit32@bandit:/tmp/tmp.bvfaHIDns3$ ~/uppershell`

 `WELCOME TO THE UPPERCASE SHELL`

  `>>  ./GETSHELL`

  `sh:  1:  ./GETSHELL:  Permission denied`

 `>>`

权限不足?试试绝对路径

  `>>  /tmp/tmp.bvfaHIDns3/GETSHELL`

  `sh:  1:  /TMP/TMP.BVFAHIDNS3/GETSHELL:  not found`

  `>>`

坑了,路径都变成大写了。最后我试试改了下目录的权限

  `bandit32@bandit:/tmp/tmp.bvfaHIDns3$ chmod 777  -R  .`

 `bandit32@bandit:/tmp/tmp.bvfaHIDns3$ ~/uppershell`

  `WELCOME TO THE UPPERCASE SHELL`

 `>>  ./GETSHELL`

  `bandit33@bandit:/tmp/tmp.bvfaHIDns3

我们的脚本被执行了,成功获取到了 `shell`,而且是 `bandit33`的 `shell`哦。这里你可能会奇怪,为什么我们在 `bandit32`用户下执行的命令,怎么变成 `bandit33`了。别忘了我们的脚本是通过 `uppershell`这个程序执行,而这个程序的所有者是 `bandit33`,并且具有 `SUID`权限。

 `bandit32@bandit:~$ ls -l`

 `total 8`

  `-rwsr-x---  1 bandit33 bandit32 7668  Jul  22  18:59 uppershell`

然后查看进入 `bandit33`的密码吧

  `bandit33@bandit:/tmp/tmp.bvfaHIDns3$ cat /etc/bandit_pass/bandit33`

  `c9c3199ddf4121b10cf581a98d51caee`

你以为就这样完了?没错!就是完了。官方暂时只更新到 Level33。

至此,Bandit 挑战全部33关完成。完结撒花~~~> 

参考文档:> > [黑客GIT指南]> > https://wildlyinaccurate.com/a-hackers-guide-to-git/#git-reflog




文章仅用于普及网络安全知识,提高小伙伴的安全意识的同时介绍常见漏洞的特征等,若读者因此做出危害网络安全的行为后果自负,与合天智汇以及原作者无关,特此声明。

你可能感兴趣的:(完结篇:OverTheWire Bandit Writeup (20-33))