Damn Vulnerable Router Firmware - Hardware Bring-up

The Damn Vulnerable Router Firmware (DVRF) is a vulnerable firmware for Linksys E1550 routers. According to the author, "the goal of this project is to simulate a real world environment to help people learn about other CPU architectures outside of the x86_64 space."

Before overwriting the original firmware, make sure to get a copy of the most recent version: FW_E1550_1.0.03.002_US_20120201_code.bin.

DVLF can be installed to the Linksys E1550 by opening the device's firmware upgrade page.

UART connection

As stated in the project's README.md file, UART access is needed in order to execute the "pwnable" binaries. The UART pins are easily accessible after populating DJ12 with a 1x5 pin male header (2.54 mm spacing between pins).

Open Housing

housing

To avoid short-circuiting, remove the power plug before you open the housing!

The Linksys E1550 uses an external power supply so it was not designed with concern for hazardous voltages inside the enclosure. However, to avoid short-circuiting, remove the power plug before you open the housing!

To open the housing, remove the three screw covers on the back of the device. Please note that products with their warranty labels and barcodes removed or altered are not covered by the warranty any more.

The screws can be easily removed using a Phillips-tip screwdriver. After removal, use a special soft-plastic housing opening tool to lift the lid.

Attach Pin Header

pcb

The UART pins are located at DJ12, right above the Serial Flash IC (Winbond 25Q128BVFG). Use a solder iron to solder a 1x5 pin male header (2.54 mm spacing between pins) to DJ12.

Pinout

  • Pin1: 3.3 V
  • Pin2: Tx (Linksys E1550 transmits on this pin)
  • Pin3: Rx (Linksys E1550 receives on this pin)
  • Pin4: ?
  • Pin5: GND

Firmware Installation

Download DVRF

git clone https://github.com/praetorian-inc/DVRF.git
file DVRF/Firmware/DVRF_v03.bin
   DVRF/Firmware/DVRF_v03.bin: data

Install DVRF

Connect your PC to the Linksys E1550 via Ethernet. Your PC should get an IP address via DHCP, the default subnet is 192.168.1.0/24. Use your default browser to open the device's firmware upgrade page and upload file DVRF/Firmware/DVRF_v03.bin. The device will automatically reboot after the installation.

After the device rebooted, connect to the router's default page, you should see the following:

housing

Reverse Engineering Remote Control Power Sockets - Part 2: Protocol analysis with oscilloscope

Tooling

If you've read the first blog post of this series, you already know that the intention of this project is to replace the remote control of these devices by a cheap 433 MHz transceiver and a microcontroller platform. In order to do so, the protocol send by the remote control encoder chip PT2262, has to be imitated by the microcontroller. We already know from the previous blog post, that pushing one of the buttons of the remote control forces the PT2262 to create a unique codeword that is send to RF modulator. The datasheet:

The encoded waveform is serially outputted to this pin. When PT2262 is not transmitting, DOUT outputs low (Vss) voltage.

To be able to replace the remote control by an own circuit driven by a microcontroller, the special codeword for each button has to be determind.

Oscilloscope

Oscilloscope DOUT

Using an oscilloscope is the most comfortable way to reverse engineer the remote control protocol. A cheap one like the Rigol DS1052e is more than sufficient. Don't mind if you can't afford one, I will show a cheaper method to get behind the protocol in an upcoming blog post.

Connection

Connect your probe's ground clip to HX2262's pin 9 (VSS) and the probe tip to pin 17 (DOUT).

Rigol DS1052E settings

  • Long Memory (Acquire -> MemDepth -> Long Mem)
  • Single shot trigger

Determining the Oscillating Clock Period α

product info

We already know from the datasheet, that each bit waveform consists of two pulse cycles and each pulse cycle has 16 oscillating time periods. In the case of a Bit "0", one pulse cycle consists of four periods high and twelve periods low clock periods. This pattern can be easily found with the oszilloscope.

The picture on the left shows the overall time (2.62 ms) for a "0" bit:

\begin{equation*} \alpha = \frac{2620\,us}{2 * (4 + 12)} = 81.875\,us \end{equation*}
product info

