Sunday, September 12, 2010

A primer on the design of a frequency detector (Part 1)

In French, we say "Theory is like practice, except in practice". I am definitely experiencing that. While trying to understand electronics, especially electronics for radio frequencies (RF), I am hitting all sorts of difficulties I want to share. It always amazes me when I see a radio, a WIFI or something else wireless. I've done a lot of theory during my studies (digital signal processing, information theory, etc.) but I've never built my own radio. Besides that, radios are known to be pure analog devices, so by definition, it's black magic stuff.

My motivation behind that is that we see more and more devices using wireless technology and it still remains pretty difficult to know what is shipped into the air. Of course you could use very expensive hardware, but the here, the goal is to make something affordable, something below 10$.


The first step when trying to understand a system is to know the frequency it uses. Nowadays, you can open the device and identify the RF chip. But sometimes, you are just unable to do it (nothing written on the chip, etc). But how can we know on which frequency it operates ? The idea here is to have a device that will try to determine a "known frequency". For example, a weather station will transmit the data at 315MHz. There are frequencies that are reserved for this type of use and for the ease of the design, will only assume the following frequencies: 315MHz, 390MHz, 434MHz.

To detect if there is a frequency in the air, we can use a logarithmic detector like the AD8313 from analog device.





The goal of this chip is to output a certain tension based on the input. Actually, they are essentially just cascaded amplifier. This is exactly what we are looking for: depending on the input it will capt in the air, the output will have more or less tension. However, this information is not enough. Indeed, you will have a high input if you are close to you weather station, but also if you are close to you Wifi station. In other words, the chip alone is not able to distinguish the difference in frequency.


To solve this issue, we will add different filters in front of the input, thus only the frequencies we are interested in will be detected. This brings us to a new hot topic: the filter design.

Thursday, July 1, 2010

Free laundry for everybody :)


Where I live, there is a room with the laundry machine. Once every other week, you can use it to wash your clothes.
We have different systems to pay: (pseudo) smart card, coins, etc, it depends on where you live. In my case, it was a pseudo smart card you have to refill with money (to the concierge) every time it gets empty.

Here is how it looks like:




I use the word "pseudo" smart card, because as you can see, it is not really one. Actually, there are only 6 contacts (instead of 8) and there is a sort of bus driving the signal somewhere in the white plastic.

The white plastic was heavily attached to the card, so to remove it, I put the whole card in an acetone bath. After few minutes, I was able to remove it without any pain.

I was amazed to see a simple EEPROM underneath. It already meant that replay attacks were possible, even if we didn't know how to interpret the content: save the content, do your laundry and restore the content afterward.




We can identify the chip and deduce from the logo that the manufacturer is "National":

71AR
93C46
M8

I found a similar datasheet. However, we'll see that it is not exactly the same.
Since I didn't want to be invasive on the card, I bought a "season 2 interface". This device is usually used by satellite pirate and is handy to do MITM on smartcards. I got mine for 8€.




I also soldered 8 pins on the back of the interface, to inject my signals (I/O of the SPI).




Since we have the datasheet, we can make the pin ring with a multimeter and deduce what corresponds to what on the smart card contacts:

X --- X (not assigned)
Di --- Sk
Do --- CS
GND --- VCC

