diff --git a/.github/ISSUE_TEMPLATE/bug.yaml b/.github/ISSUE_TEMPLATE/bug.yaml index dee0719..97f9373 100644 --- a/.github/ISSUE_TEMPLATE/bug.yaml +++ b/.github/ISSUE_TEMPLATE/bug.yaml @@ -1,7 +1,6 @@ name: Bug Report description: File a bug report. title: "[Bug]: " -type: Bug body: - type: markdown attributes: @@ -12,13 +11,13 @@ body: label: Rayhunter Version description: | Which version did you install? - placeholder: v0.2.6 + placeholder: "v0.2.6" - type: input attributes: label: Capture Date description: | YYYY-MM-DD - placeholder: 2025-05-01 + placeholder: "2025-05-01" validations: required: true - type: input @@ -27,8 +26,6 @@ body: description: | (If comfortable disclosing) What region or country were you in? placeholder: Washington State - validations: - required: false - type: input attributes: label: Device and Model @@ -43,7 +40,7 @@ body: label: What happened? description: | What steps did you take to get to your issue? - placeholder: Tell us what you see! + placeholder: "Tell us what you see!" validations: required: true - type: textarea diff --git a/.github/ISSUE_TEMPLATE/config.yaml b/.github/ISSUE_TEMPLATE/config.yml similarity index 100% rename from .github/ISSUE_TEMPLATE/config.yaml rename to .github/ISSUE_TEMPLATE/config.yml diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index decffc9..4c578f7 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -16,29 +16,38 @@ jobs: platform: - name: ubuntu-24 os: ubuntu-latest + target: x86_64-unknown-linux-musl - name: ubuntu-24-aarch64 os: ubuntu-24.04-arm + target: aarch64-unknown-linux-musl - name: macos-arm os: macos-latest + target: aarch64-apple-darwin - name: macos-intel os: macos-13 + target: x86_64-apple-darwin + - name: windows-x86_64 + os: windows-latest runs-on: ${{ matrix.platform.os }} steps: - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + targets: ${{ matrix.platform.target }} - name: Build serial - run: cargo build --bin serial --release + run: cargo build --bin serial --release --target ${{ matrix.platform.target }} - uses: actions/upload-artifact@v4 with: name: serial-${{ matrix.platform.name }} - path: ./target/release/serial + path: target/${{ matrix.platform.target }}/release/serial${{ matrix.platform.os == 'windows-latest' && '.exe' || '' }} if-no-files-found: error - uses: actions/checkout@v4 - name: Build check run: cargo build --bin rayhunter-check --release - uses: actions/upload-artifact@v4 with: - name: rayhunter-check-${{ matrix.platform.os }} - path: ./target/release/rayhunter-check + name: rayhunter-check-${{ matrix.platform.name }} + path: target/release/rayhunter-check${{ matrix.platform.os == 'windows-latest' && '.exe' || '' }} if-no-files-found: error build_rootshell: runs-on: ubuntu-latest diff --git a/.github/workflows/check-and-test.yml b/.github/workflows/check-and-test.yml index e84e324..8779b45 100644 --- a/.github/workflows/check-and-test.yml +++ b/.github/workflows/check-and-test.yml @@ -24,3 +24,18 @@ jobs: run: cargo check --verbose --no-default-features --features=${{ matrix.device.name }} - name: Run tests run: cargo test --verbose --no-default-features --features=${{ matrix.device.name }} + + windows_serial_check_and_test: + runs-on: windows-latest + steps: + - uses: actions/checkout@v3 + - name: cargo check + shell: bash + run: | + cd serial + cargo check --verbose + - name: cargo test + shell: bash + run: | + cd serial + cargo test --verbose --no-default-features --features=${{ matrix.device.name }} \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 9492106..db5c041 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -188,13 +188,13 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "axum" -version = "0.7.4" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1236b4b292f6c4d6dc34604bb5120d85c3fe1d1aa596bd5cc52ca054d13e7b9e" +checksum = "de45108900e1f9b9242f7f2e254aa3e2c029c921c258fe9e6b4217eeebd54288" dependencies = [ - "async-trait", "axum-core", "bytes", + "form_urlencoded", "futures-util", "http", "http-body", @@ -214,7 +214,7 @@ dependencies = [ "serde_urlencoded", "sync_wrapper", "tokio", - "tower", + "tower 0.5.2", "tower-layer", "tower-service", "tracing", @@ -222,13 +222,12 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.4.3" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" +checksum = "68464cd0412f486726fb3373129ef5d2993f90c34bc2bc1c1e9943b2f4fc7ca6" dependencies = [ - "async-trait", "bytes", - "futures-util", + "futures-core", "http", "http-body", "http-body-util", @@ -708,25 +707,6 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" -[[package]] -name = "h2" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" -dependencies = [ - "atomic-waker", - "bytes", - "fnv", - "futures-core", - "futures-sink", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - [[package]] name = "hashbrown" version = "0.14.3" @@ -810,7 +790,6 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2", "http", "http-body", "httparse", @@ -835,6 +814,8 @@ dependencies = [ "pin-project-lite", "socket2", "tokio", + "tower 0.4.13", + "tower-service", ] [[package]] @@ -990,9 +971,9 @@ dependencies = [ [[package]] name = "matchit" -version = "0.7.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" [[package]] name = "memchr" @@ -1546,9 +1527,9 @@ dependencies = [ [[package]] name = "sync_wrapper" -version = "0.1.2" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" [[package]] name = "tap" @@ -1706,7 +1687,6 @@ dependencies = [ "hashbrown", "pin-project-lite", "tokio", - "tracing", ] [[package]] @@ -1777,16 +1757,32 @@ dependencies = [ ] [[package]] -name = "tower-layer" -version = "0.3.2" +name = "tower" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" diff --git a/README.md b/README.md index 25564ac..bd9bc1a 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,11 @@ Great news: if you've successfully installed rayhunter, you already know how to ## Usage (viewing the web UI) -Once installed, Rayhunter will run automatically whenever your Orbic device is running. It serves a web UI that provides some basic controls, such as being able to start/stop recordings, download captures, and view heuristic analyses of captures. You can access this UI in one of two ways: +Once installed, Rayhunter will run automatically whenever your Orbic device is running. You'll see a green line on top of the device's display to indicate that it's running and recording to the SD-card. [The line will turn red](#red) once a potential IMSI catcher has been found, until the device is rebooted or a new recording is started through the web UI. + +It also serves a web UI that provides some basic controls, such as being able to start/stop recordings, download captures, and view heuristic analyses of captures. + +You can access this UI in one of two ways: 1. **Connect over wifi:** Connect your phone/laptop to the Orbic's 2.4GHz wifi network and visit [http://192.168.1.1:8080](http://192.168.1.1:8080). (Click past your browser warning you about the connection not being secure, Rayhunter doesn't have HTTPS yet). * You can find the wifi network password by going to the Orbic's menu > 2.4 GHz WIFI Info > Enter > find the 8-character password next to the lock 🔒 icon. @@ -69,6 +73,8 @@ Once installed, Rayhunter will run automatically whenever your Orbic device is r **It Depends**. Operation of Rayhunter does require the insertion of a SIM card into the device, but whether that SIM card has to be currently active for our tests to work is still under investigation. If you want to use the device as a hotspot in addition to a research device an active plan would of course be necessary, however we have not done enough testing yet to know whether an active subscription is required for detection. If you want to test the device with an inactive SIM card, we would certainly be interested in seeing any data you collect, and especially any runs that trigger an alert! + + ### Help, Rayhunter's line is red! What should I do? Unfortunately, the circumstances that might lead to a positive cell site simulator (CSS) signal are quite varied, so we don't have a universal recommendation for how to deal with the a positive signal. Depending on your circumstances and threat model, you may want to turn off your phone until you are out of the area (or put it on airplane mode) and tell your friends to do the same! diff --git a/bin/Cargo.toml b/bin/Cargo.toml index 6097927..580e52b 100644 --- a/bin/Cargo.toml +++ b/bin/Cargo.toml @@ -23,13 +23,13 @@ rayhunter = { path = "../lib" } toml = "0.8.8" serde = { version = "1.0.193", features = ["derive"] } tokio = { version = "1.44.2", features = ["full"] } -axum = "0.7.3" +axum = "0.8" futures-core = "0.3.30" thiserror = "1.0.52" libc = "0.2.150" log = "0.4.20" env_logger = "0.10.1" -tokio-util = { version = "0.7.10", features = ["rt"] } +tokio-util = { version = "0.7.10", features = ["rt", "io"] } futures-macro = "0.3.30" include_dir = "0.7.3" mime_guess = "2.0.4" diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 08508de..a71cf33 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -1,6 +1,5 @@ pub mod hdlc; pub mod diag; -pub mod diag_device; pub mod qmdl; pub mod log_codes; pub mod gsmtap; @@ -9,5 +8,9 @@ pub mod pcap; pub mod analysis; pub mod util; +// bin/check.rs may target windows and does not use this mod +#[cfg(target_family = "unix")] +pub mod diag_device; + // re-export telcom_parser, since we use its types in our API pub use telcom_parser; diff --git a/lib/src/util.rs b/lib/src/util.rs index 5d719ea..457a440 100644 --- a/lib/src/util.rs +++ b/lib/src/util.rs @@ -1,6 +1,8 @@ -use nix::sys::utsname::uname; use serde::Serialize; +#[cfg(target_family = "unix")] +use nix::sys::utsname::uname; + /// Expose binary and system information. #[derive(Serialize, Debug)] pub struct RuntimeMetadata { @@ -23,6 +25,16 @@ impl RuntimeMetadata { /// attributes from `uname(2)` and falling back to values from /// `std::env::consts`. pub fn new() -> Self { + let build_target = RuntimeMetadata { + rayhunter_version: env!("CARGO_PKG_VERSION").to_owned(), + arch: std::env::consts::ARCH.to_string(), + system_os: std::env::consts::OS.to_string(), + }; + + #[cfg(target_family = "windows")] + return build_target; + + #[cfg(target_family = "unix")] match uname() { Ok(utsname) => RuntimeMetadata { rayhunter_version: env!("CARGO_PKG_VERSION").to_owned(), @@ -33,11 +45,7 @@ impl RuntimeMetadata { utsname.release().to_string_lossy(), ), }, - Err(_) => RuntimeMetadata { - rayhunter_version: env!("CARGO_PKG_VERSION").to_owned(), - arch: std::env::consts::ARCH.to_string(), - system_os: std::env::consts::OS.to_string(), - }, + Err(_) => build_target, } } } diff --git a/serial/src/main.rs b/serial/src/main.rs index 115b614..812a499 100644 --- a/serial/src/main.rs +++ b/serial/src/main.rs @@ -107,7 +107,7 @@ fn enable_command_mode() -> Result<()> { let timeout = Duration::from_secs(1); - if let Some(interface) = open_device(0x05c6, 0xf626)? { + if let Some(device) = open_device(0x05c6, 0xf626)? { let enable_command_mode = Control { control_type: ControlType::Vendor, recipient: Recipient::Device, @@ -115,6 +115,9 @@ fn enable_command_mode() -> Result<()> { value: 0, index: 0, }; + let interface = device + .detach_and_claim_interface(1) + .context("detach_and_claim_interface(1) failed")?; if let Err(e) = interface.control_out_blocking(enable_command_mode, &[], timeout) { // If the device reboots while the command is still executing we // may get a pipe error here diff --git a/tools/devenv.dockerfile b/tools/devenv.dockerfile new file mode 100644 index 0000000..e5dfaa3 --- /dev/null +++ b/tools/devenv.dockerfile @@ -0,0 +1,5 @@ +FROM rust:1.86-bullseye + +RUN apt-get update +RUN apt-get install -y build-essential libc6-armhf-cross libc6-dev-armhf-cross gcc-arm-linux-gnueabihf +RUN rustup target add armv7-unknown-linux-gnueabihf diff --git a/tools/run-docker-devenv b/tools/run-docker-devenv new file mode 100755 index 0000000..954fd47 --- /dev/null +++ b/tools/run-docker-devenv @@ -0,0 +1,17 @@ +#!/bin/sh + +# Tool to cross-compile outside of Linux. +# +# On MacOS, OrbStack is recommended, but other docker distributions will work +# too. +# +# Usage: +# ./tools/run-docker-devenv +# +# Inside the shell: +# cargo build --bin rayhunter-daemon --target armv7-unknown-linux-gnueabihf --release +# +# Your output binary is in ./target/armv7-unknown-linux-gnueabihf/release/rayhunter-daemon + +docker build -t rayhunter-devenv -f tools/devenv.dockerfile . +exec docker run --user $UID:$GID -v ./:/workdir -w /workdir -it rayhunter-devenv "$@"