Jump to content

Rasberry Pi as invisible monitoring device


Recommended Posts

Posted

Hey guys,

is it possible to put a Raspberry Pi (having two ethernet ports) in the middle of a network connection monitoring all the traffic but without having an IP address assigned to the Pi?

I want it to be there 100% invisible and passive, basicaly I only want to use the forward option in the ip tables and put a loop in between which sends all the packets via nfqueue through a python script which then is able to filter the packets at an optional level up to some kind of dpi.

I'm not sure if I can prohibit it getting an IP assigned because I don't want it to be accessible. I guess I need some nice configuration for the /etc/network/interfaces file, the routing can be done with iptables at startup, which should not be a problem. All the other stuff with python and nfqueue also isn't the problem for me.

Posted

The tap will drop a network to 100mbps, and you'd need a third network port on the pi to be able to reach it. The first two would be connected to the tap. You could also get a 5 port managed gigabit switch and set up port mirroring. That was you only need two network ports on the pi. One management port, not connected to the network, straight to your management computer, the other set to monitor mode(no ip) to the small switch.

Posted (edited)

Thanks to both of you! I was actually thinking about the Throwing Star, too but I still think I can realize that with my setup described above. What I read so far is that one can bridge both ethernet adapters with brctl (from the bridge-utils package) in a bridge called bridge0, which you then can route through the nfqueue script. I will test this during the next days and see if it works.

@barry: for just monitoring this is a nice solution, when I wrote passive I meant that I didn't want it to be discovered on the network, nevertheless it would be cool to activly filter and maybe alter the content of unencrypted traffic. For example I read about the pihole project, so I could easily introduce something similar for blocking ads or other stuff as well.

Edited by whitenoise
Posted

Isn't the Lan star a Read-Only device? meaning that it prohibits traffic leaving the tap device? If your going to roll your own, make sure its not able to transmit anything.

Posted

Isn't the Lan star a Read-Only device? meaning that it prohibits traffic leaving the tap device? If your going to roll your own, make sure its not able to transmit anything.

That's kind of the whole point of monitor mode. The tap just keeps you from accidentally starting up in normal mode.

Posted

what I ment to say was, I thought the lan star physically separated the read/write cables so that even if the raspi was exploited, it physically couldn't write out over the line. kinda like this article, but for traffic in both directions. http://www.linuxjournal.com/article/6985

.In monitor mode, if the pi was exploited if could have its mode changed and start writing back out onto the network. I've also heard (but many years ago, and is probably now the case any more) that sometimes arp packets would be leaked corresponding to the mac address of the adapter, even in monitor mode.

Posted

what I ment to say was, I thought the lan star physically separated the read/write cables so that even if the raspi was exploited, it physically couldn't write out over the line. kinda like this article, but for traffic in both directions. http://www.linuxjournal.com/article/6985 .In monitor mode, if the pi was exploited if could have its mode changed and start writing back out onto the network. I've also heard (but many years ago, and is probably now the case any more) that sometimes arp packets would be leaked corresponding to the mac address of the adapter, even in monitor mode.

That I didn't know! Technically the monitor computer should not be connected to the monitored network, so exploitation is pretty low. That's how I have it set up at a couple locations. Security onion computer is connected to a mirror port on a switch, it's controller computer(decommissioned laptop) is directly connected to a second network port on the computer.

Posted (edited)

Just a theoretical idea, but if your monitoring software is vulnerable, it can still be attacked, just from listening on a network. Back in December 2014, there were 4 vulnerabilities discovered for "tcpdump" which up until that time I thought was rock solid software. But these vulnerabilities allowed for the possibility of remote execution of code and it would be possible to have malformed packets travelling over the wire and blindly exploit the hidden monitor. Granted I agree the chance for this is probably low, but I think it's still a possibility. Libpcap is a pretty big piece of software!

Edited by fugu
Posted (edited)

Here comes an update!

I connected an USB-Ethernet adapter to my Raspberry resulting in having 2 ethernet ports.

Now comes some configuration magic:

def setupInterfaces(iface1, iface2):
    # I needed that one for the Raspberry, otherwise I got problems with nfqueue
    os.system("modprobe br_netfilter")

    # Setting up interfaces and creating a bridge
    os.system("ifconfig %s down" %(iface1))
    os.system("ifconfig %s down" %(iface2))
    os.system("brctl addbr br0")
    os.system("brctl addif br0 %s" %(iface1))
    os.system("brctl addif br0 %s" %(iface2))
    os.system("brctl setfd br0 0")
    os.system("brctl stp br0 off")

    # Put interfaces up in promiscious mode
    os.system("ifconfig %s 0.0.0.0 promisc up" %(iface1))
    os.system("ifconfig %s 0.0.0.0 promisc up" %(iface2))
    os.system("ifconfig br0 up promisc")

    # Reset iptables
    os.system("iptables -F")
    os.system("iptables -X")
    os.system("iptables -t nat -F")
    os.system("iptables -t nat -X")
    os.system("iptables -t mangle -F")
    os.system("iptables -t mangle -X")

    # Configure iptables
    os.system("iptables -P FORWARD ACCEPT")
    os.system("iptables -P OUTPUT DROP")
    os.system("iptables -P INPUT DROP")
    os.system("iptables -A FORWARD -i br0 -p tcp -j NFQUEUE")

    # Enable ip forwarding
    os.system('echo "1" | sudo tee /proc/sys/net/ipv4/ip_forward')
    return