I'll make a long story short, because I had different, not really relevant issues. To inject the signal, I used the "Bus pirate" (BP) and to verify that the injected signal was correct, I used the OpenBench Logic Analyzer (OLA). The BP is a cool piece of hardware, because there is an interpreter that will help you to send the correct signal with the correct synchronization, so no need to write a program for it. Since I was not mastering it, I used the OLA to make sure the signal was correct. According to the datasheet, the sequence to send is 0y110 + 6 bit address. After some trial and error, I finally was able to dump the whole memory, by sending something like the following command in raw3wire mode, 5V:
]-^^_^ _^:6 r:1024[

Actually, by looking at the longest prefix, we figure out that the memory is 128 B long and looks like the following:

READ:
0x03 0xE8 0x03 0xC8 0x03 0xD7 0x02 0xE9 0x00 0x00
0x00 0x04 0x03 0xEA 0x0B 0x5E 0x01 0xAA 0x0B 0x5E
0x00 0x00 0x0B 0x5E 0x00 0x00 0x00 0x00 0x00 0x00
0x03 0xE8 0x00 0x04 0x03 0xEA 0x0B 0x5E 0x01 0xAA
0x0B 0x5E 0x0B 0x5E 0x00 0x00 0x00 0x00 0x00 0x00
0x25 0xAE 0x15 0xB3 0x1A 0x0A 0x00 0x00 0x00 0x00
0x00 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF



The smallest granularity is 2B when accessing the card (just make the division and it'll fit). At the first look, I don't know what these values really are. So I decided to go to the laundry room, put my card in the reader and pay for a wash. The price was 3.-. Then I dumped the content again and made a diff:

READ:
0x03 0xE8 0x03 0xC8 0x03 0xD7 0x02 0xE9 0x00 0x00
0x00 0x04 0x03 0xEA
0x0A 0x32 0x01 0xAA 0x0A 0x32
0x00 0x00
0x0A 0x32 0x00 0x00 0x00 0x00 0x00 0x00
0x03 0xE8 0x00 0x04 0x03 0xEA
0x0A 0x32 0x01 0xAA
0x0A 0x32 0x0A 0x32 0x00 0x00 0x00 0x00 0x00 0x00
0x25 0xAE 0x15 0xB3 0x1A 0x0A 0x00 0x00 0x00 0x00
0x00 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF


This is interesting, 6 regions in memory changed somehow. But what does 0x0A32 means ? This is 2610, and previously, we had 0x0B5E which are 2910. Remember I told you it costed me 3.-... and what I didn't tell you was the amount of money remaining on my card: 29.10.-. So it is just written in clear in 6 different regions in memory, I couldn't believe it !

The next step was to write 9990 (0x2706) in these memory position and see if it worked. However, to write, according to the datasheet, we have to set WEN, and we just cannot, since all the pinouts are taken. Thus, this is not the good method. I tried to send a "write" command, but without any success :(.

When I was looking for the datasheet of the chip, I found also this one. This is an Atmel, but it turns out the protocol is quite similar. We see there is a "Write Enable", with sequence 0y10011XXXX that has to precede every programming mode.
If we now send a command like

]-^_^^-^^^^^^^^[ ]-^_^-^ -^^^^^^ 0x12:2[ ]-^^_^ -^^^^^^ r:128[

the magic occurs and we see, hopefully, that the content has been correctly written to the EEPROM. This is a good news, so we can now modify the 6 areas we previously found. I did a small script to calculate the offsets, but basically, we need to modify by doing this:

]-^_^^-^^^^^^^^[ ]-^_^-^ _^^^-^^^ 0x27 0x06[ : 7th word
]-^_^^-^^^^^^^^[ ]-^_^-^ _^^-^_^^-^ 0x27 0x06[ : 9th word
]-^_^^-^^^^^^^^[ ]-^_^-^ _^^-^_^-^^ 0x27 0x06[ : 11th word
]-^_^^-^^^^^^^^[ ]-^_^-^ _^-^_^^-^_^ 0x27 0x06[ : 18th word
]-^_^^-^^^^^^^^[ ]-^_^-^ _^-^_^-^_^^ 0x27 0x06[ : 20th word
]-^_^^-^^^^^^^^[ ]-^_^-^ _^-^_^-^_^-^ 0x27 0x06[ : 21th word


Of course, this can be written in a shorter manner, but for clarity, I leave it this way. To sum up, we just modified the 6 areas in memory to put 9990 (0x2706) in them (99.90 CHF), because it sounded like the mechanism was working this way. Now, let's go back to the laundry room to see if it works as expeced:





This is a very small hack, but still nice. I'm not sure this company is still selling this kind of "smart cards", they probably replaced them with real smart cards nowadays. I wouldn't have done this hack without the help of Ian & Sjaak from the dangerous prototypes forum, so greetz to them.

Thursday, June 10, 2010

When a stranger calls you at work...

Hey guys,

I apologize for not being very active these last times. I've been working and trying to prepare the amateur radio exam (not sure I'll do it, but I'm preparing it...), so nothing very exciting.

This won't be a technical article, just something that happened to me today. I received an anonymous call at my working place. The guy was a financial advisor who wanted to invest my money. He said that he had contacts within my company and that was the way he got my direct phone call. While speaking a British English, he started to ask me what I was interested in (retirement, etc) and fixed an appointment after asking me a bunch of questions, like my age, if I was single, etc. Actually, I thought it was someone of my company and I trusted him, until he asked me my email address. I gave him my address, but I was puzzled: how cannot he know my email address if he had a contact in my company ? That was weird.
I was really concerned about the privacy issue here. I decided to contact the HR and I explained to them what just happened. I was also pissed off they gave my direct contact to some stranger. It turned out that they were absolutely not aware of this activity and decided to directly contact them and they swore they never told anyone about my private info.
Meanwhile, I was thinking about how they could find me and I figure out they could have used Linkedin. This is the only place where I put real info about myself... and indeed, the company looked at my profile lately. Sounds pretty easy from here, they know where I work, they call the reception, ask for me and TADA, this is it.
I reported the case to the HR who said that they will sue them if another case is registered.
I know that if I'll go to the meeting, I will probably get out with a new insurance or I don't know what, so I decided to reply that "for security reasons, I have to decline the meeting". I'll classify this as social engineering act, and fuck, it worked very well !

Saturday, April 3, 2010

Analyzing the Fiat Blue&Me iPhone Adapter

I recently got a new car, a Fiat Punto to be more precise. The car has a lot of gadgets inside, like the cruise control, USB, bluetooth for the cellphone, etc. It also has the an infotainment system called "Blue&Me", which is pretty well done, with a not too bad voice control system. Well, I have a USB connector, so I'd like to attach my iPhone in order to listen to my playlist. Sadly, the Blue&Me system is not able to read the iPod/iPhone directly, we need to buy a tiny device:



This small piece of hardware is charged around 140$ in the Fiat store. It bugs me: why the hell is it so expensive ? Is there any custom hardware inside or what ?

Let's open it and see what's inside:

  • TOP view:


  • BOTTOM view:



  1. STM32F101C8T6: The STM32F101xx access line family incorporates the high-performance ARM Cortex-M3 32-bit RISC core operating at a 36 MHz frequency, high-speed embedded memories (Flash memory up to 128Kbytes and SRAM up to 16 Kbytes), and an extensive range of enhanced peripherals and I/Os connected to two APB buses. All devices offer standard communication interfaces (two I2Cs, two SPIs, and up to three USARTs), one 12-bit ADC and three general purpose 16-bit timers.

    Price for a single chip: ~5$

  2. SMSC USB2512I: The SMSC 2-Port Hub is low power, OEM configurable STT hub controller IC with 2 downstream ports for embedded USB solutions.

    Price for a single chip: ~5$

  3. PL-2303MX: USB to Serial Bridge Controller.

    Price for a single chip: ~7$

  4. There is a small chip I wasn't able to identify.
There are other passive electronic components, like voltage rectifiers, etc. If you have access to a lab where you can print your own PCB, the overall cost of this tiny adapter is ~20$.

If you look carefully at how the adapter is designed, you might find that the chips are not placed at right location. The USB2512I(USB Host) chip is close to the male connector whereas the UART (slave) chip is close to the female USB connector. This does not really correspond to how it should work, since the iPhone [slave] must be connected to a host [aka female input] and the adapter must behave as a slave [aka male output] with respect to the car.



As you can see, there is a 10Pin connector, probably a JTAG (according to the ARM datasheet). I am surprised they let the pins, now I just want to test what's going on in the chips. However, we don't need all this information. Another approach is to check what are the signals coming in and out from this device: how does the iPhone communicate with the car and vice-versa, how does the car communicate with the iPhone ? For this, we must be able to sniff the USB connexion. How ? You might use an expensive USB sniffer, or there might be another better [aka cheaper] option: dumping the content right after the PL-2303 and right before the USB2512i, because we will have a serial signal :).

Saturday, March 20, 2010

Dumping out the content of the Arduino

I'm very impressed by how easy it is to make a small program on the arduino, the community did a great job. Also, I think it's a very easy introduction to embedded systems, because you don't have to worry about the low-level aspect of embedded systems in general.
Recently, I had to analyze a "black-box". By black-box I mean a box that you don't know anything about. In my case, it was a 3k$ video component, with a FPGA (Cyclone II) and an atmel (Atmega168). I got it for a little moment, I also had an AVR programmer but I did not know how I could dump out the content of the atmega chip.

It turns out that in Windows, you can just install AVR Studio and from there you will have a nice GUI with all the options to maybe retrieve the content from the memory. This programs does a great job, but what about Linux ?

Well, avrdude is your friend in the Linux world. I wanted to dump the content of the memory, so an idea might be to use it this way:


~/arduino-0017/hardware/tools/avrdude \
-C~/arduino-0017/hardware/tools/avrdude.conf -v -v -v -v \
-pm328p -cstk500v2 -P/dev/ttyUSB1 -D -Uflash:r:/tmp/kikou.hex:i


And ohh... magic, all the content is dumped on the file /tmp/kikou.hex.

Well, this is an intel hex dump, so not really readable:


:200240008093A30181E0809370011092A001089580919E0190919F012
:2002600081E0809399011092A00110927101109270010895809198018
:200280009801109299010895EF92FF92CF93DF93FB012091700122231
:2002A000710123503081231708F420834081C3E7D1E0BE0150E00E941
:2002C00071012FEF3FEF219713C099912927022E2295207F2025032E3
:2002E000269532272327220F220F220F20258150882359F790EF283B8
:20030000CF91FF90EF9008958091550160919A010E945F03809110016
:20032000910181E08093980108951F920F920FB60F9211242F933F934
[...]


I tried to dump it as "raw output", but you will get an hexdump. "Ce n'est pas folichon" I'd like to say. From the hexdump, one cool thing would be a disassembler, but apparently, nobody has done one on Linux. If you know a way to read hexfiles (avr-objdump won't work here), drop me a message!
Another solution is to use the AVR Studio program in Windows, apparently it does the job, but I haven't tried yet.

We'll probably come back on that very soon 8).

Saturday, January 16, 2010

My first steps with the Arduino

I recently received the arduino I ordered on Makershed. Actually, I took a starter kit to play with this small piece of hardware. The board has an ATMEGA328 uproc (8-bit) with few I/Os to play with.

They offer a nice tiny sdk to write your code/compile and upload. I've nothing to say, it's working great, they did a good job, however, since I am an emacs aficionados (and I'm not a Java fan), I wanted do the process manually.

The first was to analyze a bit was was given in the arduino (software) package. The file being in arduino-0017/hardware/cores/arduino/Makefile gives you the makefile to compile your programs. We can already notice that it does not work out of the box and that you've to modify it.

Here are my modifications:

INSTALL_DIR = $(HOME)/arduino-0017
PORT = /dev/ttyUSB0
UPLOAD_RATE = 57600

AVR_TOOLS_PATH = /usr/bin
SRC = $(ARDUINO)/pins_arduino.c $(ARDUINO)/wiring.c \
$(ARDUINO)/wiring_analog.c $(ARDUINO)/wiring_digital.c \
$(ARDUINO)/wiring_pulse.c \

AVRDUDE_FLAGS = -V -F -C $(INSTALL_DIR)/hardware/tools/avrdude.conf \

Well, you notice that one file somehow disappeared in SRC. I simply removed it and it seems to be working. Also, the AVR_TOOLS_PATH was pointing on a wrong directory.

Now, for compiling your stuff, a simple make must be enough.

The next step was the upload that was a big deal for me. Actually, it was working with the Java interface, but not with avrdude. Actually, I was using the following command, because I saw it somewhere:

avrdude -V -F -C ~/arduino-0017/hardware/tools/avrdude.conf -p m328p -P /dev/ttyUSB0 -c stk500 -b 19200 -U flash:w:applet/Fading.hex -vvvvvv

Well, I got the following message:

avrdude: Send: 0 [30] [20]
avrdude: Send: 0 [30] [20]
avrdude: Send: 0 [30] [20]
avrdude: ser_recv(): programmer is not responding
avrdude: stk500_recv(): programmer is not responding

So WTF (Huh, btw, I entered twice avrdude avrdude [...], it segfaults after trying one :)) ? How so it's working with the Java App, but not with the avrdude ? As a wise guy said once "one week of trial and error can save up to half an hour of reading documentation", well, actually I could have read the Arduino troubleshooting section, but...

My idea was to sniff the what's going on /dev/ttyUSB0 when using the Java IDE and compare it with the avrdude command. To sniff it, I found jpnevulator as being usefull.

When running it, ./jpnevulator --read --tty /dev/ttyUSB0, turned out that I was getting the "programmer is not responding" error message even in the Java IDE :), this meant that the Java IDE was calling avrdude somehow (since this is an avrdude error message).

