本文写于2015年,发表于ThoughtWorks。

这几天我在看杂志的时候看到一句话:所谓真相就是你愿意接受的东西,哪怕它并不存在。就是简单的一句话,但是我觉得对我的帮助很大的,因为这几天我偶尔在想如何清除或者不留下服务器的访问痕迹。

有经验的安全的朋友,都知道在干了事后,要清楚痕迹,例如清除history,干掉/var/log下的东西,经验稍微丰富点点,会更加谨慎的只干掉自己操作相关的信息,以避免干掉过多的信息而引起对方管理员的发现。

然而,稍微有点经验的管理员,通常也会有一定防备,例如在某个隐藏的角落添加:

1
2
3
4
5
HISTFILESIZE=4000
HISTSIZE=4000
HISTTIMEFORMAT='%F %T'
export HISTTIMEFORMAT
省略部分代码

再在启动的时候载入到环境变量中,就变成管理员守株待兔了,于是我们似乎可以换一个角度来想:系统管理员凭什么相信他的服务器是安全的?

假如管理员相信他的服务器是安全的,来自显示器上显示的预警信息,只要预警信息没有出现,则说明服务器是安全的,那么如果服务器本身是不安全的,但是预警却没有提示他,这时候他依旧相信他的服务器是安全的,实际服务器确实不安全的。

那么我们只需要让预警永远不报警,则至少在管理员的眼中,他的服务器永远是安全的。因为,真相是相对的。

在真实的情况中,即使是开发人员,在对系统进行检查的时候,不外乎执行top,ps,netstat,iostat几个命令检查有无异常进程或者有无高资源占用的情况,稍微高级点的会使用iftop,iperf来进行评估。

这时候我们可以脑洞大开,假设作为一个攻击者,攻击的再彻底一点,把整个服务器的关键命令全部替换了,比如ps,top,全部替换了,替换成被我们自己修改过的ps和top,这样的好处在于可以把我们自己的进程隐藏起来,无论管理员怎么ps,看着服务器始终是大好河山一片绿,而实际是众多的进程正在他的眼皮底下跑的正嗨。

想到这,于是我去linux源码里面把top的源码抓了出来,然后进行修改后,主要就是在执行top的时候,把自己的进程给隐藏掉,不出现在top的界面里面,修改方法也很简单:

直接暴力的编辑top.c,找到如下图所示读取进程的地方,然后只要是自己的进程,直接跳过,这样屏幕上将不会出现自己的进程:

image

然后再将上面的代码重新gcc编译一把,发现结果可行。

In file included from top.c:56:
top.h:193: 警告:填补结构以对齐‘head’

嗯,虽然有警告,结果还是过了,可以看到我们自己编译出的top程序,两个字:帅气!

image

然后测试一下,我们使用系统的top命令,可以明显的看到,有一个java程序(我特意开的一个耗资源的java),占据着大量的资源:

image

然后我们再测试一下我们自己编译的top程序:

image

发现在整个进程里面,根本就没有java这个程序,帅气的直接给跳过了。再狠一点,可以将系统内部的关键命令全部替换,这样的管理员就是求佛都不会发现系统异常的。。。

这里还有一点不足之处在于,甚至就是ps也是如此:

image

通过读top.c的源码可以发现,是直接读取/proc文件夹,而文件夹是用来存放系统的全部内存数据的,所以如果能力强点的管理员直接去看/proc,还是能发现端倪。

接下来问题来了,如何将替换后的命令上传给服务器?方法众多,现在介绍一种比较常用的,反射型获取webshell:

所谓反射型是指:我在对方的服务器上放了一个木马,只要有人触发了他,那么立即会在指定的服务器反弹出一个webshell,下面是活生生的例子:

1.首先我在一个公网服务器上使用nc监听一个8888的端口,用来接受将要攻击的服务器的web shell

image

2.然后触发将要攻击的服务器上的木马,就是下图的1.php文件

image

该文件就是一个经过base64的一个perl的socket文件

3.在我们的公网服务器上立马可用看到,反射出了一个shell:这是一个可以使用的shell:

image

当我们看到一台服务器是正常运行的,其实不一定是正常的,适当的备份关键命令进行md5,是很重要的。。。。


扫码手机观看或分享: