*原创作者:nickchang(FB特约作者)

近期,朋友的电脑中毒了,杀毒软件警报如下。

Detection time(UTC time): 12/11/2015 11:12:39 AM Malware file path: file:_C:\Users\****\WuMorbSrkSs\ASAW2adgQ6k.oDhoel;
file:_C:\Users\****\WuMorbSrkSs\ASAW2adgQ6k.oDhoel->main/AUx.class;
file:_C:\Users\****\WuMorbSrkSs\ASAW2adgQ6k.oDhoel->main/Con.class;
file:_C:\Users\****\WuMorbSrkSs\ASAW2adgQ6k.oDhoel->main/cOn.class;
regkey:_HKCU@\SOFTWARE\MICROSOFT\WINDOWS\CURRENTVERSION\RUN\\5Nna53uK5a4;
runkey:_HKCU@\SOFTWARE\MICROSOFT\WINDOWS\CURRENTVERSION\RUN\\5Nna53uK5a4; 
Remediation action: Quarantine 
Action status: Succeeded

从杀毒软件的告警信息看,这个被隔离的文件的扩展名是oDhoel,但是它包含了几个.class文件。所以初步判断这个病毒应该是打包的jar文件。而jar 文件一般都是用java(javaw) –jar命令打开的。那我们就从日志上找找看最近一次什么时候执行了java/javaw。  

2015-12-08T10:58:38,%PROGRAMFILES%\MICROSOFT OFFICE\OFFICE14\WINWORD.EXE
2015-12-08T11:00:56,%PROGRAMFILES%\JAVA\JRE1.8.0_60\BIN\JAVAW.EXE
2015-12-08T11:00:57,%SYSTEM32%\XCOPY.EXE
2015-12-08T11:01:02.38,%SYSTEM32%\REG.EXE
2015-12-08T11:01:02.41,%SYSTEM32%\ATTRIB.EXE
2015-12-08T11:01:02.48,%OSDRIVE%\USERS\****\APPDATA\ROAMING\ORACLE\BIN\JAVAW.EXE

可以看见最近一次执行javaw是4天前,虽然日志没有记录其具体执行参数,但是随后的行为: “xcopy, reg, attrib and javaw”具有adwind类病毒的特征。特别值得注意的是第二个javaw是在用户目录运行的。Adwind类病毒会先把JRE环境复制到用户目录中,修改注册表开机自启动项,并且把自己的文件属性设置为隐藏,然后再用复制到用户目录中的javaw执行下载的其他jar文件。Hybrid-analysis上有些java病毒具有非常相似的行为,例子如下:

1. https://www.hybrid-analysis.com/sample/eff25d0449480c132e4427ad9a19da8680419dfe4bc1b21f090eab56c320d7c0?environmentId=4
2. https://www.hybrid-analysis.com/sample/ccb79d1030b291b4adbe02077247a6dba6773a61848a0c5ee0ed8c50314e1ea9?environmentId=1
3. https://www.hybrid-analysis.com/sample/1da960759932ff0158f579573e2544aaa84331f5bee2152deb18010a01534668?environmentId=1

1、第一阶段

被隔离的ASAW2adgQ6k.oDhoel基本属性如下:

·大小: 115.4kb

· Md5: 3836416d7099c06508f2bd67ee3a366c

· Virustotal 检测率: 15/55 (2015年12月21日) ,国内大多数av比如江明,瑞星都没有查杀。而趋势,麦卡费,赛门铁克都可查杀。还有貌似360已经不在virustotal上面了?

我们知道,一个.jar文件其实就是一个zip压缩包,里面包含一些java二进制文件 (.class) 和配置文件。那我先试着在winxp上把这些class文件解压出来。奇怪的是,我能看见文件列表,可是解压总是失败。

仔细一看,原来一些.class文件是重名的,只不过名字字母大小写不一样,比如NUL.class和NuL.class。这当然会在大小写不敏感的操作系统比如windows下会造成某些问题。没关系,用linux好了。在ubuntu下成功解开。

· 载荷(payload)文件: 红圈里面的是载荷文件。该文件大小是107kb,几乎占个整个.jar包大小的95% 。这个文件在一个6层的随机目录下面。后来我们发现这个载荷文件其实是另一个.jar文件。但是一开始这个文件是加密的,所以没法直接读取其内容。

· 配置文件: 绿圈里面的Config.pl 是一个配置文件, 同样也是加密的。这个配置文件主要提供了一个用于解密载荷文件的密钥。 

· 若干 .class文件 : main 目录下包含一些.class文件。它们的主要功能是先解密配置文件,读取密钥,再用该密钥解密载荷文件。最后载入载荷文件执行。