Cool, I downloaded the Java files from their svn and started to grep on these. In arduino/app/src/processing/app/debug/Uploader.java I found something interesting:

if (verbose || Preferences.getBoolean("upload.verbose")) {
for(int i = 0; i < commandArray.length; i++) {
System.out.print(commandArray[i] + " ");
}
System.out.println();
}


So, since I did not want to recompile all the files (lazy ?), I just wanted to set this boolean upload.verbose to true. Turns out that the preferences are read from a file ~/.arduino/preferences.txt, so you just have to add "upload.verbose=true" somewhere in there.

Now we run the Java program again and we the nice working avrdude command. We can use it directly after resetting the device (by pushing the button or directly sending a reset signal).

The command it now:

/usr/bin/avrdude -V -F -C ~/arduino-0017/hardware/tools/avrdude.conf -p atmega168 -P /dev/ttyUSB0 -c stk500v1 -b 57600 -U flash:w:applet/Fading.hex

Basically, the speed was wrong. Again, don't forget to push the reset button before shipping the code on the board

Monday, January 11, 2010

Finding the number of parameters directly in the assembly

Recently, when working on my library tracer, I wanted to know the number of parameters a function uses. I did not have any access to source code or debug info, so I had to find another way to get this information. Programs like ltrace/strace have an extra file, usually located in /etc/ to define the prototype of certain functions. When ltrace does not know a specific function prototype, it simply sets the number of parameters to 5 by default. However, by doing a simple analysis of the assembly code we can infer the number of parameters with a pretty high success rate. In my study I assumed we are using a x86_64 Linux box that binaries have not been obfuscated.

