rayhunter icon indicating copy to clipboard operation
rayhunter copied to clipboard

Push notifications when suspicious activity is detected

Open MatejKovacic opened this issue 9 months ago • 12 comments

When suspicious activity is detected there should be an option to send user push notification through Ntfy service.

Sending Ntfy messages can be done via HTTP PUT/POST or via the CLI (with curl).

MatejKovacic avatar Mar 07 '25 13:03 MatejKovacic

this needs the device to have internet access. Maybe this could be one option besides offering an API on the device to check for notifications. So people can create rayhunter companion apps :)

m0veax avatar Mar 10 '25 13:03 m0veax

So I did some tests and here is what you need to do (assuming that Rayhunter device has internet access):

  1. On your mobile phone install Ntfy app and then add "self-hosted ntfy server" (go to Settings - Server URL and enter https://ntfy.envs.net/. You can use official Ntfy server, but is not very reliable, envs is working fine. In the ntfy app then tap the "+" button and enter the topic name you want to subscribe to. You can made up anything for topic name, however it should be unique enough name that others are unlikely to guess. Why? Because topics are basically public (unless you use authentication)! In this example I am assuming your topic name is MyTopic. Also, I recommend to set that Ntfy has unlimited battery use and that android does not remove permissions if app is not used for some time.
  2. Then you can test sending the notifications from command line. Here are example commands. If you are using curl: curl -d "TEST message!" https://ntfy.envs.net/MyTopic. If you are using wget: wget --post-data="TEST message!" https://ntfy.envs.net/MyTopic -O - &> /dev/null

That is it. @m0veax reported that TP-LINK M7350 device has wget (and not curl), and wget supports HTTP only. So in that case you can use http://ntfy.envs.net/MyTopic, which is not very safe, but it works.

However, there is an option to create a Go binary (for Arm64 architecture), to send message through HTTPS.

Here is a quick and dirty example (send_ntfy.go) with topic name and server hardcoded:

package main

import (
	"bytes"
	"fmt"
	"net/http"
)

func sendNtfyMessage(topic, message string) error {
	// Construct the URL for the ntfy topic
	url := fmt.Sprintf("https://ntfy.envs.net/%s", topic)

	// Create the request body
	body := bytes.NewBufferString(message)

	// Send the HTTP POST request
	resp, err := http.Post(url, "text/plain", body)
	if err != nil {
		return fmt.Errorf("failed to send request: %v", err)
	}
	defer resp.Body.Close()

	// Check the response status
	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
	}

	fmt.Println("Message sent successfully!")
	return nil
}

func main() {
	// Define the topic and message
	topic := "MyTopic"
	message := "Test message from Rayhunter!"

	// Send the message
	err := sendNtfyMessage(topic, message)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
	}
}

Then you can cross compile:

set GOOS=linux
set GOARCH=arm64
go build -o send_ntfy_arm64 send_ntfy.go

Copy the binary (send_ntfy_arm64) to a Rayhunter device, make it executable (chmod +x) and run it (./send_ntfy_arm64).

What do you think?

MatejKovacic avatar Mar 12 '25 08:03 MatejKovacic

You can use this code: https://github.com/MatejKovacic/ntfy-go/

MatejKovacic avatar Mar 12 '25 09:03 MatejKovacic

I would support push notifications though I think it should be behind a config flag since it will require an active service plan to work as @m0veax mentions. I think we should build it directly into rust instead of relying on wget or curl. I would be happy to accept a PR for this feature.

cooperq avatar Mar 17 '25 23:03 cooperq

I just made a successful test on M7350, however I needed to disable certificate checking.

Image

So it is working!

Updated Go code is here (see at the end of page): https://github.com/MatejKovacic/ntfy-go/blob/main/README.md

Unfortunately, I don't know Rust, but this is a proof of concept, that this could be done.

MatejKovacic avatar Mar 19 '25 21:03 MatejKovacic

I would support push notifications though I think it should be behind a config flag since it will require an active service plan to work as @m0veax mentions. I think we should build it directly into rust instead of relying on wget or curl. I would be happy to accept a PR for this feature.

I'd agree. I don't love having something have to go out to the internet when it should really be local. If the threat model is that you're living your life or having a conversation and want to know if there's an IMSI catcher then you really can't just keep watching the LCD. But, you can't really expect the internet to be reliable enough for a bunch of services to work well enough that a push works. Polling an API on the rayhunter or maybe giving the rayhunter a rest callback to hit where it's all local seems to be more reliable.

Truthfully, it's too bad that the orbic device doesn't have a buzzer :)

hpux735 avatar Mar 31 '25 20:03 hpux735

yea I really wish it had a buzzer or a speaker or something!

