Wireless Implant C2 for Security Operations
Based on research done for the DEFCON 27 Wireless Village
Last updated
Based on research done for the DEFCON 27 Wireless Village
Last updated
Since the mass adoption of wireless networks in the early 2000s, wireless standards bodies such as the WiFi Alliance have become the linchpin for the proliferation of affordable, interoperable commercial & enterprise wireless devices. While the convenience and universality of such devices cannot be denied, transparency and security often become a forethought throughout their conception.
The result is standards and norms which cement themselves in IT operations all across the world, giving what many offensive researchers view as a an easy win in terms of establishing repeatable, predictable attack surfaces in enterprises and small businesses alike. As they researched and released untold numbers of exploits over the course of the last two decades, defenders have found their infrastructure to be blindsided time and time again. Misassociation, deauthentication, and key reinstallation are a just a few classes of wireless attacks which have become a thorn in the side of IT teams.
Rogue access points are a misconfigured or maliciously placed wireless access point, generally considered to be hidden or obscured under the intended hardware baseline. They often come in small, clandestine form factors such as the Hak5 Pineapple or a Raspberry Pi. These devices are generally considered the low-effort avenue for an adversary to gain initial access into a target network, as the challenge is primarily planting the device itself and retaining access. They are almost always attacker controlled, and if placed correctly are very difficult to locate.
Simple 'gotcha' misassociation attacks such as the infamous Evil-Twin or MANA can make quick work for compromising employee endpoints and collecting the information necessary to gain a foothold on an otherwise secure network. There are many defense-in-depth measures & configurations, enterprise-grade hardware and techniques that can be leveraged to prevent many of the common pitfalls.
Rogue access points can also be located by physically triangulating various wireless signals, as presented in my research with Todd at DEFCON 26. When the access points become mobile, such as in an attacker's backpack or on a drone, or in the less than non-conspicuous WiFi Cactus wielded by d4rkm4tter, the following challenges become apparent:
Identifying the wireless signature of the device. This could be a BSSID or a beacon/probe cadence with a specific pattern of targets. It also includes a specific frequency and channel(s).
Fast moving.
Structural and wireless interference requiring additional tuning.
Large area to cover - multiple choke points with many potential sources of signal noise / attenuation.
The scope of the research performed below encompasses a novel approach to both detection and offense of common attacks seen in the wild, as perpetrated by hard-to-find/catch rogue access points.
Given the logistic impossibility of hunting rogue access points at scale on foot, we required a framework of wireless data ingestion that fit the following parameters:
Worked over a large distributed area, with multiple nodes collecting data
Continuous data ingestion & monitoring
Command & control capability
Concealable & cheap
Easy to take on the move
This would allow for proactive, large-scale data ingestion, as well as offensive command and control channels for distributed red teaming activities. The points of data we were interested in included:
Baseline BSSID presence
Source/Destinations of wireless probes
Source of wireless beacons
Physical locations of all of the above, by triangulating signal strength
Since the project budget was rather small (and personal), we opted for the ESP8266. It offers the following advantages:
Full TCP/IP stack for $3-5
Includes the easy to use EspressIf SDK
802.11b (2.4 GHz) capable
2 GPIO for Serial programming
Very small
and the following disadvantages:
No debugging capabilities at the time of conception
1MB RAM
Power hungry, gets very hot
Limited range
This project was field tested at the DEFCON 26 wireless CTF, in an attempt to locate mobile rogue access points, dubbed "foxes". Thus, the project was dubbed "Fox Trap".
We iterated through a variety of prototypes, to program, deploy & conceal the implants.
The following were identified as key points in the selection process of a software stack:
Open source support
Robust Library Offerings
Quick to leverage
Due to the need to operate in a large, noisy and highly dynamic RF environments, a mesh network seemed to be the best choice at hand due to the topological extensibility they offer. This would allow the software to fallback into alternate communication modes of our choosing, should a signal be be lost for any reason or if a message/alert failed to send any number of times.
painlessMesh was chosen for its great documentation, comprehensive code base and good developer support. The mesh mode functions with the assumption of a single root node and a constantly changing wireless topology, consisting of "leaf" worker nodes in the network.
With the parameters set in motion for a mesh-based, WiFi C2 framework, the following 2 paradigms would be implemented:
Duties:
Command & control bots
Update target BSSID
Collect and forward bot data
Software Stack:
ArduinoJson
painlessMesh
Due to the lack of software interrupts being implemented in the EspressIf SDK at the time of development (perhaps this is due to a hardware limitation), running promiscuous mode for sniffing traffic, and inter-weaving seamlessly with communication mode for the mesh was not a possibility. Instead, I created a model in which the 2 modes would be logically separate, and synchronously communicate as necessary. This would ensure that when a signal alert was located by a bot, the whole network would be in constant synchronization to propagate the data back to the root node, and acknowledge the ingestion / re-synchronization across the mesh accordingly.
Sniff Mode:
BSSID sniffer
Probe sniffer
Beacon sniffer
Mesh Mode:
Communication responsibilities
Alert propagation
Signal Acknowledgments
Re-synchronization
The bot would function by first placing itself into mesh communication mode to talk to the mesh.
The onNodeTimeAdjusted
callback function is crucial to guaranteeing the time SNTP time synchronization within the mesh, and if the node drops or falls out of sync it will reconnect an re-sync as follows:
The CalculateSyncAndLaunchTasks()
function gives an introspection into how the entire bot scheme works, in the form of asynchronous task definitions, which are added to the built-in TaskScheduler library. The scheduler model made working with painlessMesh relatively easy, and fun.
The task model functioned as follows:
botInitialization : Places the bot into mesh communication mode to talk to the network. All bots must be in communication at the same time.
channelHop : Changes the wireless channels at specified time intervals while sniffing.
resync : Sets flag to resynchronize node to the mesh at a guaranteed period.
snifferInitialization : Places the node into 'sniffing' promiscuous mode and scans the air for a BSSID (MAC) contained in the targets list which is either probing or beaconing.
sendAlert : Drops out of sniffing mode when a target is found and continuously reports to the mesh for specified periods
And would be declared in the C++ as follows, as tasks with callback function pointers:
The duty cycles of these tasks were defined by hard-coded intervals in the code, which are part of the task definitions seen above:
For example, a bot by default will run in communication mode for 20 seconds to get any messages / SNTP synchronizations across the wire back to the root, and will sniff for targets for 9 seconds and hop 13 standard WiFi channels within 9,000ms (sniff interval)/400ms (channel hop interval), which would be ~23 channel cycles within each sniff cycle (no wonder why the chips ran so hot!).
If a bot discovers a target, discussed further in the alerting section, it would enter alert mode for another preset Task interval, followed by going back to re-synchronize with the mesh. Re-synchronization is performed ad-hoc every 900 seconds by default, as it was found over time SNTP wasn't always reliable and nodes could become orphaned with increasing distance, signal attenuation & interference.
Should SNTP be found to change, the current time is pulled from the mesh, and the closest interval threshold offset to synchronize with the network is calculated as follows:
Take the sum of the two main mode intervals. Assume they both add up to a prime and/or odd number. This is the total time it will take to re-start to mesh mode, or precision
Round up the current NTP time to the calculated precision to find the next point in time to sync with. This is the nextThreshold
Subtract the current NTP time from the nextThreshold
to determine how long the node must delay to re-enter the network
With the new delay in hand, the tasks are relaunched according to the new synchronization delay, and the bot is initialized/re-initialized into the network:
The mainstay operation of the bots is to locate source BSSIDs which are sending specific beacons or probes through the air, to locate anomalies and/or zero-in on a potentially adversarial access point in an environment. Sniffer mode is where the functionality is implemented. First, the bot is taken out of mesh mode, initialized into WiFi STA opmode with promiscuous enabled:
The promiscuous callback is defined on power-up, as
The promisc_cb
function strips the 802.11 frame down into each control field. If a discovered frame is a management frame and is a beacon (source BSSID) or a probe response (to the source BSSID), the beacon is parsed against a vector of running targets. If the targets vector contain the incoming frame, the bot enters into alert mode with the RSSI signal strength, channel, and BSSID all tracked.
Similarly, if a probe request is discovered probing for the target, the same alert registration logic follows:
The video below demonstrates two bots, being monitored over serial synchronizing over the mesh, using the SNTP synchronization scheme to ensure that both bots sniff & communicate at the same intervals:
The alert mode is fairly straightforward, as it disables all other tasks and prioritizes send the alert a set number of times over a set period of time. It will either give up or receive an acknowledgement from the root node in order to resynchronize to the mesh and continue sniffing. This is discussed in the next sections pertaining to C2 functionality and the alerting model.
The root node implementation is far simpler than the bots'. It indefinitely listens for traffic in mesh mode, and facilitates 3 main responsibilities:
Handle connections to the mesh
Intake commands and propagate them to the network
Send responses to alerts
Assuming the root node is connected via serial, I wrote a simple Python script which issues commands to the mesh. The currently supported commands are:
tar
: add a target BSSID
rem
: remove a target BSSID
First the python script takes the command, checks it for length, flushes the serial port and writes it out:
Then, the root ingests the command and broadcasts it out across the mesh.
The bot picks up commands as follows:
Now its time to put the whole network together. Since the Mesh is prone to error and interference, I designed a simple Ack
-> Syn-Ack
-> Fin-Ack
model for alerting the root, verifying the alert from the root, and finalizing the acknowledgement back to the root as a way to provide durability in alert mode. To make this possible,
The root defines:
ackTimes
: The amount of acknowledgements
ackSeconds
: The interval between acknowledgements
The bot defines:
alertSeconds
: The length of time between each alert
alertTimes
: The number of alerts
The mode of operation would proceed as follows:
The bot discovers a target, enters alert mode, and attempts to send a maximum of alertTimes
alerts for a maximum of alertSeconds
The root receives the alert, and attempts to send Acknowledgements for a maximum of ackTimes
for a maximum of ackSeconds
If the bot receives the the Acknowledgement and alert mode hasn't yet expired, it will send a single FinAck and re-enter the normal duty cycle.
If the root receives the FinAck signal and it's Acknowledgement mode hasn't yet expired, it will stop Acknowledgement mode.
In the following proof of concept video, the left terminal demonstrates the C2 monitoring script, the upper-right has the C2 command script issuing a new target over serial, and the lower-right is a bot in the mesh being monitored over serial. The guided demonstration of this video can be seen here at our DEFCON 27 presentation.
I thought it would be useful to receive notifications to our Signal group when we were out hunting the foxes at DEFCON, so I added the option of adding a Signal UserId / GroupId to the C2 monitoring script using the Python signal-cli:
This would be invoked as follows:
We thought it would also be useful, in the case that we didn't have other operators helping us to hunt, to shutdown the root node when a target was found and to immediately drop into airodump. This would be invoked as follows:
To enable a continuous hunt, I simply excluded the exit() call in the python script.
During the DEFCON 26 CTF, after a prolonged period of unsuccessfully locating the fox, we began to employ more subversive tactics. We loaded our chips with a beacon spamming module, and were able to visually confirm other teams getting drawn away from the authentic targets.
We also discovered the following thread on Twitter, adding credence to the fact that ESPs are a cheap way to subvert legitimate wireless communications in the wild:
There are a myriad of use cases for a red team. While we limited ourselves to 802.11 due to budget and time constraints, the sky is the limit when it comes to the fundamental idea of tying wireless attacks together in a distributed C2 network. The WHID Elite is an awesome open source Arduino project which could be modified in such a manner, for example managing HID attacks remotely on multiple compromised endpoints. Also, creating a distributed de-authentication attack pattern would be very easy with this paradigm, as would KARMA and evil twin attacks, given the proper hardware.
While the ESP8266 is a fantastic chip to get going fast and easy on 802.11 stacks, 802.11 presented its own myriad of challenges such as crowded airwaves and unexpected signal loss. Power consumption was a major issue which could be addressed with both better hardware and more efficient software. We considered clustering the bots together with 2 chips for both bot modes to run simultaneously, and to communicate changes in topology and alert states over serial.
Using an SDR over a custom frequency, or a LoRa hardware would most likely provide a more stable communications channel and would allow for signal interrupts, nullifying the need to implement the bi-modal model in bots. BLE could also make for an interesting option.
After our DEFCON 26 presentation on hunting rogue access points, we shared the mesh C2 idea around the wireless village, and showed a couple of teams our prototypes. To a bit of surprise, the Dark Wolf Solutions team had taken our idea and run with it. Right after this presentation was given at DEFCON 27, the DarkWolf team 3d printed a box that contained a LoRa chip, multiple SMA antenna mounts, and even a GUI that they controlled their mesh from on their laptops. I wasn't given the opportunity to look at their source code beyond a peak, however it goes to show that a little extra budget and man power can truly go a long way. I wish sincerely the team will one day open source the project and give back to the community. They bought me a beer and let me take a picture, luckily, and here's what it looked like:
We also considered feeding the incoming JSON to the root node into a more human-digestible framework for presentation and tracking. One notable example of demonstrating how wireless data ingestion from a single ESP8266 SOC could be used was this pHAT Sniffer project. In the future, using a platform agnostic framework such as ELK to ingest the data would also be a good strategy for a Blue Team looking to gain insight and visibility into their wireless environment, or a Red Team looking to make a nice report for an assessment.
While this research is nothing more than an expedient anecdote in solving systemic problems with wireless communications used in the world today, the idea of distributing wireless operations in a command and control model is a valuable prospect. Given the proper hardware and programming could easily prove to be useful to attackers and defenders alike in the future, as the wireless landscape evolves into new standards and classes of attack.
The DEFCON 27 presentation can be found at the YouTube link below:
The original source code is open and free, and can be found here:
Credit goes to:
Joe Minicucci - Software implementation and architecture
Todd Cronin - Hardware and conceptual design