The picture on the right shows the low part of the first pulse cycle (12 periods low bits) with a total time of 984 us:

\begin{equation*} \frac{984\,us}{12} = 82\,us \end{equation*}
product info

Given both results, we can asume the oscillating clock period α to be 82 us. According to the datasheet, α can be configured by a resistor connected between pins 15 (OSC 1) and 16 (OSC 2), so it might differ for other power outlets. It might be a good idea to not hardcode the value.

Another approach to determine α is to connect the probe tip to pin 15 (OSC 1) and to directly measure the oscillator frequency. The picture on the left shows one cycle duration of the oscillator frequency. The measured periodic time of 83.6 us fits our previously made assumption of 82 us.

Codeword analysis

A group of Code Bits is called a Code Word. A Code Word consists of 12 AD bits followed by one Sync Bit.
product info

In part 1 of this blog post series, we assumed that the first five bits encode the outlet group part of the codeword, the next five encode the socket within that group and the last two encode the on/off part. We can simply proof this assumption by just pressing the appropriate push-button on the remote control and displaying the waveform on the oscilloscope. A good starting point is to set all pins of the DIP switch (Code Address Pin 0 ~ 5) to off (outlet group 0) and press the on/off push-buttons for each outlet within that group.

The following sequence of images show one complete codeword for pushing the on and off buttons for different combinations of groups and outlets. Please notice that some signal changes overlap, just try to find the bit patterns that are already known from the datasheet. Each picture (except the last one) contains four bit patterns. This makes a summary of 12 AD bits followed by one sync bit. The codewords are then grouped together to their group (five bits), outlet (five bits) and data (two bits) parts.

Outlet group 0 | Outlet 0 | On

Pushing the on button for outlet 0 within group 0 leads to the following codeword:

product infoproduct infoproduct infoproduct info

Codeword: FFFF F0FF FF0F Sync

Group Outlet On/Off
FFFFF 0FFFF 0F

Outlet group 0 | Outlet 0 | Off

Pushing the off button for the same outlet (0) within the same group (0) leads to a very similar result. Solely the last two bits have changed.

product infoproduct infoproduct infoproduct info

Codeword: FFFF F0FF FFF0 Sync

Group Outlet On/Off
FFFFF 0FFFF F0

Outlet group 0 | Outlet 1 | On

The next image series shows the result for pushing the on button for outlet 1 within group 0. This time, the outlet part of the codeword has changed while the group part is still the same.

product infoproduct infoproduct infoproduct info

Codeword: FFFF FF0F FF0F Sync

Group Outlet On/Off
FFFFF F0FFF 0F

Outlet group 1 | Outlet 0 | On

Setting the first DIP switch to "on" and pressing the on button for socket 0 again, leads to another codeword. This time, the first bit group has changed.

product infoproduct infoproduct infoproduct info

Codeword: 0FFF F0FF FF0F Sync

Group Outlet On/Off
0FFFF 0FFFF 0F

Outlet group 31 | Outlet 0 | On

The last image series shows the codeword for the following setup: All remote control DIP switches are set to on (group 31) and the on button for outlet 0 has been pushed.

product infoproduct infoproduct infoproduct info

Codeword: 0000 00FF FF0F Sync

Group Outlet On/Off
00000 0FFFF 0F

Determining all codeword combinations is now either a question of diligence or just a riddle. One could just configure all possible group DIP switch settings, push all buttons and record all codewords with the oscilloscope. However, a more sophisticated approach would be to find the relationship between DIP switch settings and button presses by the already given information.

Conclusion

The assumtions made in part 1 of this series seem to be correct. One codeword consists of five bits for the outlet group, five bits for the outlet within that group and two bits for the on/off part of the codeword.

The timebase for the codeword (Oscillating Clock Period α) was measured with the oscilloscope and seems to be around 82 us.

Reverse Engineering Remote Control Power Sockets - Part 1: Information gathering

Tooling

  • Phillips-tip screwdriver
  • Computer with internet access
  • Multimeter (optional)

Remote control

product info

According to the information on the back, the remote control sends on 433.92 MHz, a frequency within the UHF band. The 433 MHz band is meant for short range consumer devices including automotive, alarm systems, home automation and temperature sensors.

