# HackTheBox - CDNio
## Category: Web
## Level: Easy
### Exploitation
- Nhìn sơ qua ban đầu, đây là một trang web khá đơn giản, với chức năng search thông tin của user có trong hệ thống, bao gồm:
- ID
- Username
- Email
- API Key
- Created Time

- Trong file `entrypoint.sh` được cung cấp, nhận thấy Flag nằm ở user `admin`.

- Như vậy vấn đề nằm ở việc truy cập được, hoặc tìm kiếm được user này
- Sau một lúc tìm hiểu source code:
- Ứng dụng sử dụng JWT để xác thực
- Khi tìm kiếm một user, sẽ có token được trả về, với giá trị `sub` là tên user đó


- Thành phần `bot.py` khi nhận được URI sẽ gửi request đến `http://0.0.0.0:1337/[URI]`
```Python
base_url = "http://0.0.0.0:1337"
admin_passwd = os.getenv("RANDOM_PASSWORD")
base_headers = {
"User-Agent": "CDNio Bot ()"
}
def login_and_get_token():
session = requests.Session()
login_url = f"{base_url}/"
payload = {
"username": "admin",
"password": admin_passwd
}
response = session.post(login_url, json=payload, headers=base_headers)
if response.status_code == 200:
token = response.json().get("token")
return token, session
else:
return None, None
def bot_runner(uri):
token, session = login_and_get_token()
headers = {
**base_headers,
"Authorization": f"Bearer {token}"
}
r = requests.get(f"{base_url}/{uri}", headers=headers)
time.sleep(5)
def bot_thread(uri):
bot_runner(uri)
```

- Mặt khác, logic hiển thị thông tin của user lại không rõ ràng:
```Python
@main_bp.route('/<path:subpath>', methods=['GET'])
@jwt_required
def profile(subpath):
if re.match(r'.*^profile', subpath):
...
```
- Chỉ cần endpoint dạng `/...profile...` thì sẽ được được thông tin
- Như vậy, để khai thác `api_key` của `admin` (chứa Flag), có thể thực hiện như sau:
- Login vào một user để lấy token

- Sử dụng token đó để khiến `bot` truy cập vào profile của `admin` (sử dụng `/...profile...` thay vì `/profile`)

- Cuối cùng, truy cập vào endpoint đó và thấy thông tin của admin được hiển thị

**Lưu ý:** Dữ liệu của admin chỉ được lưu trữ trong cache trong vòng 3 phút (Do đã được config)
```
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
proxy_cache cache;
proxy_cache_valid 200 3m;
proxy_cache_use_stale error timeout updating;
expires 3m;
add_header Cache-Control "public";
```
### Result
```
HTB{cDN_10_OoOoOoO_Sc1_F1_iOOOO0000}
```