cooperq avatar Apr 07 '25 22:04 cooperq

OK, I did this: https://github.com/MatejKovacic/ntfy-send

It is an app to send Ntfy push notifications from TP link devices. If there is no internet connection, sending does not fail, but message is stored into queue and sent later, when internet connection is available. I think this is important, because if IMSI catcher does MITM it will block internet connection, so notifications would not be sent.

P. S. This is written in Rust. I do not know Rust at all, but managed to do this with the help of Deepseek (I described what I want, when there were compile errors, I pasted errors to LLM, got new version... and so on, until app was working). So this is merely a proof of concept, someone who actually knows Rust, should check this. Anyhow, I tested the app well, and sending messages and clearing the queue works really nice.

MatejKovacic avatar Apr 11 '25 10:04 MatejKovacic

i think that if the notification does not go out in real-time, it doesn't have a lot of value. if it arrives "whenever" then I can also just look at the device sometime later.

rayhunter has a HTTP API -- i propose to write a tool that polls this API, and run this tool on a device that is in the modem's wifi. this would be useful if you carry the modem around with you, at least.

maybe browser notification API can be used from the webinterface as well.

untitaker avatar Apr 11 '25 10:04 untitaker

Yes. I agree with @untitaker.

Does the RayHunter advertise itself on the lan side in any way (mDNS?) such that an app would be able to discover it and start polling the HTTP API for updates? If so, I presume that it would be pretty straight-forward to write a iOS/Android mobile app that polls it and notifies the user.

hpux735 avatar Apr 11 '25 15:04 hpux735

Well, one interesting option would be to use small computer connected through WiFi or USB. One interesting option would be LicheeRV-Nano-W (with USB and wifi/BT) or even more basic version with USB only (LicheeRV-Nano-B) which costs around 17 EUR.

It is running modern Debian (someone ported it) with systemd. You can solder speaker and connect a small touch screen! Unfortunately a board has built-in microphone, which is a security risk, but you can unsolder it.

Image

This would give us options for sound alert, more heavy processing and storage of the data, even GPS... but yes, it would require some hardware development...

MatejKovacic avatar Apr 11 '25 20:04 MatejKovacic

Alternatively, NordicSemi has released a System-on-Package (nRF91 series) that has a built-in cellular modem and processor. There are development boards available with it. They're not FCC certified in that form, but it would be trivial for a device to be made with a speaker and light. The trick would be maintaining the rule set that identifies the IMSI catcher

hpux735 avatar Apr 11 '25 20:04 hpux735

Oooo. I'm going let this hang out in my brain a bit. I was also thinking about how to get Rayhunter to send me alerts without having to be looking at the Orbics screen.

alliraine avatar Jun 05 '25 18:06 alliraine

I meeean comissioning our own hardware for this would be a dream, we could get all the things we want and turn this into a whole sigint platform with detection of bluetooth and wifi fuckery as well, it would be cool to have lora on board too!

cooperq avatar Jun 06 '25 17:06 cooperq

oh my goddddd that would be the dreammm

alliraine avatar Jun 10 '25 13:06 alliraine