Open housing

To avoid short-circuiting, remove the 12 V battery, then remove the three screws using a Phillips-tip screwdriver. When the srews are removed, you can easily lift the housing and remove the printed circuit board (PCB).

Printed circuit board

product info

There are only a few components placed on the PCB, the most interesting ones can be found on the top layer:

  • Battery holder
  • DIP switch
  • Integrated circuit (IC) in 18 pin dual in-line (DIP) package, labeled with HX2262
  • Contacts for push-buttons
  • 433 MHz oscillator
  • Light-emitting diode (LED)

Ignore the yellow dot added to the picture of the PCB's top layer at the moment, we'll come back to it later.

Remote Control Encoder

An internet search for HX2262 quickly leads to the IC's datasheet. The IC HX2262 (PT2262) is a Remote Control Encoder and can be paired with PT2272, the suitable Remote Control Decoder.

PT2262's purpose is quickly explained:

PT2262 encodes the code address and data set at A0 ~ A5 and A6/D5 ~ A11/D0 into a special waveform and outputs it to the DOUT when TE is pulled to 0 (Low State). This waveform is fed to the RF modulator for transmission. The transmitted radio frequency RF demodulator and reshaped to the special waveform. PT2272 is then used to decode the waveform and set the corresponding output pin(s). Thus completing a remote control encoding and decoding function.

Data Output Pin (DOUT)

All connections of the pins described later on have only one purpose, to influence the behaviour of pin 17, the Data Output Pin (DOUT).

The encoded waveform is serially outputted to this pin. When PT2262 is not transmitting, DOUT outputs low (Vss) voltage.

We already know from the Remote Control Encode description, that DOUT's output is fed into the RF modulator and send to the power plug. The lazy reader might stop reading at this point. The whole magic happens on DOUT as will be described in a future post.

Code Address Pin Group

product info

From the power plug manual, we already know that the DIP switch is used to control a specific outlet group and the push-buttons are used to control four outlets within that group. Using a multimeter in continuity test mode or just looking at the connections on the bottom layer shows, that five pins of the DIP switch are directly connected to the bottom layer polygone plane. The polygone plane is directly connected to the negative pole of the battery holder (GND).

The remaining five pins are directly connected to pins 1 to 5 of the HX2262 (red dots on bottom layer picture):

  • DIP switch Pin 1 <--> PT2261 Pin 1 (A0)
  • DIP switch Pin 2 <--> PT2261 Pin 2 (A1)
  • DIP switch Pin 3 <--> PT2261 Pin 3 (A2)
  • DIP switch Pin 4 <--> PT2261 Pin 4 (A3)
  • DIP switch Pin 5 <--> PT2261 Pin 5 (A4)

According to the datasheet, pins 1 to 5 belong to the Code Address Pin group (A0 ~ A5):

Code Address Pin 0 ~ 5: These six tri-state pins are detected by PT2262 to determine the encoded waveform bit 0 ~ bit 5. Each pin can be set to 0, 1 or f (floating).
R04

Taking a look at the bottom layer again shows that PT2262's pins 6, 7, 8 and 10 are connected to vias in the middle of the PCB (yellow dots). Together with pin 11 (yellow dot on the top layer picture), those pins are all connected to push-button contacts.

The description for pins 6, 7, 8, 10 and 11 states that those pins are named A6/D5 ~ A11/D0 and belong to the Code Address Pin group as well.

Code Address Pin 6 ~ 11 / Data Pin 5 ~ 0. These six tri-state pins are detected by PT2262 to determine the encoded waveform bit 6 ~ bit 11. When these pins are used as address pins, they can be set to 0, 1, or f (floating). When these pins are used as data pins, they can be set only to 0 or 1.

Since those pins are directly connected to the push-buttons, it is most likely that they are used as data pins for setting a power plug either on or off.

RF operation: Code bits

product info

A code bit is the basic component of the encoded waveform, and can be classified as either an AD (address/data) bit or a sync (synchronous) bit. The PT2262 protocol knows three different AD bits:

  • Bit "0"
  • Bit "1"
  • Bit "f" (floating)

