So the situation was this - I have a camera watching my garden (someone nicely came unasked and tilled it, so what's a guy to do? Plant stuff!).
There is also a passive IR long range detector there that radios to my living quarters (a whole building away and a long walk to the garden). It false alarms a lot.
I have an electric fence charger that will put the fear of death into any being - but thick enough fur and it won't jump through, and deer, well, anyone who does a garden knows that unless you put a cage over the entire thing, they're just going to jump over anyway. It's a puny effort this year but this is for the fun of it anyway. So, now for the fun part - totally impractical, except that it seems to work and is entertaining on top.
For the pi that's most proximate to things, I added an interface to turn some AC power on and off, and that power runs two super bright LED floodlights - they hurt to even glance at in daytime. This power also runs a class D 50w/channel audio amplifier, connected to a pair of outdoor horn speakers mounted on the side of the building, and all this is pointed at the garden... perhaps you can guess where this is going.
So, I get a bing-bong from the alarm. I spin up the monitor camera website, but it's dark. That camera is outside, runing on wifi and on its own long power lead in a porch so as to get the "long view" of the garden. It's not reasonable to hook it up to the "scare the intestinal content out of varmints" hardware. So, while I could easily have come up with some more secure proprietary way of doing this...I found this more generally useful in cases where you don't care one whit about security and don't want to have to overly customize this for each different use. You could actually add a little whitelist so it's not open to everyone, but hey, I'm on non routable IPs out here in nowhere - if you're in range of my wifi, you're in easy range for a rifle...and all my neighbors are friends.
So, what did I do? If you know the secret UDP port on the secret IP address of your target running this code, you can just send it bash commands and it'll do them.
Like telnet, only no login required - this is REALLY BAD SECURITY so don't blame me if you hold it wrong.
I simply created a daemon in perl, with a .service file for the new kidz systemd bullcrap, and it sits there waiting for a message on a port known to it (and now, you know too - it's UDP 42666) - you can choose your poison from any high number port not already in use. This daemon will pass whatever you send it to bash via perl's system() command...
And sending that command is as easy as this:
$echo "whatever I want" > /dev/udp/hostname/port (or any other way of sending a UDP packet to a known place with known content)
That is, if you're running my tellem/tellme pair so hostnames and IPs are in the /etc/hosts file. If not, you have to use an IP (dotted quad) instead of hostname,
You're not going to hang if the thing isn't there....
This way, I don't have to flip web pages and push a button on one to get something to happen on the other machine....
There are probably thousands of other ways to get this done, but since I had that daemon and systemd thing hammered, it was a minor mod to existing stuff.
In this case, I'm remotely calling "macros" in Raspberry_Pi_Cam_Web_Interface from a remote machine, ones defined with the userbuttons file. More here:
https://elinux.org/RPi-Cam-Web-Interface
There's quite a bit going on in that code. If I knew how to make obfuscated javascript mixed into php send an onclick message to itself....oh well.
So here's an example of some "not too dangerous" code that only prints out what you sent it if you start it from a command line. Change the one print line and turn off $debug (set it to 0) and you have your backdoor:
You'll need modules "Modern::Perl" and POSIX to run this. You can substitute use warnings; and use strict; for Modern::Perl or just comment that out.
I think the rest is in the perl core anyway.
Code: Select all
#! /usr/bin/perl
use Modern::Perl; # kinda the same as use warnings and strict, and enable some new stuff
use IO::Socket; # so we can hear
use POSIX; # big honkin module, but we need some of it
#daemon
# *********** globals
my $time_to_die = 0; # shutdown cleanly
my $pid; # for daemonizing
my $debug = 1; # turns printing and daemonizing on and off
my $msgsock; # the socket
my ($rin,$rout,$rgood); # vectors for select func
my $portno = 42666; # commmand port
my $maxtoread = 1024; # arbitrary max length
my $them; # their IP from recv?
my $msg; # the incoming message
#****************************************
sub signal_handler
{ # so we die gracefully when told to
$time_to_die = 1;
}
#************** main
unless ($debug)
{ # daemonize self
setpgrp(0,0); # try to be as rooty as we can be
$pid = fork(); # we're going to detach from whoever started us
exit if $pid; # parent dies
die "Couldn't fork: $!" unless defined($pid);
POSIX::setsid() or die "Can't start new session: $!";
close (STDIN); # never use it anyway
close (STDOUT) unless $debug;
close (STDERR) unless $debug;
$SIG{INT} = $SIG{TERM} = $SIG{HUP} = \&signal_handler;
}
# get a port we'll listen on
$msgsock = IO::Socket::INET->new(LocalPort => $portno, Proto => "udp")
or die ("couldn't bind to port:$!");
$rin = '';
vec ($rin, fileno($msgsock),1) = 1;
print ("waiting for message\n") if $debug;
########################################## the main loop ##############3
until ($time_to_die)
{
$them = select($rout=$rin,undef,undef,10);
if ($them) # we have a message
{
$them = $msgsock->recv($msg,$maxtoread);
print ("\nmessage received:$msg\n") if $debug;
# put in some more interesting call like system($msg); here to get your backdoor
} # you could put an else here if there's other work to do
}
__END__
Code: Select all
[Unit]
Description=run bash command from udp port, horrible backdoor
After=network.target
[Install]
WantedBy=multi-user.target
[Service]
Type=forking
Restart=always
ExecStart=/usr/bin/UDPspawnd
IgnoreSIGPIPE=false
$sudo systemctl start UDPspawnd
At the target end, I've installed sox (along with the mp3 library for it) because I like that swiss army knife for audio. You can then do things like:
$play -q /any/path/I/want/*.mp3 gain -3
for just one example of a use.
Experienced linux users will know to put an & after the command to get the terminal back before the play is done.
I went here: https://www.freesoundeffects.com/free-s ... ror-10085/
To get some interesting sounds to put together in Audacity for repelling the critters.
I'm hoping to get a good enough frame rate under those lights to get some footage of "varmint running for its life". At any rate, it beats suiting up, going and out and shooting them.
This isn't really an exploit any more than onanism is rape...(did I say that out loud?