FWIW, I attempted a prototype of integrating notifications into the rayhunter code with a config option. While the code itself is pretty straightforward, getting a TLS library cross compiling so we can hit ntfy over https ended up more complicated than I was anticipating. From what I can tell, the setup instructions in @MatejKovacic's ntfy-send tool are approximately what we'd need to add to the setup instructions for rayhunter (at least for Linux and Mac, I'm less clear on Windows).

simonft avatar Jun 20 '25 16:06 simonft

I believe reqwest with rustls should cross compile easily. unsure whether the resulting binary is small enough though

untitaker avatar Jun 20 '25 16:06 untitaker

That's what I attempting to use. The error is ToolNotFound: failed to find tool "armv7l-linux-musleabihf-gcc": No such file or directory (os error 2). The error comes from trying to build ring, which reqwest configures rustls to use as a cryptography provider. It works after downloading, extracting, and adding armv7l-linux-musleabihf-cross.tgz from https://musl.cc/ to the path.

I can check the change in the binary size too. I'm happy to try to get the notification code into a PR-able state if you're OK adding a couple steps to the build setup process.

Edit: binary size goes from 4.6M to 5.5M

simonft avatar Jun 20 '25 16:06 simonft

i'm not sure but it's also not my call. i'd make a PR anyway and see if people like it. after all, see comment from cooper:

I would support push notifications though I think it should be behind a config flag since it will require an active service plan to work as @m0veax mentions. I think we should build it directly into rust instead of relying on wget or curl. I would be happy to accept a PR for this feature.

my concern that a solution that requires a working internet connection will not be very reliable, and I would not use it because the SIM card I use is not activated. personally i'd need something that pulls data directly onto my phone over the router's wifi, so i'm thinking, android app that keeps the phone awake.

but a solution that exists today is better than one that is "perfect" and is never built.

untitaker avatar Jun 20 '25 17:06 untitaker

Yes, but we can have a queue (so mesaages are sent when internet connection is restored, and sending notifications could be setting in configuration.

MatejKovacic avatar Jun 21 '25 08:06 MatejKovacic

I think we should have a subsystem that detects whether there is an internet connection or not and enables / disables certain features based on that (like push notifications, future auto updates, etc.)

cooperq avatar Jun 24 '25 17:06 cooperq

I found what feels like a simple solution to the build issue, which is to add a clang/llvm dependency. I pushed a draft PR that adds a config option for an ntfy channel and enables notifications if it's set. Right now it's just notifying for new detections but I was thinking a low battery notification would be useful as well.

I'll wait for directional feedback from @cooperq before adding documentation to the PR, but thoughts from others is also appreciated. And if someone has a mac or non-orbic devices and doesn't mind giving it a try that would be great.

simonft avatar Jun 26 '25 22:06 simonft

hey @simonft, thanks for working on that! while Ntfy is probably the closest i've seen to the kind of service we're looking for, i still have a couple concerns about it:

  1. their privacy policy (https://docs.ntfy.sh/privacy/) is delightfully short and readable, but it doesn't clarify how long message or topic data is retained, which is a real concern if our notifications contain any sensitive information
  2. since Ntfy topics are effectively passwords (if you guess someone's topic, that's all you need to read the notifications), i worry we're setting up a major footgun for users who aren't making very secure topic names
  3. Ntfy can be self-hosted, which is great, but i worry about hitching our horse to a paid service that i don't know that well

because of 1 & 2, i tend to think any Ntfy notifications we send should contain 0 sensitive info, which IMO means they should be as opaque as possible -- maybe even just a generic "Rayhunter has emitted a warning!" message. and because of 3, we should let the user configure the Ntfy service URL.

also, while it doesn't necessarily have to make it into the first implementation, it'd be good if the UI clearly indicated whether there's network connectivity so the user knows whether or not notifications will reliably make it through.

wgreenberg avatar Jul 18 '25 23:07 wgreenberg

taking a different tack, @untitaker mentioned the possibility of using Meshtastic for user notifications. i'm not super knowledgable about Meshtastic's inner workings, but from what i've skimmed it seems like this would require connecting the rayhunter device to a Meshtastic node (either over WiFi or possibly the USB/serial connection) and broadcasting notifications to a user's private channel. this would let notifications remain encrypted from the rayhunter device to the destination node, and then a user could read the decrypted notification in the myriad ways Meshtastic allows (app, browser, device screen, etc).

at a surface level, this feels like a better environment for notifications that may contain sensitive info, but if someone knows otherwise please correct me!

wgreenberg avatar Jul 18 '25 23:07 wgreenberg

at a surface level, this feels like a better environment for notifications that may contain sensitive info, but if someone knows otherwise please correct me!

yeah i played with it for a few days now, i think it's worth continuing pursuing but i don't think it will be reliable or all that user friendly. ntfy definitely seems easier to reason about, i'd be in favor of merging it because i really don't see a better solution or architecture cropping up in the near- to mid-term.

untitaker avatar Jul 20 '25 08:07 untitaker

after talking it over w/ the team some more, i think we're good to go on accepting this ntfy-based approach! @simonft are you still free to work on the PR you submitted?

wgreenberg avatar Jul 24 '25 18:07 wgreenberg

Yep, I think I can continue work on it this week. The notification text is currently "New warning triggered!" which is maybe too generic. I can change that to "Rayhunter has emitted a warning!", allow changing the ntfy server, and update the docs.

simonft avatar Jul 28 '25 16:07 simonft

Maybe user should have the option to set the text? Also, what about some variables, for instance to describe a warning. I. e to tell which indicator got activated?

MatejKovacic avatar Jul 28 '25 20:07 MatejKovacic

Maybe user should have the option to set the text? Also, what about some variables, for instance to describe a warning. I. e to tell which indicator got activated?

i think more descriptive text could be useful down the road, but for the first implementation i think i'd prefer sticking to an opaque notification and allow the user to use a more secure channel to pull down the actual analysis

wgreenberg avatar Jul 28 '25 20:07 wgreenberg

Generally I agree, but I prefer that user decides what should be the text. Of course, there should be a little warning, that this is not really secure channel, but I prefer user freedom (based on informed decision).

Just my to cents.

MatejKovacic avatar Jul 28 '25 20:07 MatejKovacic