Tampilkan postingan dengan label clicker. Tampilkan semua postingan
Tampilkan postingan dengan label clicker. Tampilkan semua postingan
Senin, 24 Januari 2011
Generic CC1110 Sniffing, Shellcode, and iClickers
Howdy y'all,
I haven't the time to write individual posts on these subjects, but I do have plenty of new features for the CC1110 that are worth sharing. Rather than explain how they were written in too much detail, I invite you to read the source code, which is mostly Python and C shellcode.
In order to follow along with these examples, you will need to have SmartRF Studio installed to /opt/smatrf7. While this requirement will go away in a few weeks, the GoodFET client temporarily needs SmartRF Studio for machine documentation about the CC1110. You can find more details on SmartRF requirements in the goodfet.cc client page.
(1) Packet sniffing, and other neighborly scripts.
GoodFETCC now has packet sniffing support for the SimpliciTI protocol used by the Chronos watch. Not only that, but it implements the protocol well enough to act as an access point for the watch, collecting accelerometer data and deciphering it for the host.
Run an access point with 'goodfet.cc simpliciti [band]'. (This command will likely change names soon, as it is a rather ugly hack which only supports the Chronos accelerometer feature.) The optional parameter should be us, eu, or lf for the American, European, and Low Frequency versions of the watch.
Not only protocols intended for the GoodFET, but also others which are coincidentally compatible, are supported. Thanks to some register settings contributed by Mike Ossman, you can sniff and decipher i<clicker traffic with 'goodfet.cc iclicker'.
The i<clicker uses a Xemics XE1203F (PDF) radio chip, shown below. The XE1203F is nearly as configurable as the CC11xx parts, except that it is limited to 2FSK encoding. Previously, this protocol could be sniffed with the GR-Clicker project and a USRP, but the highly-versatile CC1110 chip allows this to be done with neither a software defined radio nor a chip identical to that used by the transmitter.
If you find it handy to see when a device is broadcasting, you can produce an ASCII-art plot of signal strength with 'goodfet.cc rssi [freq]':
Care to jam another transmitter? Just like with the Next Hope Badge's GoodFET mode, it takes a single command to hold a carrier wave.
'goodfet.cc carrier [freq]'
(2) Shellcode, now for quiche-eaters!
At the risk of appearing to facilitate quiche-eating, I'd like to quickly explain the new shellcode interface for placing code fragments on a Chipcon 8051 target, such as the CC1110.
The Chipcon radios have certain functions which are timing sensitive, chief among these being the rewriting of flash memory and the use of the digital radio core. If flash memory is not pulsed with the correct timing, mis-writes will occur. If the radio is read too slowly, bytes will be missed and a buffer underflow will ruin the transaction. Similarly, a transmission might fail if the single-byte transmission buffer isn't refilled quickly enough. I've also had trouble, for reasons that I can poorly explain, configuring the crystal oscillator through the debugging interface without shellcode.
As I described in my CC2430 Debugging Notes, the recommended method of flashing memory is to write a small block of code into XDATA RAM which does the actual write, then to branch to this code, waiting for a HALT (0xA5) opcode to return control to the debugger. This routine is provided in SWRA124 as machine code with assembly comments, beginning with the fragment shown below.
While this is fine and dandy for code that works, it's a bit infuriating to debug code in machine language. (Is that opcode supposed to be 0xA5 or 0xA6? Is the length of this instruction correct? Similar frustration abounds.) To correct for this, the GoodFET project now has a trunk/shellcode directory in addition to trunk/firmware and trunk/client. Shellcode is compiled for target microcontrollers, in this case just the CC1110 by SDCC, the Small Device C Compiler.
For example, this is the code that used to configure the crystal oscillator on the CC1110, a prerequisite for any radio operations:
That ugly mess becomes the following little fragment of C. It is compiled by 'sdcc --code-loc 0xF000 crystal.c' in order to place the code squarely within RAM, which is executable in this 8051 clone's unified memory architecture. (It's a Harvard chip that acts Von Neumann, or the other way around.)
For inputs to these functions, and also for their return values, I find it more convenient to declare arrays at known locations than to read the symbol files to find them. The syntax for placing an array in XDATA memory at 0xFE00 is 'char __xdata at 0xfe00 packet[256];'. You can find examples of this in txpacket.c and rxpacket.c in the GoodFET repository.
(3) Care to join the fun?
There are a number of features remaining to be implemented in shellcode. Among them in a completed port of Ossmann's $15 Spectrum Analyzer, which I began in CC1110 Instrumentation in Python and you can find in the contrib/ directory of the GoodFET repository. By dropping the GUI interface and replacing it with timing delays, full spectrum scans can be made in decent time without requiring that anything in flash memory be changed.
Another handy tool would be an OOK sniffer that over-samples, using the infinite-packet-length trick described in the CC1110 datasheet to fill ram with a recording. Triggering on RSSI allows the beginning of the packet to be reliably timed, with oversampling allowing for correction on all later bits. I've begun to implement this as 'goodfet.cc sniffook [freq]', but an enterprising neighbor should be able to start sniffing garage door remotes in short order.
A Morse-code library in combination with an external amplifier would also be neighborly for the licensed amateur bands. The ability of the microcontroller to quickly return and channel hop might be able to account for, among other things, the Doppler shift experienced in EME moon-bounce experiments, without losing backward compatibility with 19th century radio technology.
As a prize, I offer one ale apiece for GoodFET patches implementing these features.
Stay neighborly,
--Travis Goodspeed
<travis at radiantmachines.com>
Minggu, 04 Juli 2010
Reversing an RF Clicker
by Travis Goodspeed <travis at radiantmachines.com>
concerning the Turning Point ResponseCard RF,
having FCC ID R4WRCRF01,
patented as USA 7,330,716.
In this article, I describe in detail the methods by which I have reverse engineered the TurningPoint ResponseCard RF, casually known among students as a "Clicker". This 2.4GHz radio transceiver is used in undergraduate university classrooms for automated roll-call and in-class quizzing or voting. By dumping and analyzing its firmware, one can determine the radio protocol necessary to intercept and forge packets, as well as to build a custom base station. The radio hardware that I have used is a reprogrammed Next HOPE Badge running the GoodFET firmware.
A follow-up article will likely describe the writing of replacement firmware, but that can be easily enough discovered by an enterprising reader. My purpose instead is to provide the information necessary to build compatible products, as well as to teach the technique of reverse engineering these products to find such information when none is available.
The Clicker's keypad is attached only with adhesive, and it can be pulled off after lifting an edge with a knife blade. Beneath the keypad, there are four screws holding the board in place, plus a fifth from the rear of the device. If you are lucky, these will be small Phillips screws, but the unlucky will find tri-wing "Nintendo" screws. I was lucky to have one of each type, but those with neither a Phillips-screwed Clicker nor a tri-wing screwdriver can buy one or try one of these tricks.
In either case, it isn't strictly necessary to open your clicker, as test-points for dumping and replacing its firmware are accessible from the battery compartment. Further, the radio communications are accessible with no hardware access whatsoever.
The Clicker is built upon a Nordic nRF24E1 chip, which combines an 8051 microcontroller with an nRF2401 radio transceiver. Although the two cores have been combined into a single package, the 8051 core speaks to the radio through a few bit-field registers and an internal SPI bus, which is shared with the external SPI bus.
As the nRF24E1 lacks internal non-volatile storage, a CAT25C32 (pdf) SPI EEPROM is used for program and configuration storage. Within the microcontroller, there is a masked ROM bootloader from 8000h to 81FFh that loads executable code from the EEPROM into executable RAM from 0000h to 0FFFh.
At the base of the circuit board's primary side, there are test points for the SPI EEPROM. As the default firmware only uses the SPI bus when buttons are pressed, this EEPROM may be dumped at any point after the device has booted. The test points are as follows, which should be matched to those of equivalent names in the GoodFET SPI Table. They were determined by use of a continuity tester.
In order to dump the firmware, I quickly wrote a GoodFET client for the 25C32 using its datasheet. A read is performed by sending {0x02, AL, AH, 0} as a SPI transaction, with the result coming back as the fourth byte. Doing it this way with the GoodFET's SPI driver is slower than having C code within the GoodFET dump the whole ROM, but it's fast enough for a dump and takes very little code.
From this point, I dumped the firmware with 'goodfet.spi25c dump image.hex', converted the Intel Hex file to binary, and popped it open in Emacs/hexl. The result looks something like the following, whose format is described in the nRF24E1 datasheet. The opening passage is {u8 config, u8 entry offset, u8 blockcount}. Here {0x0B, 0x07, 0x0B} means that executable code begins at byte 0x07, and that the total image length is 0x0B*256==2,816 bytes. (Additional space within the SPI ROM is unused and left as 0xFF.)
To produce an image suitable for a disassembler, I cut the bytes before 0x07 to make an image beginning with {0x02, 0x0A, 0xB7, ...}. The extra bytes in this region are the serial number and default frequency, but we'll get back to that later.
As the firmware is only three kilobytes, it doesn't take terribly long to reverse engineer. First, the Special Function Registers (SFR) which are defined on pages 79 and 81 of the nRF24E1 datasheet are fed to the disassembler.
(I'm using IDA Pro here, but any 8051 disassembler with a decent text editor could suffice. All of the following function labels are from my imagination, while Special Function Registers (SFRs) come from the nRF24E1 datasheet.)
For example, "MOV 0xA0, #0x80" is rather opaque, but "MOV RADIO, #0x80" makes it clear that the immediate value 0x80 is being placed into the RADIO register. Page 89 of the datasheet will then explain that the high bit of the radio register is power control, so this instruction is powering up the radio for use. Similarly, "SETB RADIO.3" is setting the fourth bit of the RADIO register, which the datasheet describes as raising the CS signal.
Once the SFR addresses are known, it becomes useful to search for them in order to identify the I/O routines. In the nRF24E1, the radio is accessed across a SPI bus, so a good first step is to identify the SPI routine. The function containing this code will always include a MOV involving the SPI_DATA register.
Having this, a list of cross-references quickly shows that while few functions call the SPIRXTX function, each calls it many times. This is because the author has chosen to repeatedly call that function with immediate values, rather than to dump an array of bytes with a for(){} loop.
While the disassembler can automatically identify the function entry points in the table above, it is not capable of giving them English names or descriptions. To understand how this is done, it is necessary to read the datasheets of the SPI devices.
The SPI EEPROM chip, a CAT25C32, is used by dropping the !CS line then writing an opcode byte followed by its parameters or results. Opcodes include WREN/WRDI for write protection, RDSR/WRSR for accessing a status register, and READ/WRITE for reading and writing bytes. A WRITE may only be performed when the external !WP pin is low and the software write protect has been disabled by opcode. A transaction begins when !CS drops low and ends when it drops high.
To identify the function which reads a byte from the 25C32, a few things can be safely assumed: (1) The function will begin by dropping some I/O pin (!CS). (2) The function will then broadcast the READ opcode, 0x03. (3) It will then broadcast a sixteen bit parameter; that is, DPL followed by DPH. (4) Finally, it will return the result of a fourth SPIRXTX call. In pseudocode, that would be something like
Sure enough, one of the few functions calling SPIRXTX does exactly this. The constant pushing and popping of the parameters is a quirk of the compiler, which might possibly allow it to be identified. From the code below, it is clear that P0.0 is the !CS line of the CAT25C32.
The SPIROMPOKE function looks similar, except that two transactions are performed. First the WREN (0x06) opcode is sent to enable writing, then WRITE (0x02) is used to perform the actual write.
The other SPI operations concern the nRF2401 radio core, which behaves differently from the EEPROM. Rather than transactions being an opcode followed by parameters, there is only a single SPI register that must be completely written during a transaction. A second register, selected by the CE line, contains the packets.
The configuration is set by one big register, sent MSBit first. If fewer than the needed bytes are sent, the value is right-aligned into the lower bytes of the register. That is, the last byte sent is always (CHAN<<1)|RXMODE and the second to last always describes the radio configuration.
Searching around a bit yields the RADIOWRCONFIG function, the tail of which is below. It can be seen from the code that the 0x1A IRAM byte holds the channel number. That is, if 0x20 is stored at 0x1A, the radio will be configured to 2,432 MHz. The other configuration bytes reveal that the MAC addresses are 24 bits, the checksum is 16 bits, and the device broadcasts at maximum power sourced from a 16MHz crystal. (That the configured crystal is identical to the one on the board is very important. Some enterprising coders will lie to a chip about its crystal in order to access an unsupported radio frequency.)
At this point, it still remains to sniff traffic is to find the target address to which packets are broadcast as well as the frequency. We'll start with the address, because that's a bit easier.
The TXPACKET function involves a lot of PUSH and POP instructions, but it otherwise looks very similar to the RADIOWRCONFIG function, in that a series of bytes are written in order with repeated function calls to SPIRXTX. In pseudocode, this function becomes the following. From the radio documentation and configuration, it is clear that the first three bytes will be the target MAC address. From the RADIOWRCONFIG() function, it is equally clear that the three bytes at 0x1B are the receiving MAC address of the unit. (The parameter of the function happens to be the button press, as can be determined by tracking the keyboard I/O routines or viewing a few packets.)
The radio itself will append a 16-bit CRC; therefore, the full packet then becomes {u24 tmac, u24 smac, u8 button}.
To determine the value of the target MAC address, just grep the disassembly for "mov" and one of 0x1E, 0x1F, 0x20. The relevant instructions are as follows, setting the target MAC address to 0x123456. (In 8051 notation, the first instruction moves the immediate constant #0x12 into byte 0x1E of IRAM.)
As this point, it would be possible to scan each channel for a few seconds, listening for packets sent to that address, but it's classier to find the value by static analysis. Acting on the hunch that the configuration is held in EEPROM and looking for references to the SPIROMPEEK() function, the READIDFREQ() function can be found. As can be seen in the fragment below, EEPROM[6] holds the channel number while the MAC address is at EEPROM[3,4,5].
As the EEPROM begins with "0b 07 0b 15 79 1b 29", it's clear that the MAC address of the unit from which it came is 0x15791B and that it is broadcasting on 2400+0x29=2441MHz. This can be double-checked by the serial number "15791B" being printed on the label.
Knowing the modulation scheme, target address, and packet contents, it becomes possible to sniff traffic from a Clicker. This is performed by use of the GoodFET firmware on a Next Hope badge, my prior tutorial for which describes the process of packet sniffing.
The NHBadge board contains an nRF24L01+ radio, which differs dramatically from the nRF2401 in terms of how it is configured. Still, the radios are sufficiently compatible. The following hack of the goodfet.nrf client allows packets to be sniffed from the air with proper checksumming.
Sure enough, here are some packets of the 5 button being pressed on unit 1F8760. The keypress is the final byte in ASCII.
Now that it is clear how to receive and recognize button presses, it becomes necessary to reverse engineer the response codes which might be sent from the access point. Without hearing a reply of at least an ACK, the Clicker will continue to broadcast each message more than three hundred times. This takes more than ten seconds, during which all other key presses are ignored.
The broadcast loop within the MAIN() function would look a little like this in C.
This region is easy enough to find, but there's another command mode. An easier target is the channel hopping routine, which constantly broadcasts 0x3F while incrementing the channel, sticking with the last one on which a reply of 0x18 was received. Channels 1 through 83 are attempted; that is, 2,401 MHz to 2,483MHz at 1MHz steps.
Checking this code within the MAIN() function reveals that its effect is to blink the green LED (P1.1) six times, exiting the broadcast loop. Other commands include 0x04 (LED Off), 0x06 (LED Green), 0x15 (LED Red), 0x11 (Blink Green), 0x14 (Blink Red), and 0x18 (Blink Green, Channel Lock). All undefined opcodes set the red LED.
By sniffing traffic within a classroom, it is possible to watch votes as they are being cast by students. Similarly, packets could be broadcast by a reprogrammed Clicker or NHBadge to make a student in virtual attendance, automatically voting with the majority so as to gain perfect attendance and a solid C quiz average. Where instant feedback is available, this might even allow for a solid A quiz average. Without taking advantage of the masked-ROM option of the nRF24E1, the code cannot be even slightly protected from extraction and reverse engineering.
Less adventurous users can jam the network by running 'goodfet.nrf carrier 2441000000' to hold a carrier wave on the channel. The only attempt at a frequency change is made when pressing the GO button, at which point the new channel can be discovered and similarly jammed.
Since performing this work, it has come to my attention that a USRP plugin for doing this to the competing 900MHz iClicker product is available as http://gr-clicker.sourceforge.net/. Additionally, the infrared Clicker units were broken with a little tool called Survey Says. I have ordered more sophisticated Clicker models from CPS and Turning Point, and proper descriptions of them will soon follow.
concerning the Turning Point ResponseCard RF,
having FCC ID R4WRCRF01,
patented as USA 7,330,716.
In this article, I describe in detail the methods by which I have reverse engineered the TurningPoint ResponseCard RF, casually known among students as a "Clicker". This 2.4GHz radio transceiver is used in undergraduate university classrooms for automated roll-call and in-class quizzing or voting. By dumping and analyzing its firmware, one can determine the radio protocol necessary to intercept and forge packets, as well as to build a custom base station. The radio hardware that I have used is a reprogrammed Next HOPE Badge running the GoodFET firmware.
A follow-up article will likely describe the writing of replacement firmware, but that can be easily enough discovered by an enterprising reader. My purpose instead is to provide the information necessary to build compatible products, as well as to teach the technique of reverse engineering these products to find such information when none is available.
Disassembly
The Clicker's keypad is attached only with adhesive, and it can be pulled off after lifting an edge with a knife blade. Beneath the keypad, there are four screws holding the board in place, plus a fifth from the rear of the device. If you are lucky, these will be small Phillips screws, but the unlucky will find tri-wing "Nintendo" screws. I was lucky to have one of each type, but those with neither a Phillips-screwed Clicker nor a tri-wing screwdriver can buy one or try one of these tricks.
In either case, it isn't strictly necessary to open your clicker, as test-points for dumping and replacing its firmware are accessible from the battery compartment. Further, the radio communications are accessible with no hardware access whatsoever.
Hardware
The Clicker is built upon a Nordic nRF24E1 chip, which combines an 8051 microcontroller with an nRF2401 radio transceiver. Although the two cores have been combined into a single package, the 8051 core speaks to the radio through a few bit-field registers and an internal SPI bus, which is shared with the external SPI bus.
As the nRF24E1 lacks internal non-volatile storage, a CAT25C32 (pdf) SPI EEPROM is used for program and configuration storage. Within the microcontroller, there is a masked ROM bootloader from 8000h to 81FFh that loads executable code from the EEPROM into executable RAM from 0000h to 0FFFh.
Dumping Firmware
At the base of the circuit board's primary side, there are test points for the SPI EEPROM. As the default firmware only uses the SPI bus when buttons are pressed, this EEPROM may be dumped at any point after the device has booted. The test points are as follows, which should be matched to those of equivalent names in the GoodFET SPI Table. They were determined by use of a continuity tester.
T4 | MISO |
T5 | SCK |
T6 | MOSI |
T3 | !CS |
T1 | VCC |
GND | GND |
In order to dump the firmware, I quickly wrote a GoodFET client for the 25C32 using its datasheet. A read is performed by sending {0x02, AL, AH, 0} as a SPI transaction, with the result coming back as the fourth byte. Doing it this way with the GoodFET's SPI driver is slower than having C code within the GoodFET dump the whole ROM, but it's fast enough for a dump and takes very little code.
From this point, I dumped the firmware with 'goodfet.spi25c dump image.hex', converted the Intel Hex file to binary, and popped it open in Emacs/hexl. The result looks something like the following, whose format is described in the nRF24E1 datasheet. The opening passage is {u8 config, u8 entry offset, u8 blockcount}. Here {0x0B, 0x07, 0x0B} means that executable code begins at byte 0x07, and that the total image length is 0x0B*256==2,816 bytes. (Additional space within the SPI ROM is unused and left as 0xFF.)
To produce an image suitable for a disassembler, I cut the bytes before 0x07 to make an image beginning with {0x02, 0x0A, 0xB7, ...}. The extra bytes in this region are the serial number and default frequency, but we'll get back to that later.
Firmware Analysis
As the firmware is only three kilobytes, it doesn't take terribly long to reverse engineer. First, the Special Function Registers (SFR) which are defined on pages 79 and 81 of the nRF24E1 datasheet are fed to the disassembler.
(I'm using IDA Pro here, but any 8051 disassembler with a decent text editor could suffice. All of the following function labels are from my imagination, while Special Function Registers (SFRs) come from the nRF24E1 datasheet.)
For example, "MOV 0xA0, #0x80" is rather opaque, but "MOV RADIO, #0x80" makes it clear that the immediate value 0x80 is being placed into the RADIO register. Page 89 of the datasheet will then explain that the high bit of the radio register is power control, so this instruction is powering up the radio for use. Similarly, "SETB RADIO.3" is setting the fourth bit of the RADIO register, which the datasheet describes as raising the CS signal.
Once the SFR addresses are known, it becomes useful to search for them in order to identify the I/O routines. In the nRF24E1, the radio is accessed across a SPI bus, so a good first step is to identify the SPI routine. The function containing this code will always include a MOV involving the SPI_DATA register.
Having this, a list of cross-references quickly shows that while few functions call the SPIRXTX function, each calls it many times. This is because the author has chosen to repeatedly call that function with immediate values, rather than to dump an array of bytes with a for(){} loop.
While the disassembler can automatically identify the function entry points in the table above, it is not capable of giving them English names or descriptions. To understand how this is done, it is necessary to read the datasheets of the SPI devices.
The SPI EEPROM chip, a CAT25C32, is used by dropping the !CS line then writing an opcode byte followed by its parameters or results. Opcodes include WREN/WRDI for write protection, RDSR/WRSR for accessing a status register, and READ/WRITE for reading and writing bytes. A WRITE may only be performed when the external !WP pin is low and the software write protect has been disabled by opcode. A transaction begins when !CS drops low and ends when it drops high.
To identify the function which reads a byte from the 25C32, a few things can be safely assumed: (1) The function will begin by dropping some I/O pin (!CS). (2) The function will then broadcast the READ opcode, 0x03. (3) It will then broadcast a sixteen bit parameter; that is, DPL followed by DPH. (4) Finally, it will return the result of a fourth SPIRXTX call. In pseudocode, that would be something like
SPIROMPEEK(u16 ADR){
SPIRXTX(0x03);
SPIRXTX(ADRL);
SPIRXTX(ADRH);
return SPIRXTX();
}
Sure enough, one of the few functions calling SPIRXTX does exactly this. The constant pushing and popping of the parameters is a quirk of the compiler, which might possibly allow it to be identified. From the code below, it is clear that P0.0 is the !CS line of the CAT25C32.
The SPIROMPOKE function looks similar, except that two transactions are performed. First the WREN (0x06) opcode is sent to enable writing, then WRITE (0x02) is used to perform the actual write.
The other SPI operations concern the nRF2401 radio core, which behaves differently from the EEPROM. Rather than transactions being an opcode followed by parameters, there is only a single SPI register that must be completely written during a transaction. A second register, selected by the CE line, contains the packets.
The configuration is set by one big register, sent MSBit first. If fewer than the needed bytes are sent, the value is right-aligned into the lower bytes of the register. That is, the last byte sent is always (CHAN<<1)|RXMODE and the second to last always describes the radio configuration.
Searching around a bit yields the RADIOWRCONFIG function, the tail of which is below. It can be seen from the code that the 0x1A IRAM byte holds the channel number. That is, if 0x20 is stored at 0x1A, the radio will be configured to 2,432 MHz. The other configuration bytes reveal that the MAC addresses are 24 bits, the checksum is 16 bits, and the device broadcasts at maximum power sourced from a 16MHz crystal. (That the configured crystal is identical to the one on the board is very important. Some enterprising coders will lie to a chip about its crystal in order to access an unsupported radio frequency.)
At this point, it still remains to sniff traffic is to find the target address to which packets are broadcast as well as the frequency. We'll start with the address, because that's a bit easier.
The TXPACKET function involves a lot of PUSH and POP instructions, but it otherwise looks very similar to the RADIOWRCONFIG function, in that a series of bytes are written in order with repeated function calls to SPIRXTX. In pseudocode, this function becomes the following. From the radio documentation and configuration, it is clear that the first three bytes will be the target MAC address. From the RADIOWRCONFIG() function, it is equally clear that the three bytes at 0x1B are the receiving MAC address of the unit. (The parameter of the function happens to be the button press, as can be determined by tracking the keyboard I/O routines or viewing a few packets.)
void TXPACKET(u8 button){
RADIOHOP(); //set channel
//Target MAC address
SPIRXTX(&0x1E);
SPIRXTX(&0x1F);
SPIRXTX(&0x20);
//Source MAC address
SPIRXTX(&0x1B);
SPIRXTX(&0x1C);
SPIRXTX(&0x1D);
//Data value
SPIRXTX(button);
}
The radio itself will append a 16-bit CRC; therefore, the full packet then becomes {u24 tmac, u24 smac, u8 button}.
To determine the value of the target MAC address, just grep the disassembly for "mov" and one of 0x1E, 0x1F, 0x20. The relevant instructions are as follows, setting the target MAC address to 0x123456. (In 8051 notation, the first instruction moves the immediate constant #0x12 into byte 0x1E of IRAM.)
mov 0x1E, #0x12
mov 0x1F, #0x34
mov 0x20, #0x56
As this point, it would be possible to scan each channel for a few seconds, listening for packets sent to that address, but it's classier to find the value by static analysis. Acting on the hunch that the configuration is held in EEPROM and looking for references to the SPIROMPEEK() function, the READIDFREQ() function can be found. As can be seen in the fragment below, EEPROM[6] holds the channel number while the MAC address is at EEPROM[3,4,5].
As the EEPROM begins with "0b 07 0b 15 79 1b 29", it's clear that the MAC address of the unit from which it came is 0x15791B and that it is broadcasting on 2400+0x29=2441MHz. This can be double-checked by the serial number "15791B" being printed on the label.
Implementation
Knowing the modulation scheme, target address, and packet contents, it becomes possible to sniff traffic from a Clicker. This is performed by use of the GoodFET firmware on a Next Hope badge, my prior tutorial for which describes the process of packet sniffing.
The NHBadge board contains an nRF24L01+ radio, which differs dramatically from the nRF2401 in terms of how it is configured. Still, the radios are sufficiently compatible. The following hack of the goodfet.nrf client allows packets to be sniffed from the air with proper checksumming.
Sure enough, here are some packets of the 5 button being pressed on unit 1F8760. The keypress is the final byte in ASCII.
Response Codes
Now that it is clear how to receive and recognize button presses, it becomes necessary to reverse engineer the response codes which might be sent from the access point. Without hearing a reply of at least an ACK, the Clicker will continue to broadcast each message more than three hundred times. This takes more than ten seconds, during which all other key presses are ignored.
The broadcast loop within the MAIN() function would look a little like this in C.
for(count=0;count< MAXCOUNT && !reply;count++){
TXPACKET(button);
reply=RADIORX();
}
switch(reply){...}
This region is easy enough to find, but there's another command mode. An easier target is the channel hopping routine, which constantly broadcasts 0x3F while incrementing the channel, sticking with the last one on which a reply of 0x18 was received. Channels 1 through 83 are attempted; that is, 2,401 MHz to 2,483MHz at 1MHz steps.
Checking this code within the MAIN() function reveals that its effect is to blink the green LED (P1.1) six times, exiting the broadcast loop. Other commands include 0x04 (LED Off), 0x06 (LED Green), 0x15 (LED Red), 0x11 (Blink Green), 0x14 (Blink Red), and 0x18 (Blink Green, Channel Lock). All undefined opcodes set the red LED.
Conclusions
By sniffing traffic within a classroom, it is possible to watch votes as they are being cast by students. Similarly, packets could be broadcast by a reprogrammed Clicker or NHBadge to make a student in virtual attendance, automatically voting with the majority so as to gain perfect attendance and a solid C quiz average. Where instant feedback is available, this might even allow for a solid A quiz average. Without taking advantage of the masked-ROM option of the nRF24E1, the code cannot be even slightly protected from extraction and reverse engineering.
Less adventurous users can jam the network by running 'goodfet.nrf carrier 2441000000' to hold a carrier wave on the channel. The only attempt at a frequency change is made when pressing the GO button, at which point the new channel can be discovered and similarly jammed.
Since performing this work, it has come to my attention that a USRP plugin for doing this to the competing 900MHz iClicker product is available as http://gr-clicker.sourceforge.net/. Additionally, the infrared Clicker units were broken with a little tool called Survey Says. I have ordered more sophisticated Clicker models from CPS and Turning Point, and proper descriptions of them will soon follow.
Langganan:
Postingan (Atom)
Meraih Jackpot Besar: Strategi dan Tips Bermain Slot dengan Agen Slot Gacor
Meraih Jackpot Besar: Strategi dan Tips Bermain Slot dengan Agen Slot Gacor Halo, para pecinta judi online! Apakah Anda sedang mencari car...
-
I'm able to’t tell you numerous girls have instructed maine over time and months that they may be in an awful book club oregon desires ...
-
Meraih Jackpot Besar: Strategi dan Tips Bermain Slot dengan Agen Slot Gacor Halo, para pecinta judi online! Apakah Anda sedang mencari car...
-
College football is an actual thrilling overall performance. Nan rating isn't always constant while you're looking astatine footbal...