RFCat is a Python-based RF (radio frequency) analysis and attack tool that leverages Texas Instruments CC1111 and CC2531 USB dongles for wireless testing. It enables frequency analysis, packet capture, signal injection, and protocol testing across various RF bands. Critical for IoT security research, wireless protocol analysis, and authorized penetration testing.
- Texas Instruments CC1111 USB Dongle - Primary RF transceiver
- CC2531 USB Stick - ZigBee protocol analysis (alternative)
- External antenna (optional) - Improved range and signal quality
# Install Python dependencies
sudo apt-get install python3 python3-pip python-dev
# Clone RFCat repository
git clone https://github.com/atlas0fd00m/rfcat.git
cd rfcat
# Install via setup
sudo python3 setup.py install
# Or install via pip
sudo pip3 install rfcat
# Verify installation
rfcat -h
# Connect CC1111 dongle via USB
# Flash firmware
cd rfcat/firmware/cc1111
sudo rfcat -i
# For CC2531
cd rfcat/firmware/cc2531
# Use programmer or bootloader
# Test connection
rfcat -c 'd.ping()'
| Command | Purpose |
|---|
rfcat -h | Display help information |
rfcat -c '<python_code>' | Execute single Python command |
rfcat -l | List available RF frequencies |
rfcat -r | Interactive Python shell |
rfcat -i | Flash firmware to device |
# Open interactive console
rfcat -r
# Python interactive session opens
rfcat> d = getRfCat()
rfcat> d.setFreq(2400000000) # 2.4 GHz (2400 MHz)
rfcat> d.setMdmModulation(MOD_FSK) # Set modulation
# Basic commands
rfcat> d.ping() # Test device connection
rfcat> d.getFWstr() # Get firmware version
rfcat> d.getFreq() # Current frequency
rfcat> exit() # Exit shell
# Load RFCat in Python
from rfcat import *
d = getRfCat()
# ISM bands (common frequencies)
d.setFreq(868000000) # 868 MHz (EU)
d.setFreq(915000000) # 915 MHz (US, AU)
d.setFreq(2400000000) # 2.4 GHz (WiFi, ZigBee)
d.setFreq(2450000000) # 2.45 GHz (Bluetooth)
# Get current frequency
current_freq = d.getFreq()
print(f"Current frequency: {current_freq} Hz")
# Scan frequency range
for freq in range(2400000000, 2500000000, 1000000):
d.setFreq(freq)
print(f"Monitoring: {freq/1000000} MHz")
| Modulation | Constant | Use Case |
|---|
| FSK | MOD_FSK | Frequency Shift Keying (common) |
| GFSK | MOD_GFSK | Gaussian FSK (Bluetooth, ZigBee) |
| ASK/OOK | MOD_ASK_OOK | Amplitude Shift Keying |
| MSK | MOD_MSK | Minimum Shift Keying |
| GMSK | MOD_GMSK | Gaussian MSK |
| PSK | MOD_PSK | Phase Shift Keying |
# Set modulation types
d.setMdmModulation(MOD_FSK) # FSK modulation
d.setMdmModulation(MOD_GFSK) # Gaussian FSK (Bluetooth)
d.setMdmModulation(MOD_ASK_OOK) # ASK/OOK
# Get current modulation
current_mod = d.getMdmModulation()
from rfcat import *
d = getRfCat()
d.setFreq(915000000) # Set to 915 MHz
d.setMdmModulation(MOD_FSK)
# Capture packets
print("[*] Listening for packets...")
while True:
try:
pkt, timestamp = d.recvPacket()
print(f"[+] Packet received: {pkt.hex()}")
print(f" Timestamp: {timestamp}")
print(f" RSSI: {pkt.rssi}")
except Exception as e:
print(f"[-] Error: {e}")
from rfcat import *
d = getRfCat()
d.setFreq(915000000)
d.setMdmModulation(MOD_FSK)
# Create and send packet
payload = b'\x41\x42\x43\x44' # "ABCD"
d.sendPacket(payload)
print("[+] Packet sent")
# Send multiple packets
for i in range(5):
d.sendPacket(bytes([i] * 10))
print(f"[+] Sent packet {i}")
from rfcat import *
import time
d = getRfCat()
frequencies = [915000000, 916000000, 917000000]
print("[*] Detecting frequency hopping...")
for freq in frequencies:
d.setFreq(freq)
print(f"[*] Monitoring {freq/1000000} MHz")
# Listen for 1 second
start_time = time.time()
packet_count = 0
while time.time() - start_time < 1:
try:
pkt, ts = d.recvPacket(timeout=100)
packet_count += 1
print(f"[+] Packet detected on {freq/1000000} MHz")
except:
pass
print(f"[+] Packets on {freq/1000000} MHz: {packet_count}")
from rfcat import *
d = getRfCat()
print("[*] Scanning RSSI across frequency range...")
freq_range = range(2400000000, 2500000000, 5000000)
for freq in freq_range:
d.setFreq(freq)
rssi_values = []
for _ in range(10):
try:
pkt, ts = d.recvPacket(timeout=50)
if pkt:
rssi_values.append(pkt.rssi)
except:
pass
avg_rssi = sum(rssi_values) / len(rssi_values) if rssi_values else 0
print(f"{freq/1000000:.1f} MHz: {avg_rssi:.1f} dBm")
from rfcat import *
d = getRfCat()
d.setFreq(2405000000) # ZigBee channel 11
d.setMdmModulation(MOD_GFSK)
print("[*] Capturing ZigBee packets...")
while True:
try:
pkt, ts = d.recvPacket()
# Parse ZigBee frame format
frame_type = pkt[0] & 0x03
security = (pkt[0] >> 3) & 0x01
ack_request = (pkt[0] >> 6) & 0x01
print(f"[+] Frame Type: {frame_type}, Security: {security}, ACK: {ack_request}")
print(f" Payload: {pkt.hex()}")
except Exception as e:
print(f"[-] Error: {e}")
from rfcat import *
d = getRfCat()
# Bluetooth advertising channels
bt_channels = [2402000000, 2426000000, 2480000000]
print("[*] Scanning Bluetooth advertising...")
for channel in bt_channels:
d.setFreq(channel)
d.setMdmModulation(MOD_GFSK)
print(f"[*] Channel: {channel/1000000} MHz")
for _ in range(5):
try:
pkt, ts = d.recvPacket(timeout=200)
print(f"[+] BT packet: {pkt.hex()}")
except:
pass
from rfcat import *
import time
d = getRfCat()
d.setFreq(915000000)
d.setMdmModulation(MOD_FSK)
print("[!] Starting RF transmission (authorized testing only)")
# Transmit continuous pattern
pattern = b'\xAA\xBB\xCC\xDD'
try:
for i in range(100):
d.sendPacket(pattern)
time.sleep(0.1)
print(f"[+] Transmission {i}")
except KeyboardInterrupt:
print("\n[+] Transmission stopped")
d.close()
from rfcat import *
import random
d = getRfCat()
d.setFreq(915000000)
print("[*] Starting packet fuzzing...")
for i in range(50):
# Generate random payload
payload_length = random.randint(5, 50)
payload = bytes([random.randint(0, 255) for _ in range(payload_length)])
try:
d.sendPacket(payload)
print(f"[+] Fuzz packet {i}: {len(payload)} bytes")
except Exception as e:
print(f"[-] Error: {e}")
d.close()
from rfcat import *
import time
d = getRfCat()
d.setFreq(915000000)
# Step 1: Capture packets
print("[*] Capturing packets...")
captured_packets = []
for _ in range(10):
try:
pkt, ts = d.recvPacket(timeout=500)
captured_packets.append(pkt)
print(f"[+] Captured: {pkt.hex()}")
except:
pass
# Step 2: Replay captured packets
print(f"\n[*] Replaying {len(captured_packets)} packets...")
for i, pkt in enumerate(captured_packets):
d.sendPacket(pkt)
print(f"[+] Replayed packet {i}")
time.sleep(0.5)
d.close()
from rfcat import *
d = getRfCat()
d.setFreq(915000000)
# Set transmission power
d.setTxPower(0) # Maximum power
# Get current settings
freq = d.getFreq()
power = d.getTxPower()
mod = d.getMdmModulation()
print(f"Frequency: {freq/1000000} MHz")
print(f"TX Power: {power}")
print(f"Modulation: {mod}")
from rfcat import *
import time
d = getRfCat()
d.setFreq(2400000000)
print("[*] Continuous monitoring started")
packet_count = 0
start_time = time.time()
try:
while True:
try:
pkt, ts = d.recvPacket(timeout=100)
packet_count += 1
elapsed = time.time() - start_time
rate = packet_count / elapsed
print(f"[+] Packets: {packet_count} ({rate:.1f} pkt/s)")
except:
pass
except KeyboardInterrupt:
print(f"\n[+] Monitoring stopped. Total packets: {packet_count}")
d.close()
| Band | Frequency | Use Case | Region |
|---|
| ISM 169 MHz | 169000000 Hz | Industrial, Scientific | Varies |
| ISM 433 MHz | 433000000 Hz | RF modules, IoT | EU, Asia |
| ISM 868 MHz | 868000000 Hz | LoRa, SigFox | EU |
| ISM 915 MHz | 915000000 Hz | Zigbee, LoRa | US, Canada, AU |
| 2.4 GHz WiFi | 2400-2500 MHz | WiFi, Bluetooth, ZigBee | Worldwide |
| Cellular | 700-2600 MHz | Mobile networks | Region-specific |
#!/usr/bin/env python3
from rfcat import *
def scan_frequency_range(start_freq, end_freq, step, duration=1):
d = getRfCat()
print(f"[*] Scanning {start_freq/1000000} to {end_freq/1000000} MHz")
for freq in range(start_freq, end_freq, step):
d.setFreq(freq)
packets = 0
start = time.time()
while time.time() - start < duration:
try:
pkt, ts = d.recvPacket(timeout=100)
packets += 1
except:
pass
if packets > 0:
print(f"[+] {freq/1000000:.2f} MHz: {packets} packets detected")
d.close()
# Scan 2.4 GHz band
scan_frequency_range(2400000000, 2500000000, 5000000)
#!/usr/bin/env python3
from rfcat import *
import time
def log_packets(frequency, duration, output_file):
d = getRfCat()
d.setFreq(frequency)
print(f"[*] Logging to {output_file} for {duration} seconds")
with open(output_file, 'w') as f:
f.write(f"Frequency: {frequency} Hz\n")
f.write(f"Start: {time.time()}\n")
f.write("Timestamp,Payload,RSSI\n")
start = time.time()
while time.time() - start < duration:
try:
pkt, ts = d.recvPacket(timeout=100)
f.write(f"{ts},{pkt.hex()},{pkt.rssi}\n")
print(f"[+] Packet logged: {pkt.hex()}")
except:
pass
d.close()
print(f"[+] Logging complete")
log_packets(2400000000, 30, "packets.csv")
| Issue | Solution |
|---|
| Device not detected | Check USB connection, verify lsusb shows device |
| Permission denied | Add user to dialout group: sudo usermod -a -G dialout $USER |
| Firmware mismatch | Reflash firmware: rfcat -i |
| No packets received | Verify frequency, check antenna connection |
| Import errors | Install dependencies: pip3 install rfcat pyusb |
- Authorized testing only - Ensure proper authorization before any RF testing
- Frequency regulations - Respect local frequency regulations and power limits
- Interference - Be aware of potential impact on existing wireless systems
- FCC regulations - Comply with FCC Part 15 for unlicensed bands
- Documentation - Maintain detailed logs of testing activities
- Professional standards - Follow responsible disclosure practices
- Official RFCat GitHub - Latest documentation and examples
- RF Safety Guidelines - FCC frequency regulations
- Texas Instruments Documentation - CC1111/CC2531 datasheets
- Wireless Security Research - Academic resources and case studies