From 0ad60ef8bb254d92493f64d52be38fa670f87fb5 Mon Sep 17 00:00:00 2001 From: Cooper Quintin Date: Fri, 2 Feb 2024 16:31:24 -0800 Subject: [PATCH 01/10] starting docs --- Cargo.lock | 4 ++-- README.md | 3 ++- rootshell/src/main.rs | 5 ++++- serial/src/main.rs | 33 +++++++++++++++++++++++++++++++-- 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index de1bbff..59c504f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1227,9 +1227,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.35.1" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" dependencies = [ "backtrace", "bytes", diff --git a/README.md b/README.md index e7fcd25..cff3aec 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ _ _ _ _ _ _ _ _ \ | apc '._| \__; ``` +![Tests](https://github.com/EFForg/rayhunter/actions/workflows/rust.yml/badge.svg) Rayhunter is an IMSI Catcher Catcher for the Orbic mobile hotspot. Based on code from [QCSuper](https://github.com/P1sec/QCSuper) @@ -69,4 +70,4 @@ Build for arm using `cargo build` Run tests using `cargo test_pc` -push to the device with `./make.sh` \ No newline at end of file +push to the device with `./make.sh` diff --git a/rootshell/src/main.rs b/rootshell/src/main.rs index b78b168..cecc5a6 100644 --- a/rootshell/src/main.rs +++ b/rootshell/src/main.rs @@ -1,3 +1,6 @@ +//! a simple shell for uploading to the orbic device. +//! +//! It literally just runs bash as UID/GID 0 use std::process::Command; use std::os::unix::process::CommandExt; use std::env; @@ -12,4 +15,4 @@ fn main() { .uid(0) .gid(0) .exec(); -} \ No newline at end of file +} diff --git a/serial/src/main.rs b/serial/src/main.rs index c6f2ee2..fd2a20c 100644 --- a/serial/src/main.rs +++ b/serial/src/main.rs @@ -1,3 +1,24 @@ +//! Serial communication with the orbic device +//! +//! This binary has two main functions, putting the orbic device in update mode which enables ADB +//! and running AT commands on the serial modem interface which can be used to upload a shell and chown it to root +//! +//! # Panics +//! +//! No device found - make sure your device is plugged in and turned on. If it is, it's possible you have a device with a different +//! usb id, file a bug with the output of `lsusb` attached. +//! +//! # Examples +//! ``` +//! match rusb::Context::new() { +//! Ok(mut context) => match open_orbic(&mut context) { +//! Some(mut handle) => { +//! send_command(&mut handle, &args[1]) +//! }, +//! None => panic!("No Orbic device found"), +//! }, +//! Err(e) => panic!("Failed to initialize libusb: {0}", e), +//! ```` use std::str; use std::thread::sleep; use std::time::Duration; @@ -24,7 +45,9 @@ fn main() { Err(e) => panic!("Failed to initialize libusb: {0}", e), } } - +/// Sends an AT command to the usb device over the serial port +/// +/// First establish a USB handle and context by calling `open_orbic() fn send_command( handle: &mut DeviceHandle, command: &str, @@ -55,10 +78,12 @@ fn send_command( } } +/// Send a command to switch the device into generic mode, exposing serial +/// +/// If the device reboots while the command is still executing you may get a pipe error here, not sure what to do about this race condition. fn switch_device( handle: &mut DeviceHandle, ) { - // Send a command to switch the device into generic mode, exposing serial let timeout = Duration::from_secs(1); if let Err(e) = handle.write_control(0x40, 0xa0, 0, 0, &[], timeout) { @@ -71,6 +96,9 @@ fn switch_device( } } +/// Get a handle and contet for the orbic device +/// +/// If the device isn't already in command mode this function will call swtich_device to switch it into command mode fn open_orbic( context: &mut T, ) -> Option> { @@ -99,6 +127,7 @@ fn open_orbic( panic!("No Orbic device detected") } +/// Generic function to open a USB device fn open_device( context: &mut T, vid: u16, From 6be208698bfd8682a89b02866ee98331eb5c4650 Mon Sep 17 00:00:00 2001 From: Cooper Quintin Date: Wed, 28 Feb 2024 16:05:46 -0800 Subject: [PATCH 02/10] merge --- lib/Cargo.toml | 5 +++++ make.sh | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 88b72ac..4902c33 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -4,6 +4,11 @@ version = "0.1.0" edition = "2021" description = "Realtime cellular data decoding and analysis for IMSI catcher detection" + +[lib] +name = "rayhunter" +path = "src/lib.rs" + [dependencies] bytes = "1.5.0" chrono = "0.4.31" diff --git a/make.sh b/make.sh index 1a248b8..233fbbb 100755 --- a/make.sh +++ b/make.sh @@ -1,4 +1,4 @@ #!/bin/sh -cargo build --release --target="armv7-unknown-linux-gnueabihf" --bin rayhunter-daemon -adb push target/armv7-unknown-linux-gnueabihf/release/rayhunter-daemon /data/rayhunter/ +cargo build --release --target="armv7-unknown-linux-gnueabihf" +adb push target/armv7-unknown-linux-gnueabihf/release/rayhunter-daemon /data/rayhunter/rayhunter adb shell '/bin/rootshell -c "/etc/init.d/rayhunter_daemon restart"' From 63e9c53dd4999a849dfdf4f266bb623448addc25 Mon Sep 17 00:00:00 2001 From: Cooper Quintin Date: Thu, 29 Feb 2024 15:19:25 -0800 Subject: [PATCH 03/10] server listen publicly --- bin/src/main.rs | 2 +- lib/src/pcap.rs | 2 ++ scripts/rayhunter_daemon | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/bin/src/main.rs b/bin/src/main.rs index 892e914..4d65521 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -55,7 +55,7 @@ async fn run_server( .route("/", get(|| async { Redirect::permanent("/index.html") })) .route("/*path", get(serve_static)) .with_state(state); - let addr = SocketAddr::from(([127, 0, 0, 1], config.port)); + let addr = SocketAddr::from(([0, 0, 0, 0], config.port)); let listener = TcpListener::bind(&addr).await.unwrap(); task_tracker.spawn(async move { info!("The orca is hunting for stingrays..."); diff --git a/lib/src/pcap.rs b/lib/src/pcap.rs index 7bd5197..f86355b 100644 --- a/lib/src/pcap.rs +++ b/lib/src/pcap.rs @@ -1,3 +1,5 @@ +//! Parse QMDL files and create a pcap file. +//! Creates a plausible IP header and [GSMtap](https://osmocom.org/projects/baseband/wiki/GSMTAP) header and then puts the rest of the data under that for wireshark to parse. use crate::gsmtap::GsmtapMessage; use crate::diag::Timestamp; diff --git a/scripts/rayhunter_daemon b/scripts/rayhunter_daemon index 44485e7..3697c9c 100644 --- a/scripts/rayhunter_daemon +++ b/scripts/rayhunter_daemon @@ -6,7 +6,7 @@ case "$1" in start) echo -n "Starting rayhunter: " start-stop-daemon -S -b --make-pidfile --pidfile /tmp/rayhunter.pid \ - --startas /bin/bash -- -c "exec /data/rayhunter/rayhunter-daemon /data/rayhunter/config.toml > /data/rayhunter/rayhunter.log 2>&1" + --startas /bin/bash -- -c "RUST_LOG=info exec /data/rayhunter/rayhunter-daemon /data/rayhunter/config.toml > /data/rayhunter/rayhunter.log 2>&1" echo "done" ;; stop) From 0d0cad2be6025d54930326ebf166eb8caf4b185c Mon Sep 17 00:00:00 2001 From: Cooper Quintin Date: Wed, 13 Mar 2024 13:40:15 -0700 Subject: [PATCH 04/10] remove extra restart --- install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/install.sh b/install.sh index b03e0e0..32a0fcb 100755 --- a/install.sh +++ b/install.sh @@ -31,4 +31,3 @@ adb shell '/bin/rootshell -c "mv /tmp/misc-daemon /etc/init.d/misc-daemon"' adb shell '/bin/rootshell -c "chmod 755 /etc/init.d/rayhunter_daemon"' adb shell '/bin/rootshell -c "chmod 755 /etc/init.d/misc-daemon"' ./make.sh -adb shell '/bin/rootshell -c "/etc/init.d/rayhunter_daemon start"' From 67cb1bfb984678ddbe802d35d8dcaa8a7c3318cb Mon Sep 17 00:00:00 2001 From: Will Greenberg Date: Wed, 22 May 2024 10:41:17 -0700 Subject: [PATCH 05/10] CI: rename rust.yml to check-and-test.yml --- .github/workflows/{rust.yml => check-and-test.yml} | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) rename .github/workflows/{rust.yml => check-and-test.yml} (72%) diff --git a/.github/workflows/rust.yml b/.github/workflows/check-and-test.yml similarity index 72% rename from .github/workflows/rust.yml rename to .github/workflows/check-and-test.yml index 31000a2..052a588 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/check-and-test.yml @@ -1,4 +1,4 @@ -name: Rust +name: Check and Test on: push: @@ -10,13 +10,11 @@ env: CARGO_TERM_COLOR: always jobs: - build: - + check_and_test: runs-on: ubuntu-latest - steps: - uses: actions/checkout@v3 - - name: Build - run: cargo build --verbose + - name: Check + run: cargo check --verbose - name: Run tests run: cargo test --verbose From b5cd3d39117163eb5216e3659b6280aea4380892 Mon Sep 17 00:00:00 2001 From: Will Greenberg Date: Wed, 22 May 2024 10:41:26 -0700 Subject: [PATCH 06/10] CI: add release workflow --- .github/workflows/build-release.yml | 79 +++++++++++++++++++ .../config.toml.example | 0 dist/install-common.sh | 61 ++++++++++++++ dist/install-linux.sh | 6 ++ dist/install-mac.sh | 6 ++ dist/install-windows.bat | 1 + {scripts => dist/scripts}/misc-daemon | 0 {scripts => dist/scripts}/rayhunter_daemon | 0 8 files changed, 153 insertions(+) create mode 100644 .github/workflows/build-release.yml rename config.toml.example => dist/config.toml.example (100%) create mode 100644 dist/install-common.sh create mode 100644 dist/install-linux.sh create mode 100644 dist/install-mac.sh create mode 100644 dist/install-windows.bat rename {scripts => dist/scripts}/misc-daemon (100%) rename {scripts => dist/scripts}/rayhunter_daemon (100%) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml new file mode 100644 index 0000000..ed62ffa --- /dev/null +++ b/.github/workflows/build-release.yml @@ -0,0 +1,79 @@ +name: Build Release + +on: + push: + branches: [workflows] # FIXME: replace w/ main before merging + +env: + CARGO_TERM_COLOR: always + +jobs: + build_serial: + strategy: + matrix: + platform: + - os: ubuntu-latest + build_name: serial + - os: windows-latest + build_name: serial.exe + - os: macos-latest + build_name: serial + runs-on: ${{ matrix.platform.os }} + steps: + - uses: actions/checkout@v4 + - name: Build serial + run: cargo build --bin serial --release + - uses: actions/upload-artifact@v4 + with: + name: serial-${{ matrix.platform.os }} + path: ./target/release/${{ matrix.platform.build_name }} + if-no-files-found: error + build_rootshell_and_rayhunter: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + targets: armv7-unknown-linux-gnueabihf + - name: Install cross-compilation dependencies + uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: build-essential libc6-armhf-cross libc6-dev-armhf-cross gcc-arm-linux-gnueabihf + version: 1.0 + - name: Build rootshell (arm32) + run: cargo build --bin rootshell --target armv7-unknown-linux-gnueabihf --release + - uses: actions/upload-artifact@v4 + with: + name: rootshell + path: target/armv7-unknown-linux-gnueabihf/release/rootshell + if-no-files-found: error + - name: Build rayhunter-daemon (arm32) + run: cargo build --bin rayhunter-daemon --target armv7-unknown-linux-gnueabihf --release + - uses: actions/upload-artifact@v4 + with: + name: rayhunter-daemon + path: target/armv7-unknown-linux-gnueabihf/release/rayhunter-daemon + if-no-files-found: error + build_release_zip: + needs: + - build_serial + - build_rootshell_and_rayhunter + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/download-artifact@v4 + - name: Setup release directory + run: mv rayhunter-daemon/rayhunter-daemon rootshell/rootshell serial-* dist + - name: Archive release directory + uses: thedoctor0/zip-release@0.7.5 + with: + type: 'zip' + filename: 'release.zip' + directory: 'dist' + # TODO: have this create a release directly + - name: Upload release + uses: actions/upload-artifact@v4 + with: + name: release.zip + path: dist/release.zip + if-no-files-found: error diff --git a/config.toml.example b/dist/config.toml.example similarity index 100% rename from config.toml.example rename to dist/config.toml.example diff --git a/dist/install-common.sh b/dist/install-common.sh new file mode 100644 index 0000000..a02b30d --- /dev/null +++ b/dist/install-common.sh @@ -0,0 +1,61 @@ +#!/bin/env bash + +install() { + if [[ -z "${SERIAL_PATH}" ]]; then + echo "SERIAL_PATH not set, did you run this from install-linux.sh or install-mac.sh?" + exit 1 + fi + check_adb + force_debug_mode + setup_rootshell + setup_rayhunter +} + +check_adb() { + if ! command -v adb &> /dev/null + then + echo "adb not found, please ensure it's installed or check the README.md" + exit 1 + fi +} + +force_debug_mode() { + # Force a switch into the debug mode to enable ADB + $(SERIAL_PATH) AT + echo -n "adb enabled, waiting for reboot" + until adb shell true 2> /dev/null + do + echo -n . + sleep 1 + done + echo + echo "it's alive!" +} + +setup_rootshell() { + _adb_push rootshell /tmp/ + $(SERIAL_PATH) "AT+SYSCMD=mv /tmp/rootshell /bin/rootshell" + sleep 1 + $(SERIAL_PATH) "AT+SYSCMD=chown root /bin/rootshell" + sleep 1 + $(SERIAL_PATH) "AT+SYSCMD=chmod 4755 /bin/rootshell" + echo "we have root!" + adb shell /bin/rootshell -c id +} + +_adb_push() { + adb push "$(dirname "$0")/$1" "$2" +} + +setup_rayhunter() { + adb shell '/bin/rootshell -c "mkdir /data/rayhunter"' + _adb_push config.toml.example /data/rayhunter/config.toml + _adb_push rayhunter-daemon /data/rayhunter/ + _adb_push scripts/rayhunter_daemon /tmp/rayhunter_daemon + _adb_push scripts/misc-daemon /tmp/misc-daemon + adb shell '/bin/rootshell -c "mv /tmp/rayhunter_daemon /etc/init.d/rayhunter_daemon"' + adb shell '/bin/rootshell -c "mv /tmp/misc-daemon /etc/init.d/misc-daemon"' + adb shell '/bin/rootshell -c "chmod 755 /etc/init.d/rayhunter_daemon"' + adb shell '/bin/rootshell -c "chmod 755 /etc/init.d/misc-daemon"' + adb shell '/bin/rootshell -c "/etc/init.d/rayhunter_daemon start"' +} diff --git a/dist/install-linux.sh b/dist/install-linux.sh new file mode 100644 index 0000000..b188f9c --- /dev/null +++ b/dist/install-linux.sh @@ -0,0 +1,6 @@ +#!/bin/env bash + +set -e +export SERIAL_PATH="./serial-ubuntu-latest/serial" +. "$(dirname "$0")"/install-common.sh +install diff --git a/dist/install-mac.sh b/dist/install-mac.sh new file mode 100644 index 0000000..90c6064 --- /dev/null +++ b/dist/install-mac.sh @@ -0,0 +1,6 @@ +#!/bin/env bash + +set -e +export SERIAL_PATH="./serial-mac-latest/serial" +. "$(dirname "$0")"/install-common.sh +install diff --git a/dist/install-windows.bat b/dist/install-windows.bat new file mode 100644 index 0000000..05276bc --- /dev/null +++ b/dist/install-windows.bat @@ -0,0 +1 @@ +ECHO TODO diff --git a/scripts/misc-daemon b/dist/scripts/misc-daemon similarity index 100% rename from scripts/misc-daemon rename to dist/scripts/misc-daemon diff --git a/scripts/rayhunter_daemon b/dist/scripts/rayhunter_daemon similarity index 100% rename from scripts/rayhunter_daemon rename to dist/scripts/rayhunter_daemon From 166f94677215254b3e7d5d3e2b07269d8302e8b7 Mon Sep 17 00:00:00 2001 From: Will Greenberg Date: Wed, 22 May 2024 13:35:42 -0700 Subject: [PATCH 07/10] Update README for new build process --- README.md | 42 +++++++++--------------------------------- 1 file changed, 9 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index e7fcd25..92a7a55 100644 --- a/README.md +++ b/README.md @@ -32,41 +32,17 @@ Rayhunter is an IMSI Catcher Catcher for the Orbic mobile hotspot. Based on code Code is built and tested for the Orbic RC400L mobile hotspot, it may work on other orbics and other linux/qualcom devices but this is the only one we have tested on. Buy the orbic [using bezos bucks](https://www.amazon.com/gp/product/B09CLS6Z7X/) - - - ## Setup -### If your are on x86 linux -on your linux laptop install rust the usual way and then install cross compiling dependences. -run `sudo apt install build-essential libc6-armhf-cross libc6-dev-armhf-cross gcc-arm-linux-gnueabihf` - -set up cross compliing for rust: -``` -rustup target add x86_64-unknown-linux-gnu -rustup target add armv7-unknown-linux-gnueabihf -``` - -Now you can root your device and install rayhunter by running `./install.sh` - **Note:** You will have to install the cross compile tooling below before running this. - - -### If you aren't on linux or can't run the install scripts -Root your device on windows using the instructions here: https://xdaforums.com/t/resetting-verizon-orbic-speed-rc400l-firmware-flash-kajeet.4334899/#post-87855183 - -Build for arm using `cargo build` - -Run tests using `cargo test_pc` - -Push the scripts in `scripts/` to /etc/init.d on device and make a directory called /data/rayhunter using `adb shell` (and sshell for your root shell if you followed the steps above) - -you also need to copy `config.toml.example` to /data/rayhunter/config.toml - -Then run `./make.sh` this will build the binary and push it over adb. Restart your device or run `/etc/init.d/rayhunter_daemon start` on the device and you are good to go. -## Development -Write your code and write tests +1. Install the Android Debug Bridge (ADB) on your computer (don't worry about instructions for installing it on a phone/device yet). You can find instructions for doing so on your platform [here](https://www.xda-developers.com/install-adb-windows-macos-linux/#how-to-set-up-adb-on-your-computer). +2. Download the latest rayhunter release bundle and unzip it. +3. Run the install script inside the bundle corresponding to your platform (`install-linux.sh`, `install-mac.sh`, or `install-windows.bat`). +4. Once finished, rayhunter should be running! You can verify this by visiting the web UI as described below. -Build for arm using `cargo build` +## Usage -Run tests using `cargo test_pc` +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: -push to the device with `./make.sh` \ No newline at end of file +1. Over wifi: Connect your phone/laptop to the Orbic's wifi network and visit `http://192.168.1.1:8080` (click past your browser warning you about the connection not being secure, rayhunter doesn't have HTTPS yet!) + * Note that you'll need the Orbic's wifi password for this, which can be retrieved by pressing the "MENU" button on the device and opening the 2.4 GHz menu. +2. Over usb: Connect the Orbic device to your laptop via usb. Run `adb forward tcp:8080 tcp:8080`, then visit `http://localhost:8080`. From 8a514e4e7009c4a6f6f5351860203b853e02e40d Mon Sep 17 00:00:00 2001 From: Will Greenberg Date: Wed, 22 May 2024 14:02:52 -0700 Subject: [PATCH 08/10] CI: change target branch to main --- .github/workflows/build-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index ed62ffa..2bae78c 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -2,7 +2,7 @@ name: Build Release on: push: - branches: [workflows] # FIXME: replace w/ main before merging + branches: [main] env: CARGO_TERM_COLOR: always From 929b8fa5f3e78e50a2a0ccec6dfc131cbc8d936e Mon Sep 17 00:00:00 2001 From: Cooper Quintin Date: Thu, 6 Jun 2024 13:22:05 -0700 Subject: [PATCH 09/10] commit to naming --- make.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make.sh b/make.sh index 233fbbb..96f6fd7 100755 --- a/make.sh +++ b/make.sh @@ -1,4 +1,4 @@ #!/bin/sh cargo build --release --target="armv7-unknown-linux-gnueabihf" -adb push target/armv7-unknown-linux-gnueabihf/release/rayhunter-daemon /data/rayhunter/rayhunter +adb push target/armv7-unknown-linux-gnueabihf/release/rayhunter-daemon /data/rayhunter/rayhunter-daemon adb shell '/bin/rootshell -c "/etc/init.d/rayhunter_daemon restart"' From c21990074a671711091ef3289498e73fb208612b Mon Sep 17 00:00:00 2001 From: Cooper Quintin Date: Thu, 6 Jun 2024 13:57:18 -0700 Subject: [PATCH 10/10] nits --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index cf62bef..360a760 100644 --- a/README.md +++ b/README.md @@ -36,8 +36,8 @@ linux/qualcom devices but this is the only one we have tested on. Buy the orbic ## Setup 1. Install the Android Debug Bridge (ADB) on your computer (don't worry about instructions for installing it on a phone/device yet). You can find instructions for doing so on your platform [here](https://www.xda-developers.com/install-adb-windows-macos-linux/#how-to-set-up-adb-on-your-computer). -2. Download the latest rayhunter release bundle and unzip it. -3. Run the install script inside the bundle corresponding to your platform (`install-linux.sh`, `install-mac.sh`, or `install-windows.bat`). +2. Download the latest [rayhunter release bundle](https://github.com/EFForg/rayhunter/releases) and unzip it. +3. Run the install script inside the bundle corresponding to your platform (`install-linux.sh`, `install-mac.sh`). 4. Once finished, rayhunter should be running! You can verify this by visiting the web UI as described below. ## Usage @@ -87,6 +87,6 @@ Now you can root your device and install rayhunter by running `./install.sh` - * ## Documentation * Build docs locallly using `RUSTDOCFLAGS="--cfg docsrs" cargo doc --no-deps --all-features --open` -**LEGAL DISCLAIMER:** Use this program at your own risk. We beilieve running this program does not currently violate any laws or FCC regulations in the United States. However, we are not responsible for civil or criminal liability resulting from the use of this software. If you are located outside of the US please consult with an attorney in your country to help you assess the legal risks of running this program. +**LEGAL DISCLAIMER:** Use this program at your own risk. We beilieve running this program does not currently violate any laws or regulations in the United States. However, we are not responsible for civil or criminal liability resulting from the use of this software. If you are located outside of the US please consult with an attorney in your country to help you assess the legal risks of running this program. *Good Hunting!* \ No newline at end of file