From 767d9a0e6d535163b55524161ef56709f94ccea8 Mon Sep 17 00:00:00 2001 From: Markus Pettersson Date: Wed, 13 Nov 2024 13:50:46 +0100 Subject: [PATCH] WIP Add end-to-end test for MLLVD_CR_24_03 --- .../src/tests/audits/mllvd_cr_24_03.rs | 71 +++++++++++++++++++ test/test-manager/src/tests/audits/mod.rs | 1 + 2 files changed, 72 insertions(+) create mode 100644 test/test-manager/src/tests/audits/mllvd_cr_24_03.rs diff --git a/test/test-manager/src/tests/audits/mllvd_cr_24_03.rs b/test/test-manager/src/tests/audits/mllvd_cr_24_03.rs new file mode 100644 index 000000000000..9f049deb7994 --- /dev/null +++ b/test/test-manager/src/tests/audits/mllvd_cr_24_03.rs @@ -0,0 +1,71 @@ +#![cfg(target_os = "linux")] +//! Test mitigation for mllv_cr_24_03 +//! +//! TODO: Describe the audit issue and how it is tested. +//! +//! Victim: test-runner +//! Network adjacent attacker: test-manager +//! +//! # Setup +//! Have test-runner connect to relay. Then let the test-manager know about the test-runner's +//! private in-tunnel IP (such that we don't have to enumerate all possible private IPs). +//! +//! # Procedure +//! Have test-manager invoke the `arping` command with a fixed timeout targetting the bridge +//! network between test-manager <-> test-runner. . If `arping` times out without a reply, it will +//! exit with a non-0 exit code. If it got a reply from test-runner, it will exit with code 0. +//! +//! Note that only linux was susceptible to this vulnerability. + +use std::ffi::OsStr; +use std::process::ExitStatus; + +use anyhow::bail; +use mullvad_management_interface::MullvadProxyClient; +use test_macro::test_function; +use test_rpc::ServiceClient; + +use crate::tests::helpers::*; +use crate::tests::TestContext; +use crate::vm::network::bridge; + +#[test_function(target_os = "linux")] +pub async fn test_mllvd_cr_24_03( + _: TestContext, + _rpc: ServiceClient, + mut mullvad_client: MullvadProxyClient, +) -> anyhow::Result<()> { + // Get the bridge network between manager and runner. This will be used when invoking `arping`. + let bridge = bridge()?; + // Connect runner to a relay. After this point we will be able to acquire the runner's private + // in-tunnel IP. + connect_and_wait(&mut mullvad_client).await?; + // Get the private ip address + // TODO: Acquire the _real_ in-tunnel IP + let in_tunnel_ip: &str = "10.138.255.153"; + // Invoke arping + let Some(code) = arping(["-w", "5", "-i", "1", "-I", &bridge, in_tunnel_ip]) + .await? + .code() + else { + bail!("arping terminated by signal") + }; + // If arping exited with code 0, that means that the runner replied to the ARP request. + // I.e., the runner leaked its private in-tunnel IP! + if code == 0 { + // TODO: Add a more descriptive error message! + bail!("ARP leak detected") + } + // test runner did not respond to ARP request, leak mitigation seems to work! + Ok(()) +} + +async fn arping(args: I) -> std::io::Result +where + I: IntoIterator, + S: AsRef, +{ + let mut arping = tokio::process::Command::new("arping"); + arping.args(args); + arping.spawn()?.wait().await +} diff --git a/test/test-manager/src/tests/audits/mod.rs b/test/test-manager/src/tests/audits/mod.rs index b34257c71f63..c580c5c47c79 100644 --- a/test/test-manager/src/tests/audits/mod.rs +++ b/test/test-manager/src/tests/audits/mod.rs @@ -1,3 +1,4 @@ //! This module collects tests for old audit issues to prevent any potential regression. pub mod cve_2019_14899; +pub mod mllvd_cr_24_03; pub mod mul_02_002;