This is the Python code for setting up the interfaces and enable forwarding.

From there it should be easy to pass the packets through a self programmed filter script based on nfqueue. With python and nfqueue you can filter and alter packets, dpi is also an option as long as the traffic is not encrypted.

I should mention that using this script on a Raspberry Pi might result in a slow connection.

I also read, that the network plug and the usb ports are using one single bus to the processor and as there is also a second ethernet device connected via usb this bus probably becomes the bottleneck. So it might be useful to switch to another system that has more RAM and CPU power, i.e. an Intel NUC.

I did a traceroute through the device and it was completly invisible. I guess the only way to detect it might be via time period analysis as the packets need a little bit longer if the device is in between.

Thanks for all the input, hope this helps ;)

Edited by whitenoise
Posted (edited)

Ill give a thumbs up... knowing how stuff works is why we are all here...

I have identical scripts running on my pi but with 2 alfa wireless n Cards...

True your throughput is crap due to the bus, but I have not really found these speeds to be a issue... I was seeing 6.5Mbps download speed test's from->

testmy.net/dl-5000

Maybe you can give this speed test a run? I would like to compare your results to mine... I'm sure you will find the limit to the shared bus...

Edited by i8igmac
Posted

Why are you doing this with python?

It's all system invocations. Put this stuff in a shell script and, if you _must_ use python, invoke this shell script from there.

Posted

@i8igmac: The problem actually seems to arise from the main()-function:

def main():
    q = nfqueue.queue()
    q.set_callback(callback)
    q.fast_open(0, AF_INET) # 0 is the index of queue
    q.set_queue_maxlen(3)
    q.set_mode(nfqueue.NFQNL_COPY_PACKET)
    try:
	q.try_run() # Main loop
    except KeyboardInterrupt:
        q.unbind(socket.AF_INET)
	q.close()
	sys.exit('...termination')

You see "q.set_queue_maxlen(3)" is pretty low, this decreases the speed but the CPU is barely hitting the 100% on the pi. I can visit websites like example.com which are loaded in a second but if I switch over to a website with lots of content and pictures i.e. bbc.com it takes a while, BUT it does not crash.

If I increase the value for set_queue_maxlen the scripts puts more packets into the queue and on websites like bbc.com there is a higher risk of crashing the script. Unfortunatlely there is no error message, it just flips out of the script back to command line and as the loop-through is broken then, the internet connection is, too.

I'm using a Raspberry Pi B by the way, so not the hottest model.

Maybe it is some driver issue, I don't know, but it seems to be something lowlevel. I read a bit about this problem and it seems to be that the packet accept delay is too high then. If you send a packet into the nfqueue it seems to be expected coming back in a certain amount of time, if this time is exceeded the script stops working. At least that is what I assume for the moment. I also read that one could analyze and the drop all packets by default but send a copy of each to a raw socket so there is no process that is waiting for the packets and you can choose by yourself how long you want to store the copied packet until you send it.

Do you have any information about that?

Alternatively one could code all the stuff in C which would run it faster but I'm not familiar with coding in C yet ;)

@cooper: Yep, basically you're right but I was too lazy and wanted to have everything in one script ;) the right way would be to seperate the stuff.

Posted

Here comes an update:

I tried several setups. I mentioned above that it might be the delay-time of the packet stuck in the queue that may cause the crash but thats not the case. I added a time.sleep(1) and time.sleep(10) into the callback function and it didn't produce an error so there is no issue with the delay time.

As I'm parsing packets with scapy I thought maybe there are 'evil' packets for scapys IP() function so I set up a callback function that does nothing but returns the packets back to the nfqueue via accept. That worked like a charme for a q.set_queue_maxlen(10) with a speed of several megabytes per second. As I increased the value to q.set_queue_maxlen(50000) it crashed again.

I used the link testmy.net/dl-5000 suggested by i8igmac above. The crash appeard at around 7%.

So what do I know from here?

It is not a scapy issue and it is not a packet delay issue.

It looks more like some kind of overflow and the queue seems to stumble or gets out of clock if it is flooded with too many packets.

I'm still working on that one, further input is appreciated ;)

Posted (edited)

Next update:

I found a solution for handeling the crashes. Although I still don't know why it crashes I put the q.try_run() in a while loop like:

    try:
	x=0
	while x==0:
		x=1
		q.try_run() # Main loop
		x=0

Which basically restarts the try_run() function after every crash. Fortunatly there is no configuration or blocking problem when restarting the try_run() function. So the crashes are still there but everytime they appear, the function is restarted and at the other end of the connection you don't notice these drops.

This might be a quick & dirty workaround but at least I get a stable connection.

Here some speed results (testmy.net/dl-5000):

normal connection: 26 mbps

intercepted connection: 3 mbps

I hope this helps ;)

Thank you all!

Edited by whitenoise
  • 2 weeks later...
Posted (edited)

Two weeks later ....

I was able to fix the crashes by using the asyncore module around the nfqueue. Internetspeed was significantly increased. I used that script on an old 2 GHz dualcore laptop with 1GB of RAM (but booted from an USB dongle) and got 26 MBits. Works like a charme!

Next aspect I'm working on is IPv6. As far as I know, iptables does only work for IPv4 packets but not for IPv6. There is ip6tables which works analog to iptables for IPv6 packets. I'll see if I can send IPv6 traffic into the same nfqueue and write a distinction of cases in the callback function.

Does anyone have some ideas about combining those versions via iptables and nfqueue?

Edited by whitenoise

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...