We will focus on regular registers, but the theory applies for FPU registers too. By convention, on x86_64, GCC will use the registers to pass the arguments (before using the stack), in the following order: %di - %si - %dx - %cx - %r8 and %r9. Thus, without loss of generality, up to 6 parameters can be passed through registers (before using the stack), with some exceptions for bigger data structures.

We define a block as being the set of instructions between two instructions changing the control flow (e.g.: ret / call / j). First, we localize this instructions in the disassembled program. From there, we move backward to retrieve the different parameters.

Let's do it on a example. The following snippet of code defines 4 blocks:


402406: 84 c0 test %al,%al
402408: 0f 84 62 ff ff ff je 402370
----------------------------------------------------------
40240e: 40 84 ff test %dil,%dil
402411: 74 e0 je 4023f3
----------------------------------------------------------
402413: 83 3d e2 5e 21 00 03 cmpl $0x3,0x215ee2(%rip)
40241a: 75 d7 jne 4023f3
----------------------------------------------------------
40248c: 48 8b 2d 35 69 21 00 mov 0x216935(%rip),%rbp
402493: ba 05 00 00 00 mov $0x5,%edx
402498: be 88 0b 41 00 mov $0x410b88,%esi
40249d: 31 ff xor %edi,%edi
40249f: e8 24 fb ff ff callq 401fc8