· Manifest文件: jar的资源配置文件,用于定位程序入口。

下一步,我用 Krakatau 把这些 .class 文件反编译成 .java 文件。但是从这些.java文件可以看出该病毒作者使用了各种代码混淆技术,举例如下:

1. 把java 关键字当作变量名和函数名,比如下图的true, short, goto等。

这样会给分析带来两个问题,1反编译出来的java代码比较难读懂。2如果我们想再编译并且debug,编译器会报错。为了解决这些问题,我先把.class文件中的所有关键字全部替换掉,然后再用 Krakatau反编译。

find ./ -type f -exec sed -i -e 's/class/ssalc/g' {} \;
find ./ -type f -exec sed -i -e 's/enum/mune/g' {} \;
find ./ -type f -exec sed -i -e 's/short/trohs/g' {} \;
find ./ -type f -exec sed -i -e 's/true/erut/g' {} \;
find ./ -type f -exec sed -i -e 's/void/diov/g' {} \;
find ./ -type f -exec sed -i -e 's/goto/otog/g' {} \;
find ./ -type f -exec sed -i -e 's/case/esac/g' {} \;
find ./ -type f -exec sed -i -e 's/super/repus/g' {} \;

2. 代码中的所有字符串都是加密的。

没法读取字符串就没法理解作者的意图,所以必须先对这些字符串解密。很容易就在代码中找到了两个解密函数。但是用于解密的密钥是会变化的。事实上,调用解密函数的类名称和函数名称就是解密的密钥。比如,当类nUI的构造函数调用解密函数解密某些字符串时,解密的密钥就是main.nUL.<clinit>。而当类auX的run()函数调用解密函数时,密钥就变成了main.auX.run。这个是通过读取栈,getstacktrace来实现的。

当然对于分析来说,一个比较方便的解密方法就是设置好断点,然后把程序跑起来,用debug功能来读取解密过的字符串。然而这样也会带来一个问题:在第一步中,我替换掉了一些函数名,比如从enum改到mune。这样的修改同样也会改变解密密钥,从而使解密结果不准确。 针对这个问题,我做出了一些相应的修改。最终把所有的字符串逆回明文。

3. 重复调用一些无意义的函数

这个比较简单,找到它们然后注释掉就可以了。

4. 定义两个成员函数,这两个成员函数有相同的函数名,相同类型,相同数量的参数,但是不同的返回类型。这个像overload但不是overload,在java语法里面是不允许的,编译的时候会报错。

在这种情况下,我只好重命名这两个函数. 比如 mune1(byte[]) 和 mune2(byte[])。

Debug以后,我对这个jar文件有了大致的理解:

1. 它会先解密嵌在 .class文件里的字符串. 这些字符串有的是配置文件config.pl的相对路径,有的是用来解密配置文件的密钥。     

2. 用密钥 “VY999sisosouuqjqhyysuhahyujssddqsad22rhggdsfsdfs” 来解密config.pl, 解密算法是典型的异或算法。 解密后的内容将以 XML格式载入。  

3. 配置文件 config.pl 包含两部分信息, 一个是 “password”, 另一个是 “server”。 它们的值分别为"CnqPOFxY6l" 和载荷文件的相对路径。

4. 它把 “kevthehermitGAYGAYGAYD” (这句话看起来像是骂人的,本文最后将会解释) 和 “CnqPOFxY6l” 结合起来形成一个新的密钥, 用来解密载荷文件。 这一次,解密算法是 RC6, 因为子密钥生成代码有显著的RC6的特征,对比如下图。

5. 解密完成以后,载荷文件将会被作为jar文件载入 (JarInputStream)并且执行。

到目前为止,我们知道了第一阶段的目的仅仅是解密并且调入包含的另一个.jar文件。

出于静态分析的目的,我修改了一些代码,把解密后的载荷存在本地文件系统。

2、第二阶段

载荷的基本属性如下: 

·大小: 105.1kb
·Md5: 5c9409ad20fc16aea2c7ae80ed981cf5
·Virustotal 检测率: 19/54 (21/Dec/2015) ,这次,卡巴、趋势、赛门铁克也不能查杀。

jar的文件结构如下:

