Tuesday, December 10, 2013

DD-WRT, Afraid.org, and truncating base64 hashes

I've noticed that since 2010 that DD-WRT has had problems with correctly implementing Dynamic DNS authentication with Afraid.org.   You enter your username and password, but the authentication fails.   To get around this issue, you need to follow this workaround: http://www.dd-wrt.com/phpBB2/viewtopic.php?p=781615

I decided to poke into the DD-WRT source code to understand why this nuisance continues to persist to this day.  What did I find?  Inside router/httpd/validate.c, DD-WRT makes a call to http://freedns.afraid.org/api/?action=getdyndns&sha=[SHA] where [SHA] represents the SHA1 function of "username|password" (as an example of how this authentication process works, see https://github.com/atdt/afraid/blob/master/afraid/__init__.py#L94)).  The response, assuming you aren't using the Curl command-line, comes in this form:

DYNDNS_HOST|IP_ADDRESS|http://freedns.afraid.org/dynamic/update.php?HASH_VALUE

Afraid.org needs this hash value when DD-WRT reports its DNS location. The problem is that DD-WRT only assumes there are only 36 characters in the hash. The offending section is here: https://github.com/mirror/dd-wrt/blob/master/src/router/httpd/validate/webs.c#L3438

This pull request should fix this issue:

https://github.com/mirror/dd-wrt/pull/5/files

How did I verify?  Well, I saved the response from making an authenticated call to Afraid.org:

>>> open("/tmp/hash", "w").write(urllib.urlopen("http://freedns.afraid.org/api/?action=getdyndns&sha=xxxx").read())

Then I created and compiled this source code to verify:
#include <stdio.h>
#include <malloc.h> char *main() { int i; FILE *in = fopen("hash", "rb"); while (getc(in) != '?' && feof(in) == 0) ; i = 0; char *hash = malloc(64); if (feof(in)) { free(hash); return NULL; } for (i = 0; i < 63 && feof(in) == 0; i++) { hash[i] = getc(in); if (hash[i] == EOF) break; } fclose(in); hash[i] = 0; printf("%s", hash); return hash; }
Note in the bolded text that we have to break out of the loop if the character is EOF, since feof() will only exit after one extra loop.  We could also set the string terminator to be i-1 too (see Stack Overflow article about the challenges feof() presents)

Buffalo WZR-600DHP Firmware Fun

I got this Buffalo WZR-600DHP router thinking that it was a worthy successor to the WRT64GL router, which radio stopped working on me over the weekend. The Buffalo router also had DD-WRT installed, so I thought it meant one less step to install. Turns out to have been a 2-hour pain to configure.

1. The default username/password didn't even work, trying every single combination of admin/password, root/password, buffalo/dd-wrt123, etc. that was possible. I had to hold down the Reset button for 30 seconds to reset everything back to a default state.  (If you hold down shorter than this period, I often had issues resetting the firmware).

2. Soon after tweaking the IP address to something other than the default IP address of 192.168.3.1 and rebooting, the Buffalo router started to create 302 redirects on its web interface to 192.168.11.1. Sure you could use the router so long as you never needed to touch the admin interface. Was there something in the firmware that has some hard-coded setting? Or is it running a DD-WRT version that makes assumptions about its IP address?

 3. The solution for both items was simply to replace Buffalo's stock DD-WRT firmware with the latest one available. Make sure to "reset to default settings" when uploading the new firmware to clear out the old stuff setup by Buffalo.  Buffalo's stock firmware also prevents you from enabling SSH into the router, which makes even harder given problems with #2 to troubleshoot.

4. Don't close any windows until the firmware is flashed.

5. Connect to the router at 192.168.1.1. If you're using DynDNS and setting up with afraid.org, keep in mind that the hostname specified needs to be hostname,hash value (i.e. xxxx.mooo.com,abcde). There's still a bug in DD-WRT with the hash being truncated (http://www.dd-wrt.com/phpBB2/viewtopic.php?p=781615). You can go to http://freedns.afraid.org/dynamic/ to copy/paste the right hash value from the direct URL (i.e. http://freedns.afraid.org/dynamic/update.php?HASHVALUEHERE)

Thursday, December 5, 2013

Running Django's unit tests

1. Create a settngs.py file (or copy from django/conf/project_template/project_name/settings.py).

2. Make sure the databases are setup:
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'test',
        'USER': 'test',
        'PASSWORD': 'test'
    }
}

3. DJANGO_SETTINGS_MODULE=settings PYTHONPATH=. tests/runtests.py

If you get:
from django.utils._os import upath
ImportError: cannot import name upath

Chances are your DJANGO_SETTINGS_MODULE and PYTHONPATH are set.

Sunday, December 1, 2013

Samsung DVR firmware

It turns out that the Samsung DVR firmware is basically a gzip'ed package of an embedded lighttpd Linux kernel built for the ARM processor.   If you're curious about the code that it runs, you can mount the image and inspect.  There's no source code included, but Samsung should probably open source it given there are so many inherent securrity vulnerabilities.

1. Download the firmware http://www.samsungsv.com/Support/DVRFirmwareUpdate

2. Unzip the zip file.

3. Gzip decompress the .img file.

4. If you have Linux, you can mount the jffs2 file.  You'll need to install the packages to mount JFFS2 images.