If we take the last block, and we perform a backward analysis, we figure out that the registers %di, %si, %dx (and %bp) are modified. According to the _cdecl_ calling convention, it is likely that the function will take 3 arguments before jumping into the plt trampoline.

Sadly, this is not always as clear as in the previous example. For instance, we can see that the others block does not follow this nice rule, but can we deduce the function are not expecting any parameter ? As it was previously stated, it is very rare that a function in called only once. Although, the main purpose of a function is exactly the opposite, ie being called as often as possible from various parts of the program. Thus, by applying the previous criterion over all functions, we can deduce a heuristics that will retrieve the number of arguments with a good success rate.

Every time we encounter a function call, we save the set of registers of the block. A map looks like the following: (%di. %si. %dx. %cx, %r8, %r9). Every element is a boolean and says whether the register was used or not.

Let's take the same function as before, dcgettext(..) from /bin/ls. The function is called around 15 times in the overall program, but all the registers cannot be retrieved every time.

(0, 0, 1, 1, 0, 0)
(0, 0, 1, 0, 0, 0)
(0, 1, 1, 0, 0, 0)
(1, 0, 1, 0, 0, 0)
(1, 1, 1, 0, 0, 0)
[...]

Typically, (0, 0, 1, 1, 0, 0) means that only registers %dx and %cx were used. Thus, we take the set that has been used the most frequently. Let's assume the set appearing the most often is: (0, 0, 1, 0, 0, 0). This would mean that only register %dx is used. However, we do have a discrepancy compared to the official _cdecl_, because the first parameter must be sent through the %di register.

A good practice is to set to 1 all the registers that are on the left of the top-right register in the map. Thus, (0, 0, 1, 0, 0, 0) will become (1, 1, 1, 0, 0, 0). This means that register %di and %si are also used. To make sure our theory is correct, we can check in the man pages that the prototype is correct:

char * dcgettext (const char * domainname, const char * msgid, int category);

For the function having an associated man page, this technique has been shown to be very effective, by retrieving correctly the number of registers 90% of the time. When the mean gives us a guessable output, we will always choose the value that have more registers set, in order not to miss any of them. Note that this technique is very light, since it does not require to go into the called function to analyze the parameters in there.

To implement this, I chose Perl for a simple reason: I get the binary output from objdump and then I can parse into it pretty easily with simple regex. Using this kind of techniques we can also infer the type of the parameters, but this is another story 8).