├── [       4096]  META-INF
│   └── [        139]  MANIFEST.MF
├── [       4096]  module
│   └── [        674]  Server.class
├── [       4096]  org
│   ├── [       4096]  jsocket
│   │   ├── [       4096]  a
│   │   │   ├── [       2403]  iiIiiIIIii.class
│   │   │   ├── [       1837]  iiIIiIIIIi.class
│   │   │   ├── [       2135]  iIiIIIiIiI.class
│   │   │   ├── [       2182]  iIIiiiiIII.class
│   │   │   ├── [        552]  iIIiIiiIiI.class
│   │   │   ├── [       1052]  iIIIiiIiiI.class
│   │   │   ├── [        988]  IiiiIIIiIi.class
│   │   │   ├── [       6230]  IiiIIiiIIi.class
│   │   │   └── [       3607]  IiIiIiiIiI.class
│   │   ├── [       4096]  b
│   │   │   ├── [       2647]  iiiiIiIIii.class
│   │   │   ├── [       2558]  iiIiiIIIii.class
│   │   │   ├── [        564]  iiIIiIIIIi.class
│   │   │   ├── [       2593]  iIiIIIiIiI.class
│   │   │   ├── [       2145]  iIIiiiiIII.class
│   │   │   ├── [       1404]  iIIiIiiIiI.class
│   │   │   ├── [       1882]  iIIiIiIiII.class
│   │   │   ├── [       1101]  iIIIiiIiiI.class
│   │   │   ├── [       2306]  iIIIIIiIii.class
│   │   │   ├── [       1175]  IiiiIIIiIi.class
│   │   │   ├── [       2960]  IiiIIiiIIi.class
│   │   │   ├── [       1501]  IiIiIiiIiI.class
│   │   │   ├── [       3286]  IiIiIIiiII.class
│   │   │   └── [       2481]  IIiiiIiiii.class
│   │   ├── [       4096]  c
│   │   │   ├── [       4379]  iiIiiIIIii.class
│   │   │   ├── [       1492]  IiiIIiiIIi.class
│   │   │   └── [       2745]  IiIiIiiIiI.class
│   │   ├── [       4096]  d
│   │   │   ├── [       3753]  iiIiiIIIii.class
│   │   │   ├── [       2386]  iiIIiIIIIi.class
│   │   │   ├── [       2584]  iIiIIIiIiI.class
│   │   │   ├── [       1196]  iIIiiiiIII.class
│   │   │   ├── [       3255]  iIIiIiiIiI.class
│   │   │   ├── [       1191]  iIIiIiIiII.class
│   │   │   ├── [       3803]  iIIIiiIiiI.class
│   │   │   ├── [       3219]  IiiiIIIiIi.class
│   │   │   ├── [        449]  IiiIIiiIIi.class
│   │   │   └── [       1430]  IiIiIiiIiI.class
│   │   ├── [       4096]  main
│   │   │   └── [       9473]  Start.class
│   │   └── [       4096]  resources
│   │       ├── [        355]  config.json
│   │       └── [       2970]  key.dll
│   └── [       4096]  json
│       ├── [       4387]  CDL.class
│       ├── [      13755]  JSONArray.class
│       ├── [        754]  JSONException.class
│       ├── [       6584]  JSONML.class
│       ├── [        196]  JSONObject$1.class
│       ├── [      24447]  JSONObject.class
│       ├── [        881]  JSONObject$Null.class
│       ├── [        156]  JSONString.class
│       ├── [        604]  JSONStringer.class
│       ├── [       5916]  JSONTokener.class
│       ├── [       4109]  JSONWriter.class
│       ├── [       1757]  Property.class
│       ├── [       7554]  XML.class
│       └── [       4715]  XMLTokener.class
└── [       4096]  tools
    ├── [       1868]  Base64.class
    ├── [       1529]  Compress.class
    ├── [       1300]  Copy.class
    ├── [       3564]  Helper.class
    ├── [       1980]  Reader.class
    ├── [       1643]  RunJarFile.class
    └── [       1490]  WscriptProcess.class

位于 /org/jsocket/resources目录下有一个配置文件 config.json。这是一个明文json格式配置文件。

{"NETWORK":[{"PORT":1960,"DNS":"millzjsoctrinwi80gm.duckdns.org"}],"INSTALL":true,"PLUGIN_FOLDER":"OMewSKDQMyT","JRE_FOLDER":"fbAP1V","JAR_FOLDER":"WuMorbSrkSs","JAR_EXTENSION":"oDhoel","DELAY_INSTALL":2,"NICKNAME":"GODTHEFATHER","VMWARE":true,"PLUGIN_EXTENSION":"wmQYM","JAR_NAME":"ASAW2adgQ6k","JAR_REGISTRY":"5Nna53uK5a4","DELAY_CONNECT":2,"VBOX":true}

注意network下的DNS值,"millzjsoctrinwi80gm.duckdns.org”。 duckdns.org提供免费的动态子域名服务。 任何人都可以在duckdns.org上面申请子域名,并且用一个脚本动态上传修改dns记录. 这个域名很可能就是肉鸡服务器。目前这个域名指向 89.163.154.140,可是已经连不上了。

