介绍
严格来说,生成式人工智能已经存在了近十年,但该技术最近的繁荣激发了人们对其可能应用于信息安全社区面临的挑战的兴趣。找到这些挑战需要搜索一个非常大的大海捞针,其中包含每天充斥网络的全新二进制文件、文档、域和其他工件。
在这篇博文中,我们深入探讨了 Check Point 持续使用这种模型来排除大海捞针,并定期阻止滥用 DNS 协议与 C&C 服务器通信的恶意活动。我们重点关注 CoinLoader 等此类活动,并对其基础设施进行了布局,并对其 DNS 隧道功能进行了深入的技术分析。
DNS 隧道速成课程
什么是 DNS?
域名服务器 (DNS) 协议可以被视为“互联网的电话簿”。wikipedia.org当您在 Web 浏览器的地址栏中输入网站地址(假设为 )并按 Enter 键时,您的 Web 浏览器会向其最喜欢的 DNS 服务器发送 DNS 请求,询问该域对应的 IP 地址。此默认 DNS 服务器的 IP 地址由用户的网络提供商提供或由用户手动指定。
SYN在底层,一个典型的 DNS 查询建立在 UDP 协议之上(为了唤起你的记忆,而 TCP 使用s 和 s 来处理“我的对等点是否真的收到了该消息?”的问题,而 UDP 使用思想ACK和祈祷)。DNS 数据包(无论是查询还是响应)均由标头和 4 个主要部分组成:
1、问题或疑问 – 例如,“什么域名?你希望得到什么样的答案?”
2、回应——对问题的回答。
3、权限 – 有关负责跟踪域地址的服务器的信息。
4、附加 – 各种数据,例如权威服务器的 IP 地址。
如何使用 DNS 建立“隧道”?
DNS隧道”是滥用DNS的做法,将其用作隐蔽的通信渠道,例如恶意软件与其C&C服务器之间的通信。在这种情况下,恶意参与者同时控制客户端和服务器,在进行哪种查询以及在哪里隐藏响应的“刺激”部分方面为他们提供了很大的回旋余地。
然而,参与者选择的方案本质上受到 DNS 协议本身的限制。例如:
1、请求和响应长度是有限的。正在查找的整个域不得超过 255 字节,DNS 数据包的最大长度为 576 字节。
2、DNS协议自然适应缓存。服务器记录下一小时前发送的响应,当被问及时,只需重复该响应,而不是一直到权威服务器并唠叨“嘿,一小时前的答案仍然有效吗?”这对DNS的合法用户来说很好,但对DNS隧道客户端来说就不那么好了,它通常求助于查询许多虚构的子域(af34deb93557.maliciousdomain.xyz,然后是48bd9a577d114maliousmain.xyz等)来保持查询的新鲜性。
如果这一切听起来过于理论化,那么一种利用 DNS 隧道的著名恶意软件就是备受瞩目的 SUNBURST 后门,该后门是臭名昭著的 2020 SolarWinds 黑客攻击的一部分,被传递给毫无戒心的受害者。SUNBURST 使用 DNS 查询作为轻型侦察通道,秘密传输加密为标识符的受害者信息,然后将其用作 DNS 查询中的子域。该子域位于四个主要域之一的前面:
appsync-api.us-east-1[.]avsvmcloud[.]com
appsync-api.us-east-2[.]avsvmcloud[.]com
appsync-api.eu-west-1[.]avsvmcloud[.]com
appsync-api.us-west-2[.]avsvmcloud[.]com
例如,生成的虚构 FQDN 如下所示:
7cbtailjomqle1pjvr2d32i2voe60ce2[.]appsync-api[.]us-east-1[.]avsvmcloud[.]com。
根据通过 DNS 请求传输的信息,DNS 服务器会将 CNAME 记录返回给感兴趣的目标。CNAME 将指向通过 HTTPS 与恶意软件进行通信的 C&C 服务器。
分析 DNS 隧道
站在网络网关上的坚定防御者能否检测DNS隧道?这是一个令人惊讶的负载问题,因为DNS隧道的定义非常广泛,并且一些实现比其他实现更难检测。我们在下面列出了一些有趣的点,在分析怀疑是DNS隧道的活动时值得记住。
我们问自己以下问题:
多少和多久?查看与可疑域关联的子域的数量和长度。如前所述,DNS 数据包的大小有限,为参与者提供了少量可操作的字段。在 DNS 查询中传输数据的最有效方法是使用子域,这会导致向同一域的多个(通常很长)子域发出大量 DNS 请求。这也有助于避免潜在的缓存问题。
图 1 – DNS 隧道
谁在回答?DNS 具有权威性,这意味着特定的名称服务器 (NS) 负责特定域的最终解析。对这些域的 DNS 查询最终会到达这些服务器(除非它们在途中缓存在某个地方)。为了促进 DNS 隧道,参与者必须控制与特定域关联的名称服务器。查看可疑域的 NS 记录或 WHOIS 记录(表明该域的权威名称服务器)实际上可能指向威胁行为者的基础设施。
回答这些问题可能并不容易,但幸运的是,对于我们研究人员来说,其中很多问题都可以使用公共资源来回答。被动 DNS 是一种非常有用的工具,可用于分类各种威胁,但在处理 DNS 隧道时非常有效。由于 DNS 隧道依赖于 DNS 协议本身,因此被动 DNS 复制通常会记录随之传输的工件。在某些情况下,甚至有可能提取与受害者本人相关的信息。
深度 DNS 简介
作为我们对一般 DNS 隧道和恶意网络流量持续关注的一部分,今年我们引入了 DeepDNS,这是一种人工神经网络,可以搜寻和阻止滥用 DNS 的活动。DeepDNS 是一种门控循环单元自动编码器 (GRU-AE),作为遥测的一部分,根据 Check Point 通常可用的大量 DNS 流量进行训练。DeepDNS 得出的结论会自动推送到 Check Point ThreatCloud。
这篇文档当然不是关于人工智能内部工作原理的论文,但我们仍然认为,对“门控循环单元自动编码器”的一个非常简单的解释(至少在广义上)会对您有所帮助。
首先,自动编码器是一个人工神经网络,也就是说,它是一个虚拟的大脑,以一张白纸开始它的生活。在训练阶段,给它一个输入——然后观察输出,并使用微积分来确定大脑参数的变化,这些变化会使输出更理想,然后应用(这是一种奇特的说法,说你闭上眼睛,想象输出的错误性作为大脑参数的函数是一座山,然后尽可能快地下山,直到你不能再往下走)。这个过程重复进行,直到虚拟大脑的实际输出与期望的输出足够相似。如果这整个描述对你来说听起来很陌生,请考虑一下,它在概念上与你对三岁的孩子反复喊“不!!不!!别管它!!”时所做的没有太大区别。
图 2 – 人工神经网络 (ANN) 示意图。
人工神经网络具有惊人的学习各种功能的能力(这甚至在 理论上得到了证明))。其中一个功能就是“将此文本映射到某种简短的表示形式(代码),然后将代码更改回文本,以便最终文本尽可能类似于初始文本。” 经过训练来学习此类功能的神经网络称为自动编码器。自动编码器可以用作生成模型:以某种方式获得代码空间中的新点(通过随机选取或将一些已知点混合在一起),如果模型已经学会了数据的良好表示,则解码该点将结果是新颖的文本。由于这在技术上不是自动编码器规范的一部分,因此文献对于将其称为生成模型而不是具有生成能力的模型的正确性存在分歧(通过谷歌搜索获得乐趣));但是“具有生成能力的模型”与主标题不太相符,所以我们就到这里了。
图 3 – 自动编码器的示意结构。
自动编码器的另一个相关用例是异常检测。应用一些数学直觉将使您得出这样的结论:“典型”输入将由自动编码器相对成功地压缩和重建,而“非典型”输入的压缩和重建更有可能引入错误。这基本上是出于同样的原因,如果我说“敏捷的棕色狐狸跳过了懒狗”,那么五分钟后让你重复这句话,你可能会成功,但对于“深奥的紫色鸭嘴兽”则不然。让多产的猎豹感到困惑”。
DeepDNS 的工作原理与此相同。通过对进一步分解为更小的组成部分的子域名进行深入检查,它使用它学到的编码解码过程来对简单的问题做出判断,“这组查询看起来有多正常?” 如果重建足够失败,DeepDNS 就会得出答案“不够正常”的结论,并给出恶意判决。如果您忽略训练模型涉及彩色浮动表面和一堆偏导数的部分,那么这种方法的简单性就很优雅。
隧道的尽头 – 挖掘并深入研究 CoinLoader DNS 隧道
现在我们已经介绍了理论,是时候将其付诸实践了。了解了 DeepDNS 在黑匣子级别的工作原理(甚至通过上面的部分了解了它的一些内部工作原理),我们很自然地会问,如果我们让它在可用的遥测数据中搜索异常情况,它会发现什么。我们就是这样做的,并在我们的样本上运行 DeepDNS。在它标记为异常的众多结果中,一个以前未知的域簇特别引起了我们的注意:
rqmetrixsdn[.]info
candatamsnsdn[.]info
mapdatamsnsdn[.]info
仔细观察与这些域连接的基础设施表明它们是用于 CoinLoader 感染的 DNS 备份通道的一部分。
Coinloader 首次在Avira 的这份详尽报告中进行了描述 ,但我们找不到描述此特定功能的先前文档。样本是在包含多个文件的存档中找到的,通常是 a rar 或 a zip。虽然名称各不相同,但您在下面看到的内容或多或少代表了每个示例中的文件结构。
图 4 – CoinLoader 文件结构。
可执行文件(ZD_1.4.24.17 图中)始终是用于 DLL 旁加载的合法工具。主要的恶意逻辑位于旁加载的 DLL 中(此处 AppleVersions.dll)。加载后,它会经历几层解包,包括一个经过精心混淆的检查,检查其父进程是从隐藏在 Z-1-36-81 一些复杂的控制流结构中的目录内部启动的(同样,目录名称因样本而异)。
图 5 – CoinLoader 执行流程。
解包完成后,恶意逻辑就可见了。最后阶段仍然包含一些反分析功能,例如垃圾代码;使用简单的替换密码即时解密的加密堆栈字符串;以及使用自制函数表解析的间接调用,其中寄存器指向传递给 中每个函数的内容 ecx
。然后每次都会将其
复制到随机寄存器,用于实现调用。
图 6 – 用作反分析的垃圾指令。
图 7 – 混淆的堆栈字符串。
图 8 – 使用自制函数表的间接调用。
虽然垃圾代码最好被忽略,模糊字符串最好通过动态执行代码和观察解码器输出来处理,但IDA数据库中函数调用的解析需要专用脚本。要查看这样的脚本,请参阅附录A。
由这样一个样本生成的流量捕获似乎很有作用:
图 9 – CoinLoader 执行中捕获的数据包。
因此我们着手对此功能进行技术分析。
函数get_c2_domain接收枚举参数(此处传入寄存器edx)。值0、1、2和3使函数分别解密和返回恶意软件的每个硬编码C&C域名——在本例中是rqmetrixa.info、rqmetricxb.info,rqmetryx.info,rqmetrixd.info(我们很失望地发现,没有一些逻辑将字母附加到rqMetricx,但这些都是硬编码的)。
图 10 – “get c2”函数的不同开关分支。
最后,如果该枚举值等于4(上面注释为GET_DOMAIN_DNS_TUNNEL_BACKUP),恶意软件将诉诸备份计划,并试图通过流量捕获中看到的TXT DNS隧道查询,通过与其他服务器rqmetrixsdn.info协商来获得域名。
图 11 – DNS TXT 查询。
FQDN 是通过采用硬编码域之一并将其添加到其前面来创建的 hexlify(md5(timestamp))。在下图中,我们将其显示为一个代码块,用于过滤掉垃圾指令。
mov ebx, eax
mov [ebp+md5_of_timestamp], ebx
call [edi+FuncTable.GetSystemTime]
xor eax, eax
mov [esi+0Eh], ax
push ebx ; allocated buffer
call mre_get_filetime_md5 ; now has md5 of current timestamp
时间戳md5是使用获得的(然后使用其他WinAPI函数转换为时间戳)。一旦服务器响应,其响应将馈送到内联BASE64解码器。结果被解释为要使用的C&C域,类似于我们前面提到的SUNBURST设置。签入格式是deobfusion处理程序的输出,在.SystemFileToFileTimestring_decoder下面可见
图 12 – C&C 签入的构建。
结论
DNS 隧道可以称为“老式”技术。它起源于第一批防火墙的出现所创建的安全环境,以及简单化边界的绘制:谁发起了连接?和谁一起?在什么端口?使用什么协议?因此,要么允许,要么拒绝。此后,该行业已经发生了巨大的发展,DNS 隧道的好处已经变得不那么明显了。DNS 不再是任何安全解决方案都不会考虑查看的“隐蔽通道”;相反,攻击者已经加深了对如何使用 HTTP 进行有效通信以及如何使用隐藏术和加密等各种技术隐藏在众目睽睽之下的理解。
尽管如此,DNS 隧道显然并未消亡。无论是因为它在人眼中不太明显,还是因为恶意软件作者只是认为如果直接的 HTTP 通信失败,该技术值得一试,或者由于其他原因,现代恶意软件并不羞于参与这种做法。作为防守者,我们自然对如何在比赛中接球感兴趣。在这篇文章中,我们解释了如何将 DNS 隧道建模为异常并从不寻常的角度捕获它们,如 DeepDNS 所示。这次追捕让我们找到了目前使用该技术的许多行为者的证据,包括国家支持的网络犯罪分子,甚至黑客活动分子。例如,我们对 Coinlander 样本及其隧道协议进行了技术分析,DeepDNS 发现该样本存在异常。
虽然学术界高举着突破科学界限和证明可能性的火炬,但大规模实施学术思想的责任往往落在工业界身上,并引导它们沿着从有希望的白皮书到在混乱的现实世界中生存下来的道路前进。虽然我们不断努力将人工神经网络应用于该成熟度的安全性,但前沿还远未穷尽。随着最近人们对人工神经网络及其应用的兴趣激增,我们只能期望越来越多的人工大脑能够做出现实世界的安全决策,作为一个行业,我们有责任让他们以技能和责任来做到这一点。
因此,本着这种精神,让这篇文章成为我们当时说的“哦,模型,你说那是 DNS 隧道?让我们的分析师和逆向工程师仔细检查一下”。
IOC
CoinLoader 样本
a05144d7254b419d3a09787e280b4be3
84548cf16e26979ff9a3fa2b3f854f34
CoinLoader基础架构
candatamsnsdn[.]info
candatamsna[.]info
candatamsnb[.]info
candatamsnc[.]info
candatamsnd[.]info
mapdatamsnsdn[.]info
mapdatamsna[.]info
mapdatamsnb[.]info
mapdatamsnc[.]info
mapdatamsnd[.]info
rqmetrixsdn[.]info
rqmetrixa[.]info
rqmetrixb[.]info
rqmetrixc[.]info
rqmetrixd[.]info
附录 A — 用于解析 Coinloader 最后阶段间接调用函数的 Python 脚本
(需要从内存中提取函数表 - 下面包含示例函数表。)
from abc import ABC, abstractmethod, abstractclassmethod
from typing import List, Tuple, NewType, Dict, Set, Callable, TypeVar, Any, cast, Optional
from functools import wraps
from enum import Enum
import sys
FuncT = TypeVar("FuncT", bound=Callable[...,Any])
try:
import idc #type: ignore
import idautils #type: ignore
import ida_struct #type: ignore
import ida_bytes #type: ignore
import ida_idaapi #type: ignore
except ModuleNotFoundError:
pass #ok, not running within IDA
#IDA
def ida(func: FuncT) -> FuncT:
ida_modules = set(["idc","idaapi"])
@wraps(func)
def wrapper_ida_check(*args: Any, **kwargs: Any) -> Any:
if not set(sys.modules).issuperset(ida_modules):
print("ERROR: IDA function called outside IDA context!")
raise NotImplementedError
return func(*args, **kwargs)
return cast(FuncT, wrapper_ida_check)
class OPERAND_TYPE(Enum):
o_void = 0
o_reg = 1
o_mem = 2
o_phrase = 3
o_displ = 4
o_imm = 5
o_far = 6
o_near = 7
o_idpspec0 = 8
o_idpspec1 = 9
o_idpspec2 = 10
o_idpspec3 = 11
o_idpspec4 = 12
o_idpspec5 = 13
Addr = NewType("Addr",int)
#Functable
class Functable(ABC):
@abstractmethod
def funcname_from_offset(self, addr: Addr) -> str:
raise NotImplementedError
@abstractmethod
def as_dict(self) -> Dict[Addr, str]:
raise NotImplementedError
@ida
@abstractmethod
def ida_struct_id(self) -> int:
raise NotImplementedError
@abstractclassmethod
def from_file(cls, fname: str) -> "Functable":
raise NotImplementedError
class _Functable(Functable):
def __init__(self, base: Addr, addr_contents: List[Tuple[Addr,str]]) -> None:
self.base = base
self.content_by_addr = {k: v for (k,v) in addr_contents}
self.struct_id = None
def funcname_from_offset(self, offset: int) -> str:
return self.content_by_addr[Addr(self.base+offset)]
def as_dict(self) -> Dict[Addr, str]:
return self.content_by_addr
@ida
def ida_struct_id(self) -> int:
if self.struct_id is None:
self.struct_id = ida_struct.add_struc(ida_idaapi.BADADDR, "FuncTable", False)
struct_ptr = ida_struct.get_struc(self.struct_id)
for (addr, funcname) in sorted(self.as_dict().items(), key = lambda item: item[0]):
ida_struct.add_struc_member(struct_ptr, funcname, addr-self.base, ida_bytes.dword_flag(), None, 4)
return self.struct_id #type: ignore
@classmethod
def from_file(cls, fname: str) -> "_Functable":
with open(fname, "r") as fh:
tokenized_entrylist = [line.strip().split(" ") for line in fh.readlines()]
base = Addr(int(tokenized_entrylist[0][0],16))
addr_contents : List[Tuple[Addr,str]] = []
for tokenized_entry in tokenized_entrylist:
if len(tokenized_entry) > 2:
addr_contents.append((
Addr(int(tokenized_entry[0],16)),
tokenized_entry[2].replace("!","_")
))
return _Functable(base, addr_contents)
#CoinLoaderFunction
class CoinLoaderFunction(ABC):
@ida
@abstractmethod
def functable_register(self) -> Optional[str]:
raise NotImplementedError
@ida
@abstractmethod
def heads(self) -> List[Addr]:
raise NotImplementedError
@ida
@abstractmethod
def is_indirect_call(self, addr: Addr) -> bool:
raise NotImplementedError
@ida
@abstractmethod
def all_indirect_calls(self) -> Dict[Addr,int]:
raise NotImplementedError
@ida
@abstractmethod
def patch_single_indirect_call(self, ea: Addr, ft: Functable) -> None:
raise NotImplementedError
@ida
@abstractmethod
def patch_indirect_calls(self, ft: Functable) -> None:
raise NotImplementedError
@ida
@abstractclassmethod
def from_addr(cls, addr: Addr) -> "CoinLoaderFunction":
raise NotImplementedError
class _CoinLoaderFunction(CoinLoaderFunction):
@ida
def __init__(self, addr: Addr) -> None:
self.addr = addr
self._functable_register = self.functable_register()
@ida
def heads(self) -> List[Addr]:
return [insn for bound in idautils.Chunks(self.addr) for insn in idautils.Heads(*bound)]
@ida
def is_regload_insn(self, ea: Addr) -> bool:
if idc.print_insn_mnem(ea) != "mov": return False
for i in (0,1):
if OPERAND_TYPE(idc.get_operand_type(ea,i)) != OPERAND_TYPE.o_reg:
return False
if idc.print_operand(ea,1) != "ecx": return False
return True
@ida
def functable_register(self) -> Optional[str]:
try:
regload_insn = next(filter(self.is_regload_insn, self.heads()))
return idc.print_operand(regload_insn,0) #type: ignore
except StopIteration:
return None
@ida
def is_indirect_call(self, ea: Addr) -> bool:
if self._functable_register is None: return False
if idc.print_insn_mnem(ea) != "call": return False
if OPERAND_TYPE(idc.get_operand_type(ea,0)) != OPERAND_TYPE.o_displ: return False
if not idc.print_operand(ea,0).startswith("dword ptr ["+self._functable_register+"+"): return False
return True
@ida
def all_indirect_calls(self) -> Dict[Addr,int]:
eas = [h for h in self.heads() if self.is_indirect_call(h)]
return {ea:idc.get_operand_value(ea,0) for ea in eas}
@ida
def patch_single_indirect_call(self, ea: Addr, ft: Functable) -> None:
sid = ft.ida_struct_id()
if sid is None:
print("Cannot patch, functable doesn't have IDA struct")
print("Use: functable.create_struct()")
idc.op_stroff(ea, 0, sid,0)
@ida
def patch_indirect_calls(self, ft: Functable) -> None:
for call in self.all_indirect_calls():
self.patch_single_indirect_call(call,ft)
@ida
@classmethod
def from_addr(cls, addr: Addr) -> "CoinLoaderFunction":
return _CoinLoaderFunction(addr)
def patch_indirect_calls_all_functions(ft: Functable):
for ea in idautils.Functions():
clf : CoinLoaderFunction = _CoinLoaderFunction(ea)
clf.patch_indirect_calls(ft)
def test_get_name() -> None:
f = _Functable.from_file("functable.txt")
assert(f.funcname_from_offset(0x0) == "kernel32_OpenProcess")
assert(f.funcname_from_offset(0x4) == "kernel32_VirtualProtect")
函数表示例:
0x26cfb94 0x7dd71986 OpenProcess
0x26cfb98 0x7dd7435f VirtualProtect
0x26cfb9c 0x7dd711c0 GetLastError_0
0x26cfba0 0x7dd74913 LoadLibraryExA
0x26cfba4 0x7dd8e4be GlobalReAlloc
0x26cfba8 0x7dd7588e GlobalAlloc
0x26cfbac 0x7dd734d5 CreateThread
0x26cfbb0 0x7dd8d16f GlobalSize
0x26cfbb4 0x7dd7492b LoadLibraryW_0
0x26cfbb8 0x7dd71856 VirtualAlloc
0x26cfbbc 0x7dd71072 CreateProcessA
0x26cfbc0 0x7dd7495d LoadLibraryExW
0x26cfbc4 0x7dd77a10 ExitProcess
0x26cfbc8 0x7dd732bb SetThreadPriority
0x26cfbcc 0x7dd7186e VirtualFree
0x26cfbd0 0x7dd7168c LocalAlloc_0
0x26cfbd4 0x7dd734c8 FreeLibrary_0
0x26cfbd8 0x7dd75558 GlobalFree
0x26cfbdc 0x7dd72d3c LocalFree
0x26cfbe0 0x7ddeaeee SetFileCompletionNotificationModes
0x26cfbe4 0x7dd8cf28 SetPriorityClass
0x26cfbe8 0x7dd93102 lstrcpyW
0x26cfbec 0x7dd75971 FindResourceW
0x26cfbf0 0x7dd8ecbb SetFileTime
0x26cfbf4 0x7dd71809 GetCurrentProcess_0
0x26cfbf8 0x7dd7e2ce FindFirstFileA
0x26cfbfc 0x7dd8e9bb FindResourceA
0x26cfc00 0x7dd734b0 GetModuleHandleW
0x26cfc04 0x7dd741f0 QueryPerformanceFrequency
0x26cfc08 0x7dd9d53e FindNextFileA
0x26cfc0c 0x7dd75444 DeleteFileA
0x26cfc10 0x7dd9cb05 RegisterWaitForSingleObject
0x26cfc14 0x7ddf453f SetNamedPipeHandleState
0x26cfc18 0x7dd9691f K32EnumProcesses
0x26cfc1c 0x7dd8d3ab ReleaseSemaphore
0x26cfc20 0x7dd75a4b lstrlen
0x26cfc24 0x7df720c0
0x26cfc28 0x7dd8192a lstrcpyn
0x26cfc2c 0x7dd997aa GetSystemWindowsDirectoryA
0x26cfc30 0x7ddf1807 CreateNamedPipeA
0x26cfc34 0x7dd743ef ResumeThread
0x26cfc38 0x7dd75ac9 SizeofResource
0x26cfc3c 0x7dd749ca GetSystemInfo
0x26cfc40 0x7dd71282 WriteFile
0x26cfc44 0x7dd73f5c CreateFileW
0x26cfc48 0x7dd75959 LockResource
0x26cfc4c 0x7dd7170d WideCharToMultiByte_0
0x26cfc50 0x7dd716c5 SetEvent
0x26cfc54 0x7ddf498e QueryFullProcessImageNameA
0x26cfc58 0x7dd71725 QueryPerformanceCounter_0
0x26cfc5c 0x7dd905a0 SetThreadAffinityMask
0x26cfc60 0x7ddf44bf RemoveDirectoryA
0x26cfc64 0x7dd8ca5a CreateSemaphoreW
0x26cfc68 0x7dd717ec GetCurrentThread
0x26cfc6c 0x7dd74f2b FlsAlloc
0x26cfc70 0x7dd7183e CreateEventW
0x26cfc74 0x7dd751a1 GetCommandLineA
0x26cfc78 0x7dd8b6e0 GetComputerNameA
0x26cfc7c 0x7dd75611 GetCurrentDirectoryW
0x26cfc80 0x7dd8eceb lstrcmp
0x26cfc84 0x7dd92a9d lstrcpy
0x26cfc88 0x7dd74208 FlsSetValue
0x26cfc8c 0x7ddfe6ab UnregisterWait
0x26cfc90 0x7dd71245 GetModuleHandleA
0x26cfc94 0x7dd9276c GetTempPathA
0x26cfc98 0x7dd8ecd3 SetFileAttributesA
0x26cfc9c 0x7dd7195e IsWow64Process
0x26cfca0 0x7dd7469b FlushFileBuffers
0x26cfca4 0x7dd75a7e SystemTimeToFileTime
0x26cfca8 0x7dde3161 EnumResourceNamesW
0x26cfcac 0x7dd8d650 Wow64DisableWow64FsRedirection
0x26cfcb0 0x7ddf40fb ConnectNamedPipe
0x26cfcb4 0x7dd71b00 SetErrorMode
0x26cfcb8 0x7dd8eef2 CreateIoCompletionPort
0x26cfcbc 0x7dd75aa6 GetLocalTime
0x26cfcc0 0x7dd74c6b CreateMutexA
0x26cfcc4 0x7dd7192e MultiByteToWideChar_0
0x26cfcc8 0x7dd7594c LoadResource
0x26cfccc 0x7dd74950 GetModuleFileNameW_0
0x26cfcd0 0x7dd8d3c3 GetQueuedCompletionStatus
0x26cfcd4 0x7dd71410 CloseHandle_0
0x26cfcd8 0x7dd7359f FlsFree
0x26cfcdc 0x7dd8195c SetHandleInformation
0x26cfce0 0x7dd710ff Sleep_0
0x26cfce4 0x7dd714b1 GetModuleFileNameA
0x26cfce8 0x7dd8d668 Wow64RevertWow64FsRedirection
0x26cfcec 0x7dd96dcb GetVolumeInformationA
0x26cfcf0 0x7dd75a96 GetSystemTime
0x26cfcf4 0x7dd73ed3 ReadFile
0x26cfcf8 0x7dd9d526 CreateDirectoryA
0x26cfcfc 0x7dd7110c GetTickCount_0
0x26cfd00 0x7dd73e8e lstrcmpiA
0x26cfd04 0x7dd9ab72 EnumResourceNamesA
0x26cfd08 0x7dd754ee FindNextFileW
0x26cfd0c 0x7ddf41df DisconnectNamedPipe
0x26cfd10 0x7dd74435 FindFirstFileW
0x26cfd14 0x7dd8eb39 ExpandEnvironmentStringsA
0x26cfd18 0x7dd75414 GetFileAttributesA
0x26cfd1c 0x7dd74220 WaitForMultipleObjects
0x26cfd20 0x7dd8d802 TerminateProcess_0
0x26cfd24 0x7dd74442 FindClose
0x26cfd28 0x7dded911 MoveFileA
0x26cfd2c 0x7dd753c6 CreateFileA
0x26cfd30 0x7ddf43af GetQueuedCompletionStatusEx
0x26cfd34 0x7dd789b3 DeleteFileW
0x26cfd38 0x7dd8ef29 PostQueuedCompletionStatus
0x26cfd3c 0x7dd74173 ExpandEnvironmentStringsW
0x26cfd40 0x7dd74407 GetFileTime
0x26cfd44 0x7dd71136 WaitForSingleObject
0x26cfd48 0x7dd716dd ResetEvent
0x26cfd4c 0x7dd71252 FlsGetValue
0x26cfd50 0x7dd717d1 SetFilePointer
0x26cfd54 0x7dd71700 lstrlenW_0
0x26cfd58 0x7dd8efec SwitchToThread
0x26cfd5c 0x77c69edf SetSecurityInfo
0x26cfd60 0x77c8077c LsaOpenPolicy
0x26cfd64 0x77c740e6 AllocateAndInitializeSid
0x26cfd68 0x77c740fe RegCreateKeyExW
0x26cfd6c 0x77c741b3 LookupPrivilegeValueW
0x26cfd70 0x77c7431c GetTokenInformation
0x26cfd74 0x77cb15a0 SetNamedSecurityInfoA
0x26cfd78 0x77c7469d RegCloseKey_0
0x26cfd7c 0x77c81af7 LsaClose
0x26cfd80 0x77c74620 InitializeSecurityDescriptor
0x26cfd84 0x77c7468d RegOpenKeyExW_0
0x26cfd88 0x77c714d6 RegSetValueExW
0x26cfd8c 0x77ca8819 LsaAddAccountRights
0x26cfd90 0x77cb15e9 SetEntriesInAclA
0x26cfd94 0x77c7412e FreeSid
0x26cfd98 0x77c7418e AdjustTokenPrivileges
0x26cfd9c 0x77cb187f GetExplicitEntriesFromAclA
0x26cfda0 0x77c715ad RegOpenCurrentUser
0x26cfda4 0x77c7157a GetUserNameW
0x26cfda8 0x77c7415e SetSecurityDescriptorDacl
0x26cfdac 0x77c60000
0x26cfdb0 0x77c74304 OpenProcessToken
0x26cfdb4 0x77cb1554 GetNamedSecurityInfoA
0x26cfdb8 0x7deb01e3
0x26cfdbc 0x7debd2f3
0x26cfdc0 0x7dea9c70
0x26cfdc4 0x7de922b0
0x26cfdc8 0x7de70000
0x26cfdcc 0x7deec240
0x26cfdd0 0x7dea2265
0x26cfdd4 0x7debc4ca
0x26cfdd8 0x7dea45f5
0x26cfddc 0x7de92340
0x26cfde0 0x7de92270
0x26cfde4 0x7debca3a
0x26cfde8 0x7de9df20
0x26cfdec 0x7dea2500
0x26cfdf0 0x7dea2c42
0x26cfdf4 0x7deebfa0
0x26cfdf8 0x7dcbfd3f MessageBoxW
0x26cfdfc 0x7dcbfd1e MessageBoxA
0x26cfe00 0x7dc70a19 GetDesktopWindow
0x26cfe04 0x7dc8e061 wsprintfW
0x26cfe08 0x7dc50000 Ordinal2447
0x26cfe0c 0x7dc7ae5f wsprintfA
0x26cfe10 0x72589d0b CoCreateInstance
0x26cfe14 0x72540000
0x26cfe18 0x72567259 CoInitializeSecurity
0x26cfe1c 0x725809ad CoInitializeEx
0x26cfe20 0x72555ea5 CoSetProxyBlanket
0x26cfe24 0x725886d3 CoUninitialize
0x26cfe28 0x6fc33e59 SysFreeString
0x26cfe2c 0x6fc34642 SysAllocString
0x26cfe30 0x6fc30000 Ordinal471
0x26cfe34 0x504b30
0x26cfe38 0x504b58
0x26cfe3c 0x535120 aAmdRyzen536006_0
0x26cfe40 0x1
0x26cfe44 0x712175e8 InternetSetOptionA
0x26cfe48 0x7127a920 InternetGetLastResponseInfoA
0x26cfe4c 0xcc0004
0x26cfe50 0x7121b406 InternetReadFile
0x26cfe54 0x712430f1 InternetOpenUrlA
0x26cfe58 0x7122f18e InternetOpenA
0x26cfe5c 0x71224c7d HttpOpenRequestA
0x26cfe60 0x712249e9 InternetConnectA
0x26cfe64 0x71200000 Ordinal367
0x26cfe68 0x7121ab49 InternetCloseHandle
0x26cfe6c 0x71211b56 InternetQueryOptionA
0x26cfe70 0x712918f8 HttpSendRequestA
0x26cfe74 0x6dc00000
0x26cfe78 0x6dc2a9bc DnsQuery_A
0x26cfe7c 0x6dc0436b DnsFree
0x26cfe80 0x7d830000
0x26cfe84 0x7d83647a BCryptVerifySignature
0x26cfe88 0x7d834d42 BCryptImportKey
0x26cfe8c 0x7d831fbc BCryptGenerateSymmetricKey
0x26cfe90 0x7d831b44 BCryptFinishHash
0x26cfe94 0x7d831a5f BCryptDestroyHash
0x26cfe98 0x7d831b93 BCryptCreateHash
0x26cfe9c 0x7d831b0b BCryptHashData
0x26cfea0 0x7d8318b8 BCryptDecrypt
0x26cfea4 0x7d83195c BCryptEncrypt
0x26cfea8 0x7d8320d4 BCryptSetProperty
0x26cfeac 0x7d83234e BCryptCloseAlgorithmProvider
0x26cfeb0 0x7d834f94 BCryptImportKeyPair
0x26cfeb4 0x7d83519b BCryptExportKey
0x26cfeb8 0x7d831ca7 BCryptGetProperty
0x26cfebc 0x7d831f40 BCryptDestroyKey
0x26cfec0 0x7d832d30 BCryptOpenAlgorithmProvider
转载来源:https://research.checkpoint.com/2023/tunnel-warfare-exposing-dns-tunneling-campaigns-using-generative-models-coinloader-case-study/#single-post
图片来源网络侵权可联系删除