---
# System prepended metadata

title: Web - CDNio

---

# 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
    
![image](https://hackmd.io/_uploads/BktVjSo2xe.png)
    
- Trong file `entrypoint.sh` được cung cấp, nhận thấy Flag nằm ở user `admin`.

![image](https://hackmd.io/_uploads/rJ902Hjhxl.png)

- 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 đó
    ![image](https://hackmd.io/_uploads/H1t478onex.png)
    ![image](https://hackmd.io/_uploads/rJXPQLihxx.png)
    
    - 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)
    ```
    
    ![image](https://hackmd.io/_uploads/BkQKN8shlg.png)

    
    - 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
    ![image](https://hackmd.io/_uploads/BJRoKUj2lx.png)

    - Sử dụng token đó để khiến `bot` truy cập vào profile của `admin` (sử dụng `/...profile...` thay vì `/profile`)
    ![image](https://hackmd.io/_uploads/r1NxqLshle.png)

    - Cuối cùng, truy cập vào endpoint đó và thấy thông tin của admin được hiển thị
    ![image](https://hackmd.io/_uploads/H1JpuIohgl.png)
    
    **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}
```