A group of code bits is called a code word. A code word consists of 12 AD bits followed by one sync bit.

The time base for all code bits is the so called Oscillating Clock Period (α). To be able to create the codewords with a microcontroller, it is necessary to know α. The simplest way to get the Oscillating Clock Period is to connect an oscilloscope to the DOUT pin, search for a known bit pattern ("0", "1" or "f") and just measure the time for that pattern.

Signal Resistor Oscillator

R04

The PT2262 has a built-in oscillator circuitry that can be configured with a resistor connected between pins 15 (OSC1) and 16 (OSC2). Taking a look at the bottom layer shows that the respective resistor is R04. The SMD resistor code "335" indicates the numerical resistance value of 3.3 MΩ, a value suggested by the datasheet.

Osc

The Signal Resistor Oscillator directly affects the DOUT carrier frequency. The datasheet includes a diagram showing the relationship between R04 and the encoder oscillator frequency. For the resistor value of 3.3 MΩ, the frequency amounts to approximately 10 kHz.

Schematics

As stated before, all relevant information, needed to reverse engineer the protocol send by the remote control, is already known. However, the nosy reader may want to grab a multimeter in continuity test mode to reverse engineer the functionality of the push-buttons and the DIP switch.

product info
  • As stated before, one pin row of the DIP switch is directly connected to GND. The other row is connected to PT2262's pins A0 to A4. The DIP switch is used to configure the outlet group part of the code word send out by the DOUT pin.
  • Pin A10 is pulled high by R03 by default. Pushing one of the ON buttons pulls the pin to GND. Pin A10 encodes the ON information part of the codeword.
  • Pin A11 is pulled high by R01 by default. Pushing one of the OFF buttons pulls the pin to GND. Pin A11 encodes the OFF information part of the codeword.
  • One of the three contacts of each push-button pair is connected to one of PT2262'S pins A5 to A8:
    • Push-buttons A: A5
    • Push-buttons B: A6
    • Push-buttons C: A7
    • Push-buttons D: A8
  • The low-active Transmission Enable (/TE) pin is pulled high by R02 normally. Pushing one of the buttons brings the corresponding diode in its conductive state and pulls /TE towards GND. PT2262 starts to output the encoded waveform to DOUT.

Reverse Engineering Remote Control Power Sockets

pollin frontpollin back

For about 13 EUR, the German electronics dispatcher Pollin sells remote controlled power plugs that can be used as kind of a poor man's home automation system. Four plugs can be grouped together and switched on or off by a remote control.

Inspired by an article in the German c't Hacks magazine (3/2012), the following series of post will guide through a reverse engineering process with the intention to replace the remote control in two different ways. The first approach uses an Andoid smartphone connected to a Raspberry Pi via WiFi, the second one makes use of a STM32F0DISCOVERY. Both microcontroller platforms make use of a cheap 433 MHz transceiver ordered in China. If you plan to rebuild one of the projects, make sure to order right now, the shipping from China may take weeks to month.

In case of the Raspberry Pi, two approaches will be described, one in userspace and one in kernel space. The kernel space approach comes in form of a Linux Kernel Module (LKM) and hides the fact that the Raspberry Pi normally is not capable of fulfilling realtime tasks.

Tooling

In order to follow the articles, or to rebuild one of the projects, you'll need the following items:

  • Raspberry Pi and Android smartphone or
  • STM32F0DISCOVERY
  • 433 MHz transceiver (e.g. from ebay)
  • Multimeter (optional, e.g UNI-T UT61C)
  • Oscilloscope (e.g. RIGOL DS1052E) or
  • Software-defined radio supported by rtl-sdr (e.g. Noxon DAB Stick)
  • Phillips-tip screwdriver

Fix PlayStation 2 not reading discs

Open housing

product info

To avoid short-circuiting, remove the power plug before you open the housing!

The PlayStation 2 (PS 2) uses an external power supply so it was not designed with concern for hazardous voltages inside the enclosure. However, to avoid short-circuiting, remove the power plug before you open the housing!

To open the housing, remove the five screw covers on the back of the PS 2. One of the screw covers is hidden behind the guarantee sticker. Please note that products with their warranty labels and barcodes removed or altered are not covered by the warranty any more.