sudo apt-get install mtd-tools
sudo modprobe -v mtd
sudo modprobe -v jffs2
sudo modprobe -v mtdram total_size=256000 erase_size=256
sudo modprobe -v mtdchar
sudo modprobe -v mtdblock

5. Create a mount directory for the image (i.e. mkdir /mt/tst)

6. Create the JFFS2 image by writing to the /dev/mtdblock0 device:

sudo dd if=hi3520_data.jffs2 of=/dev/mtdblock0

7. Mount the device:
mount -t jffs2 /dev/mtdblock0  /mnt/tst


8. Much of the web server code resides in the /root/www directory.

Friday, November 29, 2013

Seriously Samsung? Home surveillance cameras that exposes usernames and passwords to login.

SDE-4001N
Samsung's home surveillance IP cameras (including the SDE and SDR models) must be controlled with Silverlight Internet Explorer plugins, so I decided over the Thanksgiving holiday to see whether I could study the network traffic and understand how these devices worked.  While studying some of the endpoints, I came upon this security bulletin published 3 months ago.

http://www.securityfocus.com/archive/107/528120/30/0/threaded
Samsung provides a wide range of DVR products, all working with nearly
the same firmware. The firmware it's a Linux embedded system that
expose a web interface through the lighttpd webserver and CGI pages.

The authenticated session is tracked using two cookies, called DATA1
and DATA2, containing respectively the base64 encoded username and
password. So, the first advise for the developers is to don't put the
user credentials into the cookies!

Anyway, the critical vulnerability is that in most of the CGI, the
session check is made in a wrong way, that allows to access protected
pages simply putting an arbitrary cookie into the HTTP request. Yes,
that's all.

This vulnerability allows remote unauthenticated users to:

- Get/set/delete username/password of local users (/cgi-bin/setup_user)

- Get/set DVR/Camera general configuration

- Get info about the device/storage

- Get/set the NTP server

- Get/set many other settings
It turns out that the major Samsung home surveillance DVR have this security flaw. Essentially all the username and passwords are unhashed and can be retrieved by using an arbitary cookie.   The source code that retrieves this info is included here:

http://www.andreafabrizi.it/download.php?file=samsung_dvr.py

If you want to verify whether your device is vulnerable, check out :

http://ismysamsungdvrhacked.appspot.com/ (GitHub code here)

Hoping to find that Samsung fixed the issue, I went to http://www.samsungsv.com/Support/DVRFirmwareUpdate and discovered that the firmware versions have yet to be updated.

Why does this issue matter? For one, Samsung provides a Dynamic DNS service at samsungipolis.com (i.e. http://samsungipolis.com/home1) that enables customers to have their systems devices report the IP location.  This IP address is stored by Samsung and provides a redirect to the owner's hosted cameras.

$ curl http://www.samsungipolis.com/testing
<body>

    <meta http-equiv="refresh" content="0;url=http://98.17.152.5:80"/>


</body>

In other words, all you have to do is find a name that's using Samsung's Dynamic DNS service, point the Python script at this IP, and assuming the owner has enabled remote web interface access for the user account, you can login to their service (and possibly gain admin access to make any changes).  You obviously have to use Internet Explorer to test, since the plug-ins were built in Silverlight.  (If you get a blank white screen, you're probably using a non-IE browser.)

I've sent a note to their customer support and tweeted to them about this unpatched security flaw (now going on 3 months)  If you are running one of these systems, you're best option is to disable the web interface until this flaw is patched.

Update (12/1/2013): Samsung's web site at samsungsv.com does not have the updated firmware images, but you can sign up for a free account at http://developer.samsungtechwin.com and get access to newer versions of the firmware.

For the SDE-5001 DVR device, for instance, the latest version is v1.05.  However, this last update was made on 01/2013, about a year ago, which suggests that the patch has yet to be applied.  Also, by mounting the flash image, we can also see that the binary for the cgi_login program which has this security hole does not appear to have changed since the v1.02 version.   I also checked the lighttpd configuration and did not see any differences in the files. In other words, the security flaw still seems to exist.

Friday, November 22, 2013

Auto populating PDF form data

How easy is it to auto-populate form data in a PDF? Well, it turns out there's a tool called PDFTk (described in http://www.mactech.com/articles/mactech/Vol.20/20.11/FillOnlinePDFFormsUsingHTML/index.html) that provides the ability to dump the interactive fields into a FDF and load it back into the PDF. The download links don't appear on the main site, but you can go to this link to grab the latest versions.

Ubuntu v12.04 has PDFTk version 1.4, which isn't the latest version. To compile the latest, download the source and apt-get install gcj, which is a Java to native bytecode compiler. Link the Makefile.Debian to Makefile, and run make. At the end, you should have a working pdftk binary!

PDFTk seems to provide a wrapper over the iText PDF library. There is one issue whereby if an owner password is set, you are prevented from opening it (http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=531529) The workaround is either to patch the source accordingly (see https://github.com/onehub/pdftk/blob/master/debian/patches/drm_fix) or use qpdf --decrypt to remove the encryption before using pdftk with it.

Friday, November 15, 2013

Mac Excel 2011 doesn't support UTF-8?

It turns out the workaround is to install TextWrangler and export documents via UTF-8..

http://legacy.x3ro.de/excel-mac-2011-utf8/