1、前言
在2016年左右研究人员发现一个与东南亚和中国南海问题的APT攻击,该APT攻击利用MS Offcie系列漏洞通过钓鱼邮件的形式欺骗受害者点击木马。以美国在内的各国政府和公司为目标发送了大量的恶意代码样本 。
其中木马上线的方式是利用了白名单网站的方式。攻击者将控制端的IP地址加密后发表文章到开放有博客、论坛的合法网站上。利用这类网站的RSS订阅服务作为受控主机访问的地址,
受害者的主机会读取RSS订阅中留存有攻击者C2加密信息的帖子地址将攻击者的C2信息解密后建立网络连接。
这种白名单网站利用的上线方式非常巧妙,可以有效地混淆分析者的视线。报告里将这个用来攻击的恶意软件称为BADNEWS。
2、BADNEWS说明
BADNEWS能够执行任意命令,截图,服务端更新,下载文件、执行文件以及列目录操作。利用DLL加载的方式(dll side-loading)以实现免杀,如果目标有价值将会进行第二阶段恶意软件的部署。
DLL Side-Loading:通过加载DLL注入到一个合法签名JAVA程序中,释放一个二进制文件和一个加密VBScript脚本,在VBScript脚本运行的同时生成以下三个文件:
microscmgmt.exe
MSVCR71.dll
jli.dll
其中MicroScMgmt.exe用来加载DLL注入合法进程【javarmi.exe】的恶意程序,通过调用合法的【MSVCR71.dll】和恶意【jli.dll】达到执行恶意软件目的。
【MicroScMgmt.exe】一旦执行,将加载【jli.dll】,最终调用DLL组件中的jli_wildcardexpandclasspath_0。执行自身恶意代码。
加载DLL注入后将产生两个线程,一个线程负责键盘记录,另一个线程负责获取本地和映射硬盘驱动器文档。
长期驻留:通过在注册表中生成以下注册表项达到在受害者系统长期驻留的目的:
HKEY_CURRENT_USERSOFTWAREMicrosoftWindowsCurrentVersionRun
C&C通信 :BADNEWS 中包含有获取远程C&C服务器指令的固定通信代码和方式,这些方式包括RSS订阅、GitHub ,论坛、博客和动态 DNS主机。
C&C运行机制:BADNEWS与C&C服务器之间建立连接之后,将会向C&C
3、上线代码加密与解密
- 加密原理
恶意软件会从博客或RSS订阅的地址从网页中搜索并提取“ {{”内的字段以 获取C&C信息,“{{”之后的内容是以相同方式加密的C&C地址信息。
- 解密方法
BADNEWS早期的C2上线IP加密方式都是Base64加密,通过把每字节循环右移3bit,然后以0×23进行异或操作,之后再以16进制内容进行Base64加密。新的BADNEWS变种还增加了一层Blowfish算法的加密。
通过对http://feeds.rapidfeeds.com/88604/的解密熟悉了一下密码解密的方法。
以下是对数据进行解密的一个Python脚本:badnews_decoder.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import requests
import base64
import binascii
import re
from Crypto.Cipher import Blowfish
from struct import pack
rol = lambda val, r_bits, max_bits: (val << r_bits%max_bits) & (2**max_bits-1) | ((val & (2**max_bits-1)) >> (max_bits-(r_bits%max_bits)))
ror = lambda val, r_bits, max_bits: ((val & (2**max_bits-1)) >> r_bits%max_bits) | (val << (max_bits-(r_bits%max_bits)) & (2**max_bits-1))
def unhexData(d): # 十六进制解密
if len(d) % 2:
d = d.zfill(len(d)+1)
return ord(binascii.unhexlify(d)) # 十六进制解密,然后将单个字符以ascii码的方式返回
def decodeDecrypt(data): # 传参 c945adaa8a656b8fc9c9a5aec56fe58a248ac96c650b848423
decdata = ''
for x in range(len(data)):
x = x*2
if x < len(data):
c = unhexData(data[x]) # 十六进制转ASCII码
add_num = unhexData(data[x+1])
c = c << 4 # 左移动4位
c = (c + add_num) & 0xff
c ^= 0x23 # 异或0x23
c = rol(c, 3, 8) # 运算
decdata += chr(c) # 恢复为Base64编码
data2 = base64.b64decode(decdata)
key = binascii.unhexlify("F0E1D2C3B4A5968778695A4B3C2D1E0F0011223344556677")
cipher = Blowfish.new(key, Blowfish.MODE_ECB) # Blowfish算法解密
dec = cipher.decrypt(data2) # 解密后的C2地址
return dec
# 加密C2的Url列表
urls = [
"http://feeds.rapidfeeds.com/88604"
]
for d in urls:
r = requests.get(d)
body = r.text
r = re.search("[+s*([a-zA-Z0-9=]+)]+", body) # 取值得到 [[[Yzk0NWFkYWE4YTY1NmI4ZmM5YzlhNWFlYzU2ZmU1OGEyNDhhYzk2YzY1MGI4NDg0MjM=]]]]
if r:
data = base64.b64decode(r.group(0)) # Base64解密得到c945adaa8a656b8fc9c9a5aec56fe58a248ac96c650b848423
print("[{}] Decrypted C2: {}".format(d, decodeDecrypt(data).split("x00")[0])) # 输出解密后的IP地址
运行后的结果:
4、IOCs
- 恶意Word文档SHA256哈希
a67220bcf289af6a99a9760c05d197d09502c2119f62762f78523aa7cbc96ef1
07d5509988b1aa6f8d5203bc4b75e6d7be6acf5055831cc961a51d3e921f96bd
fd8394b2ff9cd00380dc2b5a870e15183f1dc3bd82ca6ee58f055b44074c7fd4
b8abf94017b159f8c1f0746dca24b4eeaf7e27d2ffa83ca053a87deb7560a571
d486ed118a425d902044fb7a84267e92b49169c24051ee9de41327ee5e6ac7c2
- BADNEWS SHA256哈希
ab4f86a3144642346a3a40e500ace71badc06a962758522ca13801b40e9e7f4a
290ac98de80154705794e96d0c6d657c948b7dff7abf25ea817585e4c923adb2
- C2服务器
185.203.118[.]115
94.156.35[.]204
- Dead Drop解析器
hxxp://feed43[.]com/8166706728852850.xml
hxxp://feed43[.]com/3210021137734622.xml
hxxp://www.webrss[.]com/createfeed.php?feedid=49966
hxxp://feeds.rapidfeeds[.]com/88604/
4、参考
【翻译稿件】揭秘Patchwork APT攻击 :一个与中国南海和东南亚问题相关的网络攻击组织