The screws can be easily removed using a Phillips-tip screwdriver. After removal, use a special soft-plastic housing opening tool to lift the lid.

Clean-up

Clean housing

After removing the housing, use a slightly damp cloth to clean the inside of the PS 2.

Let the device dry for several hours in order to avoid a short-circuiting.

Clean laser lens

lense

Never look into the lens!

Avoid touching the lens or some of the fat from your fingers will stick on it. Use a clean cotton bud, dip it into denatured alcohol (methylated spirits) and gently clean the lens. It should appear completely clean.

Check DVD drive motors

  • Never look into the laser beam inside the PS 2!
power_plug

The DVD reader has two motors, one to spin the DVD (left rectangle) and one to move the laser unit (right rectangle) back and forth. Obviously, both motors have to work properly to guarantee an error-free operation of the DVD drive. A special safety mechanism avoids motor spinning while the cover is removed.

Put a DVD into the PS 2 (onto the spindle) and attach the power plug. Inserting a DVD has two advantages, the DVD will cover the laser and it will be easier to check if the DVD motor is spinning. The red LED should indicate that the PlayStation 2 is powered properly.

power_plug

Push the power button (see picture on the right) to power up the PS 2. As usal, the green status LED should indicate the device start-up.

Notice the small black push-botton on the top of the power button PCB. It gets pushed when the DVD tray gets closed.

front push-button

As noted before, a special safety mechanism avoids motor spinning while the cover is removed. The safety mechanism consists of two push-buttons, one on the top of the power button PCB (left picture) and one on the mainboard (right picture). Both buttons normaly get pushed when the DVD tray gets closes. To be able to check if the motors work properly, the buttons have to be pushed manually. Press and hold both buttons simultaneously. The DVD should start spinning and the optical unit containing the laser should start moving.

mainboard push-button

If both motors do not start to spin, remove the power plug and use the continuity test mode of your digital multimeter to check both switches. If both are working correctly, your housing might be the problem. Check if one of the plastic pins (pushing the buttons when you close the housing) is broken. If one of the pins is broken, you may want to either fix it (glue) or just short-circuit the corresponding push-button.

Send SMS from Python on the Nokia N900

The script

The following Python script can be used to send a SMS on the Nokia N900.

#!/usr/bin/python

import pexpect # Python module for controlling other programms.
import time
import sys
from subprocess import * # Pyton module for spwaning new processes.

tmp  = raw_input("Enter mobile number:\n");
tmp = tmp.rstrip('\n')

if (tmp[0] == tmp[1] == "0"):
    number = tmp
elif (tmp[0] == "0" ) and (tmp[1] != "0"):
    number = "+49"+tmp[1:]
else:
    print "[-] This does not seem to be a mobile phone number. "
    sys.exit()

string = 'at+cmgs='+"\""+number+"\""+'\r'
string = string.rstrip('\n')

#print string
Message = raw_input("Enter text:\n")

child = pexpect.spawn('pnatd');
child.send('at\r');
time.sleep(0.25);
child.send('at+cmgf=1\r');
time.sleep(0.25);
child.send(string);
child.send(Message);
child.send(chr(26));
child.send(chr(26));
child.sendeof();

Issues

'module' object has no attribute 'GPSDControl'

The Python script name shall not be 'location.py' otherwise the interpreter will fail with the following error message:

Traceback (most recent call last):
File "location.py", line 1, in <module>
import location
File "/home/user/location.py", line 25, in <module>
control = location.GPSDControl.get_default()
AttributeError: 'module' object has no attribute 'GPSDControl'

Position dependent event triggering on the Nokia N900

alternate text

Retrieve destination's coordinates

The program is first served with a destination address, the user input is realized as follows:

addr = raw_input('\nAddress: ') # Read destination address.

A sample input could be "Karl-Wilhelm-Strasse 4, Karlsruhe". The destination's coordinates can be retrieved by starting a Google Maps request.

# Encode query string into URL
url = 'http://maps.google.com/?q=' + urllib.quote(addr) + '&amp;output=js'
# Get location as XML file
xml = urllib.urlopen(url).read()