从Threatcrowd 上面看, 这个域名(millzjsoctrinwi80gm.duckdns.org) 也被其他一些java病毒当作肉鸡服务器。

其他一些配置信息,比如 “plugin_folder”, “jar_folder” 和 “jre_folder”定义了jre环境和病毒的安装目录。 “delay_install” 和 “delay_connect”定义了潜伏的时间。 “vbox” 和 “vmware” 定义了是否侦测虚拟环境。所有这些配置信息都是明文的,所以,很可能这是一个商业化的后门?

继续反编译.class文件,发现所有内嵌的字符串也都是加密的。解密方法和第一阶段完全相同:用调用函数的函数名和类名作为解密密钥。最终我把所有的字符串还原成了明文。

结合代码,发现很明显这是个远控后门程序。

首先,它从config.json里面读取基本配置信息,并放入 settings。  

如果配置要求的话,它会检查当前运行环境是否是虚拟机(只检测vmware和virtualbox)。检测基于是否有一些特殊的目录,“virualbox guest additions” 和 “VMware tools”。如果发现是虚拟环境,它会停止运行,立即退出。主要目的是防止被动态分析。

它会继续监测目标电脑的软件硬件信息ip地址等,并且存放于settings。

Java程序可以跨平台执行,所以有可能运行在不同的操作系统上。因此该病毒会检查受害者的操作系统。针对windows, linux, mac,它都有相应的代码。

该病毒会潜伏一段时间以后,开始安装。

对于windows平台,它会用 “xcopy” 把 jre 环境复制到用户目录下。

xcopy "%PROGRAMFILES%\Java\jre1.8.0_25" "C:\Users\%USERNAME%\AppData\Roaming\Oracle\" /e


对于流行的杀毒软件,它会修改注册表进行镜像劫持。在Image File Execution Options (IFEO)下面新建一个debugger 项,重定向为svchost.exe。

用“attrib”把自己文件的属性设置为隐藏。

attrib +h "%USERPROFILE%\qPL63CO8myp\*.*

用https连接配置文件中指定的肉鸡服务器。

SSL的证书,密钥信息是从key.dll里面读取的。这个文件包含在jar包里面。

它还会登陆maxmind 并且取出感染主机的地理位置信息。

继续下载更多的jar文件,把它们存放在一个临时文件里,并且伪装成png文件。然后载入这些下载的文件。

用“wmic” 命令检测被感染主机是否有摄像头。

如果是以 admin 权限运行的, 它会把自己加到 “current version/ run” 键里面,以实现开机自启动。如果在linux下面它会配置autostart。

在某些时候,它会生成一个vb脚本删除自己,包括文件,目录,和注册表信息。

3、后记

根据这些信息,搜索后发现其实这个后门叫做jsocket, 是 “alienspy” 和 “adwind”的新版本。 它是个商业化的后门,网址是 https://jsocket.org。 售价大约是25美刀一个月,或者300美刀一年。看起来像是一个合法的后门,可是网站却宣称它可以杀掉或者绕过某些杀毒软件。

Fidelissecurity 对该后门的免费版本做过一些研究并且在上个月写过一篇报告[2],而且统计了被感染主机的地理位置,如图所示,重灾区在美国。当然在欧洲和中国也有一定程度的感染。

图来自 [2]

而肉鸡服务器主要位于美国、俄罗斯和尼日利亚。中国几乎没有。

图来自[2]

笑点在最后, 安全专家Kevin Breen曾经在github上开源了一个解密Alienspy病毒配置文件的程序[3]。他的github 名字是 “Kevthehermit”。而前文说过Alienspy是jSocket的早期版本,病毒作者可能是同一个人。

还记得吗,在第一阶段分析的时候,解密载荷文件的密钥的开头是“kevthehermitGAYGAYGAYD”。 骂别人是gay, 看来该病毒的作者真的恨死Keven Breen了。

4、文献

[1] jsocket home page https://jsocket.org/

[2] Fidlis cysbersecurity,  Ratcheting Down on JSocket: A PC and Android,Threat https://www.fidelissecurity.com/sites/default/files/FTA_1019_Ratcheting_Down_on_JSocket_A_PC_and_Android_Threat_FINAL.pdf

[3] Alienspy decoders https://github.com/kevthehermit/RATDecoders/blob/master/AlienSpy.py

*原创作者:nickchang,本文属FreeBuf原创奖励计划文章,未经许可禁止转载。

源链接

Hacking more

...