Google Maps responds with a XML-file, the following code extracts longitude and latitude to the variables latDest and longDest:

# Strip lat/long coordinates from XML
latDest, longDest = 0.0,0.0
center = xml[xml.find('{center')+9:xml.find('}',xml.find('{center'))]
center = center.replace('lat:', '').replace('lng:', '')
latDest, longDest = center.split(',')
latDest, longDest = float(latDest), float(longDest)

Given the example user input from above, variables latDest and longDest will contain the following coordinates:

  • latDest: 49.010149 # Destination latitude
  • longDest: 8.420162 # Destination longitude

The Python API googlemaps leads to the same result:

from googlemaps import GoogleMaps
gmaps = GoogleMaps(API_KEY) # Set API_KEY to your Google Maps API Key
address = 'Karl-Wilhelm-Strasse 4, Karlsruhe'
lat, lng = gmaps.address_to_latlng(address)

The API can only be used with a valid Google accout and a valid API key.

Get actual position

The actual position can be retrieved from the Nokia N900 GPS receiver GPS5030 (Texas Instruments). The receiver supports Assisted GPS (A-GPS) and can be controlled by liblocation. The library is availlable as C and Python implementation and provides two objects control and device that have to be initialized as follows:

control = location.GPSDControl.get_default()
device = location.GPSDevice()

GPSDControl can be used to start and stop the receiver. The position update interval can be set by method set_properties() and has to fit the form of movement. The following code snippet sets the interval to 60 s (suitable for pedestrians):

control.set_properties(preferred_interval=location.INTERVAL_DEFAULT)

GPSDevice provides information about the receiver status and the actual GPS data (the fix) as tuple (immutable list). This fix-tuple contains the following information:

  • time stamp
  • latitude and longitude of the actual position
  • height
  • velocity

After initialization of GPSDControl and GPSDevice, latitude and longitute can be accessed as follows:

latPosition = float(device.fix[4])  # Latitude of actual position
longPosition = float(device.fix[5]) # Longitude of actual position.

Great-circle distance (orthodromic distance)

alternate text

The great-circle distance or orthodromic distance is the shortest distance between two points on the surface of a sphere, measured along the surface of the sphere. In other words: the great-circle distance is the the shortest connection between two GPS coordinates.

By calculating the orthodromic distance, one can calculate the distance between the actual position (A) and the final destination (B). Longitude and latitude have to be converted into radian measure. The central angle between them, is given by the spherical law of cosines. The distance in meters can be calculated by mutliplying the central angle by the earth radius (approx. 6370 km).

def SphericalDistance(latPosition,longPosition):
  longDestRad = (longDest * (2 * pi / 360))
  latDestRad = (latDest * (2 * pi / 360))
  longPositionRad = (longPosition * (2 * pi / 360))
  latPositionRad = (latPosition * (2 * pi / 360))

  distance = sin(latDestRad) * sin(latPositionRad) + cos(latDestRad) * \
             cos(latPositionRad) * cos(abs(longPositionRad - longDestRad))
  if ((distance >= 1) or (distance <= -1)):
      distance = 0
  else:
      distance = acos(distance)
      distance = distance * 6370000 # Change this for other planets.
  return distance # orthodromic distance

Position dependent event triggering

Variable distance returned by method SphericalDistance() contains the air-line distance between the actual position and the final destination in meters. Comparing distance with a given minimal distance makes it possible to trigger one of the following events when distance is lower or equal to the minimal distance:

  • Play an audio file ("You will arrive in about 5 minutes").
  • Toggle one or more LEDs (at night).
  • Send SMS ("I will arrive in about 5 minutes").

The following code listing shows how the Nokia N900 can be forced to send a SMS.

def SendSMS():
  string = 'at+cmgs='+"\""+number+"\""+'\r'
  child = pexpect.spawn('pnatd');
  child.send('at\r');
  time.sleep(0.25);
  child.send('at+cmgf=1\r');
  time.sleep(0.25);
  child.send(string);
  child.send('Schatz mach das Essen warm!');
  child.send(chr(26));
  child.send(chr(26));
  child.sendeof();