TUNNEL WARFARE: EXPOSING DNS TUNNELING CAMPAIGNS USING GENERATIVE MODELS – COINLOADER CASE STUDY

渗透技巧 11个月前 admin
213 0 0
TUNNEL WARFARE: EXPOSING DNS TUNNELING CAMPAIGNS USING GENERATIVE MODELS – COINLOADER CASE STUDY

Introduction 介绍

Generative AI has been around for nearly a decade, strictly speaking, but the recent boom in this technology has inspired renewed interest in its possible applications to challenges facing the information security community. Finding these challenges entails searching through a very large haystack consisting of brand-new binaries, documents, domains and other artifacts that flood the web every day.
严格来说,生成式人工智能已经存在了近十年,但最近这项技术的繁荣激发了人们对其可能应用于信息安全社区所面临挑战的兴趣。要找到这些挑战,需要搜索一个非常大的大海捞针,其中包括全新的二进制文件、文档、域和其他每天充斥在 Web 中的工件。

In this blog post, we provide a deep dive into Check Point’s ongoing use of such a model to sweep across this haystack, and routinely thwart malicious campaigns abusing the DNS protocol to communicate with C&C servers. We focus on one such campaign, of CoinLoader, and lay out its infrastructure as well as an in-depth technical analysis of its DNS tunnelling functionality.
在这篇博文中,我们深入探讨了Check Point持续使用这种模型来扫除大海捞针,并定期阻止滥用DNS协议与C&C服务器通信的恶意活动。我们专注于CoinLoader的一个这样的活动,并布置其基础设施以及对其DNS隧道功能的深入技术分析。

A Crash Course in DNS Tunneling
DNS 隧道速成课程

What is DNS? 什么是域名系统?

Domain Name Server (DNS) protocol can be considered “the phonebook of the internet.” When you enter a website address (let’s say wikipedia.org) into your web browser’s address bar and press enter, your web browser sends a DNS request to its favorite DNS server, asking what IP addresses correspond to that domain. The IP address of this default DNS server is either supplied by the user’s network provider or specified manually by the user.
域名服务器(DNS)协议可以被认为是“互联网的电话簿”。当您在 Web 浏览器的地址栏中输入网站地址(假设 wikipedia.org )并按 Enter 键时,您的 Web 浏览器会向其喜欢的 DNS 服务器发送 DNS 请求,询问哪些 IP 地址对应于该域。此默认 DNS 服务器的 IP 地址由用户的网络提供商提供或由用户手动指定。

Under the hood, a typical DNS query rides on top of the UDP protocol (to jog your memory, whereas TCP deals with the issue of “did my peer really get that message?” using SYNs and ACKs, UDP deals with it using thoughts and prayers). A DNS packet, whether a query or a response, consists of a header and 4 main sections:
在引擎盖下,典型的DNS查询位于UDP协议之上(以慢动您的内存,而TCP使用s和s处理“我的对等方真的收到该消息吗?”的问题,UDP使用 SYN 思想和 ACK 祈祷来处理它)。DNS 数据包(无论是查询还是响应)由标头和 4 个主要部分组成:

  • Question or Query – For example, “What domain name? What kind of answer do you expect?”
    问题或查询 – 例如,“什么域名?你期待什么样的答案?
  • Response – An answer to the question.
    回应 – 问题的答案。
  • Authority – Information about the servers responsible for keeping track of the domain addresses.
    颁发机构 – 有关负责跟踪域地址的服务器的信息。
  • Additional – Miscellaneous data such as the IP addresses of the authoritative servers.
    附加 – 杂项数据,例如权威服务器的 IP 地址。

How does one “Tunnel” using DNS?
如何使用 DNS “隧道”?

“DNS Tunneling” is the practice of abusing DNS, using it as a covert channel of communication such as between a malware and its C&C server. In this scenario, the malicious actor controls both the client and the server, giving them a lot of wiggle room with respect to what kind of query to make, and where to hide the “spicy” part of the response.
“DNS隧道”是滥用DNS的做法,将其用作隐蔽的通信渠道,例如恶意软件与其C&C服务器之间的通信。在这种情况下,恶意参与者同时控制客户端和服务器,在进行哪种查询以及在哪里隐藏响应的“辛辣”部分方面为他们提供了很大的回旋余地。

However, the scheme the actors choose is inherently subject to the limitations of the DNS protocol itself. For example:
但是,参与者选择的方案本质上受到 DNS 协议本身的限制。例如:

  • Request and response lengths are bounded. The entire domain that is being looked up must not exceed 255 bytes, and the maximum length of a DNS packet is 576 bytes.
    请求和响应长度是有限制的。正在查找的整个域不得超过 255 字节,DNS 数据包的最大长度为 576 字节。
  • The DNS protocol naturally lends itself to caching. Servers make note of a response they sent an hour ago and when asked, simply repeat that response, instead of going all the way to the authoritative server and nagging “Hey, is that answer from an hour ago still valid?” This is great for legitimate users of DNS, but not so great for DNS tunneling clients, which typically resort to querying many fictitious subdomains (af34deb93557.maliciousdomain.xyz, then later 48bd9a577d114.maliciousdomain.xyz, and so on) to keep the queries fresh.
    DNS 协议自然适合缓存。服务器会记录他们一小时前发送的回复,当被问及时,只需重复该回复,而不是一直到权威服务器并唠叨“嘿,一小时前的答案仍然有效吗?这对于 DNS 的合法用户非常有用,但对于 DNS 隧道客户端来说就不是那么好了,这些客户端通常采用查询许多虚构的子域(然后是 af34deb93557.maliciousdomain.xyz 48bd9a577d114.maliciousdomain.xyz ,等等)来保持查询的新鲜度。

If this all sounds too theoretical, one well-known malware that utilizes DNS tunneling is the high-profile SUNBURST backdoor, which was delivered to unsuspecting victims as part of the infamous 2020 SolarWinds hack. SUNBURST used DNS queries as a light recon channel, covertly transferring victim information encrypted as an identifier, and then used it as a subdomain in a DNS query. This subdomain was prepended to one of the four main domains:
如果这一切听起来太理论化,那么利用 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

For example, the resulting fictitious FQDN looks like this:
例如,生成的虚构 FQDN 如下所示:

7cbtailjomqle1pjvr2d32i2voe60ce2[.]appsync-api[.]us-east-1[.]avsvmcloud[.]com.
Based on the information transferred over the DNS requests, the DNS server would return a CNAME record to targets of interest. The CNAME would point to a C&C server that communicates with the malware over HTTPS.
根据通过 DNS 请求传输的信息,DNS 服务器会将 CNAME 记录返回给感兴趣的目标。CNAME将指向通过HTTPS与恶意软件通信的C&C服务器。

Analyzing DNS Tunnels 分析 DNS 隧道

Can a determined defender, standing atop a network gateway, detect DNS tunneling? This is a surprisingly loaded question, because the definition of DNS tunneling is very broad, and some implementations are more difficult to detect than others. We list some points of interest below that are worth keeping in mind while analyzing activities suspected to be DNS tunneling.
站在网络网关顶端的坚定防御者能否检测到 DNS 隧道?这是一个令人惊讶的问题,因为 DNS 隧道的定义非常广泛,并且某些实现比其他实现更难检测。我们在下面列出了一些在分析怀疑是 DNS 隧道的活动时值得牢记的兴趣点。

We asked ourselves the following questions:
我们问自己以下问题:

  • How many? and How Long? Take a look at the number and length of sub-domains associated with a suspicious domain. As mentioned previously, DNS packets are limited in size, offering actors a small number of fields to manipulate. The most effective way to transfer data in DNS queries is using subdomains, which results in a high volume of DNS requests to multiple, often long, subdomains of the same domain. This also helps to avoid potential caching problems.
    几个?以及多长时间?查看与可疑域关联的子域的数量和长度。如前所述,DNS 数据包的大小有限,为参与者提供了少量字段来操作。在 DNS 查询中传输数据的最有效方法是使用子域,这会导致对同一域的多个(通常很长)子域发出大量 DNS 请求。这也有助于避免潜在的缓存问题。
TUNNEL WARFARE: EXPOSING DNS TUNNELING CAMPAIGNS USING GENERATIVE MODELS – COINLOADER CASE STUDY
Figure 1 – DNS Tunneling
图 1 – DNS 隧道
  • Who’s answering? DNS is authoritative, meaning specific name-servers (NS) are responsible for the final resolution of specific domains. DNS queries for those domains do eventually end up reaching those servers (unless they are cached somewhere along the way). To facilitate DNS Tunneling, an actor must control the nameserver associated with a particular domain. A look at a suspicious domain’s NS record or WHOIS record, that indicates the authoritative nameserver for that domain, might actually point to the threat actors’ infrastructure.
    谁在回答?DNS 是权威的,这意味着特定名称服务器 (NS) 负责特定域的最终解析。对这些域的DNS查询最终会到达这些服务器(除非它们在途中缓存在某个地方)。为了促进 DNS 隧道,参与者必须控制与特定域关联的名称服务器。查看可疑域的 NS 记录或 WHOIS 记录,指示该域的权威名称服务器,实际上可能指向威胁参与者的基础架构。

Answering those questions may not be easy, but luckily for us as researchers, a lot of them can be answered using public resources. Passive DNS is a very helpful tool in triaging a wide variety of threats but is extremely efficient when dealing with DNS tunneling. As DNS tunneling relies on the DNS protocol itself, passive DNS replications often document artifacts transferred with it. In some cases, it might even be possible to extract information related to the victims themselves.
回答这些问题可能并不容易,但幸运的是,对于我们研究人员来说,其中很多都可以使用公共资源来回答。被动 DNS 是分类各种威胁的非常有用的工具,但在处理 DNS 隧道时非常有效。由于 DNS 隧道依赖于 DNS 协议本身,因此被动 DNS 复制通常会记录随它传输的项目。在某些情况下,甚至可以提取与受害者本身有关的信息。

Introducing DeepDNS 深度域名解析简介

As part of our ongoing interest in general DNS tunneling and malicious web traffic, this year we saw the introduction of DeepDNS, an artificial neural network that hunts and blocks campaigns that abuse DNS. DeepDNS is a Gated Recurrent Unit Autoencoder (GRU-AE) that is trained on the vast amount of DNS traffic routinely available to Check Point as part of the telemetry. The DeepDNS conclusions drawn are automatically pushed to Check Point ThreatCloud.
作为我们对一般DNS隧道和恶意网络流量的持续兴趣的一部分,今年我们看到了DeepDNS的引入,这是一种人工神经网络,可以搜寻和阻止滥用DNS的活动。DeepDNS 是一种门控循环单元自动编码器 (GRU-AE),它针对 Check Point 常规可用的大量 DNS 流量进行训练,作为遥测的一部分。得出的DeepDNS结论会自动推送到Check Point ThreatCloud。

This document is certainly not a treatise on the inner workings of AI, but we still felt you would be well served by a very simplified explanation of what a “Gated Recurrent Unit Autoencoder” is, at least in broad strokes.
本文档当然不是一篇关于人工智能内部工作的论文,但我们仍然认为,至少在广义上,对“门控循环单元自动编码器”的非常简化的解释会很好地为您服务。

To begin with, an autoencoder is an artificial neural network, meaning, it is a virtual brain that begins its life as a blank slate. During its training phase, it is given an input — the output is then observed, and changes to the brain’s parameters that would make the output more desirable are determined using calculus, then applied (this is a fancy way of saying that you close your eyes, imagine that the wrongness of the output as a function of the brain parameters is a mountain, then go as quickly down the mountain as you can until you cannot go further down). This process repeats until the virtual brain’s actual output sufficiently resembles the desired output. If this whole description sounds alien to you, consider that it is not so conceptually different from what you do when you repeatedly shout “NO!! NO!! LEAVE THAT ALONE!!!” at your three-year-old.
首先,自动编码器是一个人工神经网络,这意味着,它是一个虚拟大脑,它的生命始于一张白纸。在训练阶段,它被赋予一个输入——然后观察输出,并使用微积分确定使输出更理想的大脑参数的变化,然后应用(这是一种奇特的说法,你闭上眼睛,想象输出作为大脑参数函数的错误是一座山, 然后尽可能快地下山,直到你不能再往下走)。这个过程重复,直到虚拟大脑的实际输出与期望的输出足够相似。如果这整个描述对你来说听起来很陌生,请考虑一下它与你反复喊“不!不!!别管它!!“对你三岁的孩子。

TUNNEL WARFARE: EXPOSING DNS TUNNELING CAMPAIGNS USING GENERATIVE MODELS – COINLOADER CASE STUDY
Figure 2 – Schematic of an Artificial Neural Network (ANN).
图 2 – 人工神经网络 (ANN) 示意图。

Artificial neural networks have a surprising capacity to learn all sorts of functions (this is even theoretically proven). One such function is simply “map this text to some short representation (code), then change the code back to a text so that the final text resembles the initial text as much as possible.” A neural network that’s been trained to learn this kind of function is called an autoencoder. An autoencoder can function as a generative model: obtain a novel point in code space in some way (by picking at random or just mixing some known points together), and if the model has learned a good representation of the data, decoding this point will result in novel text. As this isn’t technically part of an autoencoder’s specification, the literature appears divided on how correct it is to refer to it as a generative model, as opposed to a model with generative capacity (have fun with this Google search); but “model with generative capacity” did not fit so neatly into the main title, so here we are.
人工神经网络具有学习各种函数的惊人能力(这甚至在理论上得到了证明)。其中一个功能就是简单地“将此文本映射到一些简短的表示形式(代码),然后将代码更改回文本,以便最终文本尽可能类似于初始文本。经过训练来学习这种函数的神经网络称为自动编码器。自动编码器可以用作生成模型:以某种方式(通过随机选择或只是将一些已知点混合在一起)在代码空间中获取一个新点,如果模型已经学会了数据的良好表示,解码该点将产生新颖的文本。由于这在技术上不是自动编码器规范的一部分,因此文献似乎对将其称为生成模型而不是具有生成能力的模型的正确性存在分歧(享受此Google搜索的乐趣);但是“具有生成能力的模型”并没有那么整齐地融入主标题,所以我们来了。

TUNNEL WARFARE: EXPOSING DNS TUNNELING CAMPAIGNS USING GENERATIVE MODELS – COINLOADER CASE STUDY
Figure 3 – Schematic structure of an autoencoder.
图 3 – 自动编码器的原理图结构。

One other use case for autoencoders, which is relevant here, is that of anomaly detection. Applying some mathematical intuition will lead you to the conclusion that “typical” input will be compressed and reconstructed by the autoencoder with relative success, whereas compression and reconstruction of “atypical” input is more likely to introduce errors. This is basically for the same reason that if I say “the quick brown fox jumps over the lazy dog” then five minutes later ask you to repeat that sentence, you will probably succeed, but the same is not true for “the abstruse purple platypus confounds the prolific cheetah”.
自动编码器的另一个用例(此处与此相关)是异常检测。应用一些数学直觉将使您得出结论,“典型”输入将由自动编码器压缩和重建,并相对成功,而“非典型”输入的压缩和重建更有可能引入错误。这基本上是出于同样的原因,如果我说“敏捷的棕色狐狸跳过懒惰的狗”,那么五分钟后让你重复这句话,你可能会成功,但对于“深奥的紫色鸭嘴兽迷惑了多产的猎豹”来说,情况并非如此。

DeepDNS works on this same principle. Using deep inspection of subdomain names which are further broken down into smaller constituent parts, it uses the encode-decode process that it learned to render its judgment on the simple question, “how normal does this set of queries look?” If the reconstruction sufficiently fails, DeepDNS concludes that the answer is “not normal enough”, and delivers a malicious verdict. This approach is elegant in its simplicity, if you ignore the part where training the model involves colorful floating surfaces and a bunch of partial derivatives.
DeepDNS的工作原理相同。通过对子域名的深入检查,这些子域名被进一步分解为更小的组成部分,它使用它学会的编码-解码过程来判断一个简单的问题,“这组查询看起来有多正常?如果重建足够失败,DeepDNS会得出结论,答案“不够正常”,并给出恶意的判决。这种方法在简单性中是优雅的,如果你忽略训练模型涉及彩色浮动表面和一堆偏导数的部分。

At the End of the Tunnel – Fishing Out and Drilling Down into CoinLoader DNS Tunneling
在隧道的尽头 – 钓鱼并深入到CoinLoader DNS隧道

Now that we’ve covered the theory, it’s time to put it into practice. Knowing how DeepDNS works at the black box level (and even some of its inner workings thanks to the section above), it is natural to ask what it can find if we make it search for anomalies across our available telemetry. We did just that and ran DeepDNS on our sample. Among the many results that it flagged as anomalous, one previously unknown cluster of domains caught our eye in particular:
现在我们已经介绍了这个理论,是时候把它付诸实践了。了解 DeepDNS 在黑盒级别的工作方式(甚至由于上面的部分,它的一些内部工作原理),很自然地会问如果我们让它在可用的遥测中搜索异常,它会发现什么。我们就是这样做的,并在我们的样本上运行了DeepDNS。在它标记为异常的众多结果中,一个以前未知的域集群特别引起了我们的注意:

  • rqmetrixsdn[.]info
  • candatamsnsdn[.]info
  • mapdatamsnsdn[.]info

A closer look at the infrastructure connected with these domains suggests they are part of a DNS backup channel used for CoinLoader infections.
仔细观察与这些域连接的基础设施,表明它们是用于CoinLoader感染的DNS备份通道的一部分。

Coinloader was first described in this extensive report by Avira, but we could not find prior documentation describing this specific feature. Samples were found in an archive, typically a rar or a zip, containing several files. While the names varied, what you see below is more or less representative of the file structure in each sample.
Coinloader 最初是由 Avira 在这篇详尽的报告中描述的,但我们找不到描述此特定功能的先前文档。样本是在包含多个文件的档案中找到的,通常是 zip a rar 或 a。虽然名称各不相同,但您在下面看到的内容或多或少代表了每个示例中的文件结构。

TUNNEL WARFARE: EXPOSING DNS TUNNELING CAMPAIGNS USING GENERATIVE MODELS – COINLOADER CASE STUDY
Figure 4 – CoinLoader file structure.
图 4 – 硬币加载器文件结构。

The executable (ZD_1.4.24.17 in the image) is always some legitimate tool which is used for DLL sideloading. The main malicious logic is in the sideloaded DLL (here AppleVersions.dll). Upon being loaded, it goes through several layers of unpacking, including a well-obfuscated check that its parent process was launched from inside the Z-1-36-81 directory (again, the directory name varies from sample to sample) that is buried inside some complex control flow structures.
可执行文件( ZD_1.4.24.17 在图像中)始终是用于DLL旁加载的合法工具。主要的恶意逻辑在旁加载的 DLL 中(此处 AppleVersions.dll )。加载后,它会经历几层解压缩,包括一个经过良好混淆的检查,其父进程是否从目录内部启动(同样,目录名称因样本而异),该 Z-1-36-81 目录隐藏在一些复杂的控制流结构中。

TUNNEL WARFARE: EXPOSING DNS TUNNELING CAMPAIGNS USING GENERATIVE MODELS – COINLOADER CASE STUDY
Figure 5 – CoinLoader execution flow.
图 5 – 硬币加载器执行流程。

Once unpacking is complete, the malicious logic is visible. This final stage still contains several anti-analysis features, such as junk code; encrypted stack strings that are decrypted on-the-fly using a simple substitution cipher; and indirect calls that are resolved using a homebrew function table, in which the register points at what is passed to each function in ecx. This is then copied to a random register each time, which is used to implement the calls.
解包完成后,恶意逻辑可见。这个最后阶段仍然包含几个反分析功能,例如垃圾代码;使用简单的替换密码即时解密的加密堆栈字符串;以及使用 Homebrew 函数表解析的间接调用,其中寄存器指向传递给 中 ecx 每个函数的内容。 然后每次将其复制到随机寄存器,用于实现调用。

TUNNEL WARFARE: EXPOSING DNS TUNNELING CAMPAIGNS USING GENERATIVE MODELS – COINLOADER CASE STUDY
Figure 6 – Junk instructions used as anti-analysis.
图 6 – 用作反分析的垃圾指令。
TUNNEL WARFARE: EXPOSING DNS TUNNELING CAMPAIGNS USING GENERATIVE MODELS – COINLOADER CASE STUDY
Figure 7 – Obfuscated stack strings.
图 7 – 经过模糊处理的堆栈字符串。
TUNNEL WARFARE: EXPOSING DNS TUNNELING CAMPAIGNS USING GENERATIVE MODELS – COINLOADER CASE STUDY
Figure 8 – Indirect calls using homebrew function table.
图 8 – 使用自制函数表的间接调用。

While the junk code is best ignored and the obfuscated strings are best dealt with by dynamically executing the code and observing the decoder output, the resolution of the function calls in the IDA database requires a dedicated script. To see such a script, go to Appendix A.
虽然最好忽略垃圾代码,最好通过动态执行代码并观察解码器输出来处理混淆字符串,但解析 IDA 数据库中的函数调用需要专用脚本。若要查看此类脚本,请转到附录 A。

The traffic capture generated by one such sample seemed promising:
一个这样的样本生成的流量捕获似乎很有希望:

TUNNEL WARFARE: EXPOSING DNS TUNNELING CAMPAIGNS USING GENERATIVE MODELS – COINLOADER CASE STUDY
Figure 9 – Packets captured in CoinLoader execution.
图 9 – 在 CoinLoader 执行中捕获的数据包。

So we set out to perform a technical analysis of this feature.
因此,我们开始对此功能进行技术分析。

The function get_c2_domain receives an enum argument (here passed in the register edx). The values 0, 1, 2 and 3 cause the function to decrypt and return, respectively, each of the malware’s hardcoded C&C domain names — in this case rqmetrixa.inforqmetrixb.inforqmetrixc.inforqmetrixd.info (we were honestly disappointed not to find some piece of logic appending a letter to rqmetrix but these were all hardcoded as-is).
该函数 get_c2_domain 接收一个枚举参数(此处在寄存器 edx 中传递)。值 0、1、2 和 3 导致函数分别解密并返回每个恶意软件的硬编码 C&C 域名——在本例 rqmetrixa.info 中为 、、、 rqmetrixb.info rqmetrixc.info ( rqmetrixd.info 老实说,我们很失望没有找到一些逻辑附加一个字母 rqmetrix ,但这些都是硬编码的)。

TUNNEL WARFARE: EXPOSING DNS TUNNELING CAMPAIGNS USING GENERATIVE MODELS – COINLOADER CASE STUDY
Figure 10 – Different switch branches of the “get c2” function.
图 10 – “get c2”函数的不同开关分支。

Finally, if this enum value equals 4 (above annotated as GET_DOMAIN_DNS_TUNNEL_BACKUP), the malware resorts to a backup plan, and attempts to obtain a domain name by conferring with a different server, rqmetrixsdn.info, via the TXT DNS tunneling query as seen in the traffic capture.
最后,如果此枚举值等于 4(上面注释为 GET_DOMAIN_DNS_TUNNEL_BACKUP ),则恶意软件会求助于备份计划,并尝试通过流量捕获中所示的 TXT DNS 隧道查询与其他服务器 rqmetrixsdn.info 协商来获取域名。

TUNNEL WARFARE: EXPOSING DNS TUNNELING CAMPAIGNS USING GENERATIVE MODELS – COINLOADER CASE STUDY
Figure 11 – DNS TXT query.
图 11 – DNS TXT 查询。

The FQDN is created by taking one of the hardcoded domains and prepending to it hexlify(md5(timestamp)). In the image below we show it as a code block to filter out junk instructions.
FQDN 是通过采用其中一个硬编码域并在其前面添加前缀来创建 hexlify(md5(timestamp)) 的。在下图中,我们将其显示为代码块以过滤掉垃圾指令。

mov ebx, eax
MOV EBX, EAX
mov [ebp+md5_of_timestamp], ebx
MOV [EBP+md5_of_timestamp], EBX
call [edi+FuncTable.GetSystemTime]
call [edi+FuncTable.GetSystemTime]
xor eax, eax
Xor EAX, EAX
mov [esi+0Eh], ax
mov [esi+0Eh], ax
push ebx ; allocated buffer
推 EBX ;分配的缓冲区
call mre_get_filetime_md5 ; now has md5 of current timestamp
呼叫mre_get_filetime_md5 ;现在具有当前时间戳的MD5

The timestamp md5 is obtained using SystemFileToFileTime (then converted into a timestamp using additional WinAPI functions). Once the server responds, its response is fed to an inline BASE64 decoder. The result is interpreted as a C&C domain to check in with, similar to the SUNBURST setup that we mentioned earlier. The check-in format, which is the output of the string_decoder deobfuscation handler, is visible below.
时间戳 md5 是使用 (然后使用其他 WinAPI 函数转换为时间戳) 获取 SystemFileToFileTime 的。服务器响应后,其响应将馈送到内联 BASE64 解码器。结果被解释为要签入的C&C域,类似于我们之前提到的SUNBURST设置。签入格式(即 string_decoder 去混淆处理程序的输出)如下所示。

TUNNEL WARFARE: EXPOSING DNS TUNNELING CAMPAIGNS USING GENERATIVE MODELS – COINLOADER CASE STUDY
Figure 12 – Construction of C&C check-in.
图12 – C&C签到的构造。

Conclusion 结论

DNS tunneling is what you might call an “old-school” technique. It originated in a security landscape created by the advent of the first firewalls, and the drawing of simplistic boundaries: who initiated a connection? With whom? On what port? Using what protocol? Therefore allow, or deny. The industry has since greatly evolved and the benefits of DNS tunneling have become less clear-cut. DNS is no longer some “covert channel” where no security solution would think to look; and conversely, attackers have refined their understanding of how to effectively communicate using HTTP and hide in plain sight, using a variety of techniques such as steganography and encryption.
DNS 隧道是您可能称之为“老式”技术。它起源于第一个防火墙的出现以及简单边界的绘制所创造的安全环境:谁发起了连接?和谁在一起?在什么端口上?使用什么协议?因此,允许或拒绝。此后,该行业发生了巨大的变化,DNS隧道的好处变得不那么明显。DNS 不再是没有安全解决方案会想到的“隐蔽渠道”;相反,攻击者已经完善了他们对如何使用HTTP有效通信和使用隐写术和加密等各种技术隐藏在众目睽睽之下的理解。

Still, DNS tunneling is clearly not dead. Whether because it less obviously jumps out at the human eye, or because malware authors simply figure the technique is worth a try if straightforward HTTP communication has failed — or for other reasons — modern malware is not shy to engage in this practice. As defenders, we are naturally interested in ways of catching it in the act. In this post, we explained how it is possible to model DNS tunnels as anomalies and hunt them from an unusual perspective, as demonstrated with DeepDNS. This hunt has led us to evidence of a number of actors currently using the technique, including state-sponsored cybercriminals and even hacktivists. As an example, we performed a technical analysis of a Coinlander sample and its tunneling protocol that DeepDNS sniffed out as anomalous. Other than its natural interest to us as threat hunters, this also served as a nice proof-of-concept for DeepDNS’s capabilities.
尽管如此,DNS隧道显然并没有消亡。无论是因为它不太明显地跳出人眼,还是因为恶意软件作者只是认为如果简单的HTTP通信失败,或者由于其他原因,该技术值得一试,现代恶意软件并不羞于参与这种做法。作为捍卫者,我们自然会对在行动中抓住它的方式感兴趣。在这篇文章中,我们解释了如何将DNS隧道建模为异常并从不寻常的角度搜寻它们,如DeepDNS所示。这次狩猎使我们发现了许多目前正在使用该技术的行为者的证据,包括国家资助的网络犯罪分子甚至黑客活动家。例如,我们对Coinlander样本及其隧道协议进行了技术分析,DeepDNS将其嗅出为异常。除了作为威胁猎人的我们自然兴趣之外,这也是DeepDNS功能的一个很好的概念验证。

While academia carries the torch of pushing scientific boundaries and proving what is possible, it often falls to industry to implement academic ideas at scale, and usher them along the path from promising whitepaper to surviving impact with the messy real world. While we continuously work to apply ANNs to security at that level of maturity, the frontier is far from exhausted. With the recent surge of interest in ANNs and their applications, we can only expect more and more artificial brains to be making real-world security decisions, and it is our responsibility as an industry that they do so with skill and accountability.
虽然学术界高举着推动科学界限和证明可能性的火炬,但工业界经常需要大规模实施学术理念,并引导它们从有希望的白皮书到在混乱的现实世界中幸存下来。虽然我们不断努力将人工神经网络应用于成熟度的安全,但前沿还远未耗尽。随着最近对人工神经网络及其应用的兴趣激增,我们只能期待越来越多的人工大脑做出现实世界的安全决策,作为一个行业,我们有责任以技能和责任感做到这一点。

So, in that spirit, let this article be a testament to that time when we said “Oh, model, you say that’s DNS tunneling? Let our analysts and reverse-engineers double-check you on that”.
所以,本着这种精神,让这篇文章成为那个时代的证明,当时我们说“哦,模型,你说这是DNS隧道?让我们的分析师和逆向工程师仔细检查您”。

Indicators of Compromise
妥协指标

CoinLoader Samples 硬币加载器示例

a05144d7254b419d3a09787e280b4be3
84548cf16e26979ff9a3fa2b3f854f34

CoinLoader Infrastructure
投币机基础设施

candatamsnsdn[.]info Candatamsnsdn[.]信息
candatamsna[.]info Candatamsna[.]信息
candatamsnb[.]info Candatamsnb[.]信息
candatamsnc[.]info Candatamsnc[.]信息
candatamsnd[.]info Candatamsnd[.]信息
mapdatamsnsdn[.]info mapdatamsnsdn[.]信息
mapdatamsna[.]info mapdatamsna[.]信息
mapdatamsnb[.]info mapdatamsnb[.]信息
mapdatamsnc[.]info 地图数据MSNC[.]信息
mapdatamsnd[.]info mapdatamsnd[.]信息
rqmetrixsdn[.]info rqmetrixsdn[.]信息
rqmetrixa[.]info rqmetrixa[.]信息
rqmetrixb[.]info rqmetrixb[.]信息
rqmetrixc[.]info rqmetrixc[.]信息
rqmetrixd[.]info rqmetrixd[.]信息

Check Point Software Customers remain protected against the threat described in this research.
Check Point Software 客户仍然受到保护,免受本研究中描述的威胁。

Check Point Threat Emulation and Harmony Endpoint provide comprehensive coverage of attack tactics and is protecting against the type of attacks and threats described in this report.
检查点威胁仿真和和谐端点提供全面的攻击策略覆盖,并针对本报告中描述的攻击和威胁类型提供保护。

Check Point Harmony Endpoint:
检查点协调端点:

APT.Win.Coinloader.B 容易。赢.硬币加载器.B
APT.Win.Coinloader.C 容易。Win.Coinloader.C

Check Point Threat Emulation:
检查点威胁仿真:

APT.Wins.Coinloader.A 容易。Wins.Coinloader.A
APT.Wins.Coinloader.D 容易。Wins.Coinloader.D

Appendix A — Python script for resolving indirectly called functions in the final stage of Coinloader
附录A — 用于解析 Coinloader 最后阶段间接调用函数的 Python 脚本

(Requires function table ripped from memory — sample function table included below.)
(需要从内存中翻录函数表 — 下面包含的示例函数表。

from abc import ABC, abstractmethod, abstractclassmethod
从 abc 导入 ABC, 抽象方法, 抽象类方法
from typing import List, Tuple, NewType, Dict, Set, Callable, TypeVar, Any, cast, Optional
从键入导入列表、元组、新类型、字典、设置、可调用、类型变量、任何、强制转换、可选
from functools import wraps
从 functools 导入换行
from enum import Enum 从枚举导入枚举
import sys 导入系统
FuncT = TypeVar(“FuncT”, bound=Callable[…,Any])
FuncT = TypeVar(“FuncT”, bound=Callable[…,Any])
try: 尝试:
import idc #type: ignore
导入 IDC #type:忽略
import idautils #type: ignore
导入 idautils #type:忽略
import ida_struct #type: ignore
导入ida_struct #type:忽略
import ida_bytes #type: ignore
导入ida_bytes #type:忽略
import ida_idaapi #type: ignore
导入ida_idaapi #type:忽略
except ModuleNotFoundError:
除了 ModuleNotFoundError:
pass #ok, not running within IDA
传递 #ok,不在 IDA 内运行
#IDA
def ida(func: FuncT)> FuncT:
def ida(func: FuncT) -> FuncT:
ida_modules = set([“idc”,“idaapi”])
ida_modules = set([“idc”,“idaapi”])
@wraps(func)
def wrapper_ida_check(*args: Any, **kwargs: Any)> Any:
def wrapper_ida_check(*args: Any, **kwargs: Any) -> Any:
if not set(sys.modules).issuperset(ida_modules):
如果不是 set(sys.modules).issuperset(ida_modules):
print(“ERROR: IDA function called outside IDA context!”)
print(“错误:在 IDA 上下文之外调用 IDA 函数!
raise NotImplementedError
引发未实现错误
return func(*args, **kwargs)
return func(*args, **kwargs)
return cast(FuncT, wrapper_ida_check)
回程铸件(wrapper_ida_check)
class OPERAND_TYPE(Enum):
类 OPERAND_TYPE(枚举):
o_void = 0
o_void = 0
o_reg = 1
o_reg = 1
o_mem = 2
o_mem = 2
o_phrase = 3
o_phrase = 3
o_displ = 4
o_displ = 4
o_imm = 5
o_imm = 5
o_far = 6
o_far = 6
o_near = 7
o_near = 7
o_idpspec0 = 8
o_idpspec0 = 8
o_idpspec1 = 9
o_idpspec1 = 9
o_idpspec2 = 10
o_idpspec2 = 10
o_idpspec3 = 11
o_idpspec3 = 11
o_idpspec4 = 12
o_idpspec4 = 12
o_idpspec5 = 13
o_idpspec5 = 13
Addr = NewType(“Addr”,int)
Addr = NewType(“Addr”,int)
#Functable
class Functable(ABC): 类函数(ABC):
@abstractmethod
def funcname_from_offset(self, addr: Addr)> str:
def funcname_from_offset(self, addr: addr) -> str:
raise NotImplementedError
引发未实现错误
@abstractmethod
def as_dict(self)> Dict[Addr, str]:
def as_dict(self) -> Dict[Addr, str]:
raise NotImplementedError
引发未实现错误
@ida
@abstractmethod
def ida_struct_id(self)> int:
def ida_struct_id(self) -> int:
raise NotImplementedError
引发未实现错误
@abstractclassmethod
def from_file(cls, fname: str)> “Functable”:
def from_file(cls, fname: str) -> “Functable”:
raise NotImplementedError
引发未实现错误
class _Functable(Functable):
类 _Functable(可函数):
def __init__(self, base: Addr, addr_contents: List[Tuple[Addr,str]])> None:
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.content_by_addr = {k: v for (k,v) in addr_contents}
self.struct_id = None
self.struct_id = 无
def funcname_from_offset(self, offset: int)> str:
def funcname_from_offset(self, offset: int) -> str:
return self.content_by_addr[Addr(self.base+offset)]
return self.content_by_addr[addr(self.base+offset)]
def as_dict(self)> Dict[Addr, str]:
def as_dict(self) -> Dict[Addr, str]:
return self.content_by_addr
返回self.content_by_addr
@ida
def ida_struct_id(self)> int:
def ida_struct_id(self) -> int:
if self.struct_id is None:
如果self.struct_id为“无”:
self.struct_id = ida_struct.add_struc(ida_idaapi.BADADDR, “FuncTable”, False)
self.struct_id = ida_struct.add_struc(ida_idaapi.BADADDR, “FuncTable”, False)
struct_ptr = ida_struct.get_struc(self.struct_id)
struct_ptr = ida_struct.get_struc(self.struct_id)
for (addr, funcname) in sorted(self.as_dict().items(), key = lambda item: item[0]):
对于 (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)
ida_struct.add_struc_member(struct_ptr, funcname, addr-self.base, ida_bytes.dword_flag(), None, 4)
return self.struct_id #type: ignore
返回self.struct_id #type:忽略
@classmethod
def from_file(cls, fname: str)> “_Functable”:
def from_file(cls, fname: str) -> “_Functable”:
with open(fname, “r”) as fh:
使用 open(fname, “r”) 作为 fh:
tokenized_entrylist = [line.strip().split(” “) for line in fh.readlines()]
tokenized_entrylist = [line.strip().split(“ ”) for line in fh.readlines()]
base = Addr(int(tokenized_entrylist[0][0],16))
base = Addr(int(tokenized_entrylist[0][0],16))
addr_contents : List[Tuple[Addr,str]] = []
addr_contents : 列表[元组[地址,str]] = []
for tokenized_entry in tokenized_entrylist:
对于tokenized_entrylist tokenized_entry:
if len(tokenized_entry) > 2:
如果 len(tokenized_entry) > 2:
addr_contents.append((
addr_contents.append((
Addr(int(tokenized_entry[0],16)),
Addr(int(tokenized_entry[0],16)),
tokenized_entry[2].replace(“!”,“_”)
tokenized_entry[2].replace(“!”,“_”)
))
return _Functable(base, addr_contents)
返回_Functable(基本,addr_contents)
#CoinLoaderFunction
class CoinLoaderFunction(ABC):
类 CoinLoaderFunction(ABC):
@ida
@abstractmethod
def functable_register(self)> Optional[str]:
def functable_register(self) -> Optional[str]:
raise NotImplementedError
引发未实现错误
@ida
@abstractmethod
def heads(self)> List[Addr]:
def heads(self) -> List[Addr]:
raise NotImplementedError
引发未实现错误
@ida
@abstractmethod
def is_indirect_call(self, addr: Addr)> bool:
def is_indirect_call(self, addr: addr) -> bool:
raise NotImplementedError
引发未实现错误
@ida
@abstractmethod
def all_indirect_calls(self)> Dict[Addr,int]:
def all_indirect_calls(self) -> dict[addr,int]:
raise NotImplementedError
引发未实现错误
@ida
@abstractmethod
def patch_single_indirect_call(self, ea: Addr, ft: Functable)> None:
def patch_single_indirect_call(self, ea: addr, ft: funtable) -> None:
raise NotImplementedError
引发未实现错误
@ida
@abstractmethod
def patch_indirect_calls(self, ft: Functable)> None:
def patch_indirect_calls(self, ft: Funcable) -> None:
raise NotImplementedError
引发未实现错误
@ida
@abstractclassmethod
def from_addr(cls, addr: Addr)> “CoinLoaderFunction”:
def from_addr(cls, addr:addr) -> “CoinLoaderFunction”:
raise NotImplementedError
引发未实现错误
class _CoinLoaderFunction(CoinLoaderFunction):
类_CoinLoaderFunction(CoinLoaderFunction):
@ida
def __init__(self, addr: Addr)> None:
def __init__(self, addr: addr) -> None:
self.addr = addr
self.addr = addr
self._functable_register = self.functable_register()
self._functable_register = self.functable_register()
@ida
def heads(self)> List[Addr]:
def heads(self) -> List[Addr]:
return [insn for bound in idautils.Chunks(self.addr) for insn in idautils.Heads(*bound)]
返回 [INSN 表示在 Idautils 中绑定。Chunks(self.addr) for insn in idautils.头(*绑定)]
@ida
def is_regload_insn(self, ea: Addr)> bool:
def is_regload_insn(self, ea: addr) -> bool:
if idc.print_insn_mnem(ea) != “mov”: return False
如果 idc.print_insn_mnem(ea) != “mov”:返回 False
for i in (0,1):
对于 (0,1) 中的 i:
if OPERAND_TYPE(idc.get_operand_type(ea,i)) != OPERAND_TYPE.o_reg:
如果 OPERAND_TYPE(idc.get_operand_type(ea,i)) != OPERAND_TYPE.o_reg:
return False
返回假
if idc.print_operand(ea,1) != “ecx”: return False
如果 idc.print_operand(ea,1) != “ecx”:返回 False
return True
返回真
@ida
def functable_register(self)> Optional[str]:
def functable_register(self) -> Optional[str]:
try:
尝试:
regload_insn = next(filter(self.is_regload_insn, self.heads()))
regload_insn = next(filter(self.is_regload_insn, self.heads()))
return idc.print_operand(regload_insn,0) #type: ignore
返回idc.print_operand(regload_insn,0) #type:忽略
except StopIteration:
停止迭代除外:
return None
返回 无
@ida
def is_indirect_call(self, ea: Addr)> bool:
def is_indirect_call(self, ea: addr) -> bool:
if self._functable_register is None: return False
如果self._functable_register为“无”:返回 False
if idc.print_insn_mnem(ea) != “call”: return False
如果 idc.print_insn_mnem(ea) != “调用”:返回 False
if OPERAND_TYPE(idc.get_operand_type(ea,0)) != OPERAND_TYPE.o_displ: return False
如果 OPERAND_TYPE(idc.get_operand_type(ea,0)) != OPERAND_TYPE.o_displ: 返回 False
if not idc.print_operand(ea,0).startswith(“dword ptr [“+self._functable_register+“+”): return False
如果不是 idc.print_operand(ea,0).startswith(“dword ptr [”+self._functable_register+“+”):返回 False
return True
返回真
@ida
def all_indirect_calls(self)> Dict[Addr,int]:
def all_indirect_calls(self) -> dict[addr,int]:
eas = [h for h in self.heads() if self.is_indirect_call(h)]
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}
返回 (A) 空气中空气的idc.get_operand_value
@ida
def patch_single_indirect_call(self, ea: Addr, ft: Functable)> None:
def patch_single_indirect_call(self, ea: addr, ft: funtable) -> None:
sid = ft.ida_struct_id()
sid = ft.ida_struct_id()
if sid is None:
如果 sid 为“无”:
print(“Cannot patch, functable doesn’t have IDA struct”)
print(“无法修补,函数没有 IDA 结构”)
print(“Use: functable.create_struct()”)
打印(“使用: functable.create_struct()”)
idc.op_stroff(ea, 0, sid,0)
idc.op_stroff(ea, 0, sid,0)
@ida
def patch_indirect_calls(self, ft: Functable)> None:
def patch_indirect_calls(self, ft: Funcable) -> None:
for call in self.all_indirect_calls():
对于在 self.all_indirect_calls() 中调用:
self.patch_single_indirect_call(call,ft)
self.patch_single_indirect_call(通话,英尺)
@ida
@classmethod
def from_addr(cls, addr: Addr)> “CoinLoaderFunction”:
def from_addr(cls, addr:addr) -> “CoinLoaderFunction”:
return _CoinLoaderFunction(addr)
返回_CoinLoaderFunction(地址)
def patch_indirect_calls_all_functions(ft: Functable):
def patch_indirect_calls_all_functions(ft: funcable):
for ea in idautils.Functions():
对于 EA 在 Idautils。函数():
clf : CoinLoaderFunction = _CoinLoaderFunction(ea)
clf : CoinLoaderFunction = _CoinLoaderFunction(ea)
clf.patch_indirect_calls(ft)
clf.patch_indirect_calls(英尺)
def test_get_name()> None:
def test_get_name() -> 无:
f = _Functable.from_file(“functable.txt”)
f = _Functable.from_file(“functable.txt”)
assert(f.funcname_from_offset(0x0) == “kernel32_OpenProcess”)
assert(f.funcname_from_offset(0x0) == “kernel32_OpenProcess”)
assert(f.funcname_from_offset(0x4) == “kernel32_VirtualProtect”)
assert(f.funcname_from_offset(0x4) == “kernel32_VirtualProtect”)

Sample function table: 示例函数表:

0x26cfb94 0x7dd71986 OpenProcess
0x26cfb94 0x7dd71986 开放流程
0x26cfb98 0x7dd7435f VirtualProtect
0x26cfb98 0x7dd7435f 虚拟保护
0x26cfb9c 0x7dd711c0 GetLastError_0
0x26cfba0 0x7dd74913 LoadLibraryExA
0x26cfba0 0x7dd74913 加载库ExA
0x26cfba4 0x7dd8e4be GlobalReAlloc
0x26cfba4 0x7dd8e4be 全球再分配
0x26cfba8 0x7dd7588e GlobalAlloc
0x26cfba8 0x7dd7588e 全球阿洛克
0x26cfbac 0x7dd734d5 CreateThread
0x26cfbac 0x7dd734d5 创建线程
0x26cfbb0 0x7dd8d16f GlobalSize
0x26cfbb0 0x7dd8d16f 全球规模
0x26cfbb4 0x7dd7492b LoadLibraryW_0
0x26cfbb8 0x7dd71856 VirtualAlloc
0x26cfbb8 0x7dd71856 虚拟分配
0x26cfbbc 0x7dd71072 CreateProcessA
0x26cfbbc 0x7dd71072 创建进程A
0x26cfbc0 0x7dd7495d LoadLibraryExW
0x26cfbc0 0x7dd7495d 加载库ExW
0x26cfbc4 0x7dd77a10 ExitProcess
0x26cfbc4 0x7dd77a10退出流程
0x26cfbc8 0x7dd732bb SetThreadPriority
0x26cfbc8 0x7dd732bb 设置线程优先级
0x26cfbcc 0x7dd7186e VirtualFree
0x26cfbcc 0x7dd7186e 虚拟免费
0x26cfbd0 0x7dd7168c LocalAlloc_0
0x26cfbd4 0x7dd734c8 FreeLibrary_0
0x26cfbd8 0x7dd75558 GlobalFree
0x26cfbd8 0x7dd75558 全球免费
0x26cfbdc 0x7dd72d3c LocalFree
0x26cfbdc 0x7dd72d3c 本地免费
0x26cfbe0 0x7ddeaeee SetFileCompletionNotificationModes
0x26cfbe0 0x7ddeaeee设置文件完成通知模式
0x26cfbe4 0x7dd8cf28 SetPriorityClass
0x26cfbe4 0x7dd8cf28 设置优先级类
0x26cfbe8 0x7dd93102 lstrcpyW
0x26cfbec 0x7dd75971 FindResourceW
0x26cfbec 0x7dd75971 查找资源W
0x26cfbf0 0x7dd8ecbb SetFileTime
0x26cfbf0 0x7dd8ecbb设置文件时间
0x26cfbf4 0x7dd71809 GetCurrentProcess_0
0x26cfbf8 0x7dd7e2ce FindFirstFileA
0x26cfbf8 0x7dd7e2ce 查找第一个文件A
0x26cfbfc 0x7dd8e9bb FindResourceA
0x26cfbfc 0x7dd8e9bb 查找资源A
0x26cfc00 0x7dd734b0 GetModuleHandleW
0x26cfc04 0x7dd741f0 QueryPerformanceFrequency
0x26cfc04 0x7dd741f0 查询性能频率
0x26cfc08 0x7dd9d53e FindNextFileA
0x26cfc08 0x7dd9d53e 查找下一个文件A
0x26cfc0c 0x7dd75444 DeleteFileA
0x26cfc0c 0x7dd75444 删除文件A
0x26cfc10 0x7dd9cb05 RegisterWaitForSingleObject
0x26cfc10 0x7dd9cb05 注册等待单一对象
0x26cfc14 0x7ddf453f SetNamedPipeHandleState
0x26cfc18 0x7dd9691f K32EnumProcesses
0x26cfc1c 0x7dd8d3ab ReleaseSemaphore
0x26cfc1c 0x7dd8d3ab发布信号量
0x26cfc20 0x7dd75a4b lstrlen
0x26cfc20 0x7dd75a4b 斯特伦
0x26cfc24 0x7df720c0  0x26cfc24 0x7df720c0
0x26cfc28 0x7dd8192a lstrcpyn
0x26cfc2c 0x7dd997aa GetSystemWindowsDirectoryA
0x26cfc2c 0x7dd997aa 获取系统Windows目录A
0x26cfc30 0x7ddf1807 CreateNamedPipeA
0x26cfc30 0x7ddf1807 创建命名管道A
0x26cfc34 0x7dd743ef ResumeThread
0x26cfc34 0x7dd743ef 恢复线程
0x26cfc38 0x7dd75ac9 SizeofResource
0x26cfc38 0x7dd75ac9资源大小
0x26cfc3c 0x7dd749ca GetSystemInfo
0x26cfc3c 0x7dd749ca获取系统信息
0x26cfc40 0x7dd71282 WriteFile
0x26cfc40 0x7dd71282写文件
0x26cfc44 0x7dd73f5c CreateFileW
0x26cfc44 0x7dd73f5c 创建文件W
0x26cfc48 0x7dd75959 LockResource
0x26cfc48 0x7dd75959锁资源
0x26cfc4c 0x7dd7170d WideCharToMultiByte_0
0x26cfc50 0x7dd716c5 SetEvent
0x26cfc50 0x7dd716c5集事件
0x26cfc54 0x7ddf498e QueryFullProcessImageNameA
0x26cfc54 0x7ddf498e 查询完整进程图像名称A
0x26cfc58 0x7dd71725 QueryPerformanceCounter_0
0x26cfc5c 0x7dd905a0 SetThreadAffinityMask
0x26cfc60 0x7ddf44bf RemoveDirectoryA
0x26cfc60 0x7ddf44bf 删除目录A
0x26cfc64 0x7dd8ca5a CreateSemaphoreW
0x26cfc64 0x7dd8ca5a 创建信号量
0x26cfc68 0x7dd717ec GetCurrentThread
0x26cfc68 0x7dd717ec 获取当前线程
0x26cfc6c 0x7dd74f2b FlsAlloc
0x26cfc6c 0x7dd74f2b 弗洛尔斯阿洛克
0x26cfc70 0x7dd7183e CreateEventW
0x26cfc70 0x7dd7183e 创建事件W
0x26cfc74 0x7dd751a1 GetCommandLineA
0x26cfc74 0x7dd751a1 获取命令行A
0x26cfc78 0x7dd8b6e0 GetComputerNameA
0x26cfc78 0x7dd8b6e0 获取计算机名称A
0x26cfc7c 0x7dd75611 GetCurrentDirectoryW
0x26cfc7c 0x7dd75611 获取当前目录W
0x26cfc80 0x7dd8eceb lstrcmp
0x26cfc84 0x7dd92a9d lstrcpy
0x26cfc84 0x7dd92a9d
0x26cfc88 0x7dd74208 FlsSetValue
0x26cfc8c 0x7ddfe6ab UnregisterWait
0x26cfc8c 0x7ddfe6ab 注销等待
0x26cfc90 0x7dd71245 GetModuleHandleA
0x26cfc94 0x7dd9276c GetTempPathA
0x26cfc94 0x7dd9276c 获取温度路径A
0x26cfc98 0x7dd8ecd3 SetFileAttributesA
0x26cfc98 0x7dd8ecd3 设置文件属性A
0x26cfc9c 0x7dd7195e IsWow64Process
0x26cfc9c 0x7dd7195e IsWow64进程
0x26cfca0 0x7dd7469b FlushFileBuffers
0x26cfca0 0x7dd7469b刷新文件缓冲区
0x26cfca4 0x7dd75a7e SystemTimeToFileTime
0x26cfca4 0x7dd75a7e系统时间到文件时间
0x26cfca8 0x7dde3161 EnumResourceNamesW
0x26cfca8 0x7dde3161 枚举资源名称W
0x26cfcac 0x7dd8d650 Wow64DisableWow64FsRedirection
0x26cfcac 0x7dd8d650 哇64禁用哇64Fs重定向
0x26cfcb0 0x7ddf40fb ConnectNamedPipe
0x26cfcb0 0x7ddf40fb 连接命名管道
0x26cfcb4 0x7dd71b00 SetErrorMode
0x26cfcb4 0x7dd71b00 设置错误模式
0x26cfcb8 0x7dd8eef2 CreateIoCompletionPort
0x26cfcb8 0x7dd8eef2 创建完备端口
0x26cfcbc 0x7dd75aa6 GetLocalTime
0x26cfcbc 0x7dd75aa6 获取本地时间
0x26cfcc0 0x7dd74c6b CreateMutexA
0x26cfcc0 0x7dd74c6b 创建互斥A
0x26cfcc4 0x7dd7192e MultiByteToWideChar_0
0x26cfcc8 0x7dd7594c LoadResource
0x26cfcc8 0x7dd7594c负载资源
0x26cfccc 0x7dd74950 GetModuleFileNameW_0
0x26cfcd0 0x7dd8d3c3 GetQueuedCompletionStatus
0x26cfcd0 0x7dd8d3c3 获取队列完成状态
0x26cfcd4 0x7dd71410 CloseHandle_0
0x26cfcd8 0x7dd7359f FlsFree
0x26cfcdc 0x7dd8195c SetHandleInformation
0x26cfcdc 0x7dd8195c 设置句柄信息
0x26cfce0 0x7dd710ff Sleep_0
0x26cfce4 0x7dd714b1 GetModuleFileNameA
0x26cfce4 0x7dd714b1 获取模块文件名A
0x26cfce8 0x7dd8d668 Wow64RevertWow64FsRedirection
0x26cfce8 0x7dd8d668 哇64还原哇64Fs重定向
0x26cfcec 0x7dd96dcb GetVolumeInformationA
0x26cfcec 0x7dd96dcb 获取卷信息A
0x26cfcf0 0x7dd75a96 GetSystemTime
0x26cfcf0 0x7dd75a96 获取系统时间
0x26cfcf4 0x7dd73ed3 ReadFile
0x26cfcf4 0x7dd73ed3读取文件
0x26cfcf8 0x7dd9d526 CreateDirectoryA
0x26cfcf8 0x7dd9d526 创建目录A
0x26cfcfc 0x7dd7110c GetTickCount_0
0x26cfd00 0x7dd73e8e lstrcmpiA
0x26cfd04 0x7dd9ab72 EnumResourceNamesA
0x26cfd04 0x7dd9ab72 枚举资源名称A
0x26cfd08 0x7dd754ee FindNextFileW
0x26cfd08 0x7dd754ee 查找下一个文件W
0x26cfd0c 0x7ddf41df DisconnectNamedPipe
0x26cfd0c 0x7ddf41df 断开名称管道
0x26cfd10 0x7dd74435 FindFirstFileW
0x26cfd10 0x7dd74435 查找第一文件W
0x26cfd14 0x7dd8eb39 ExpandEnvironmentStringsA
0x26cfd14 0x7dd8eb39 展开环境字符串A
0x26cfd18 0x7dd75414 GetFileAttributesA
0x26cfd18 0x7dd75414 获取文件属性A
0x26cfd1c 0x7dd74220 WaitForMultipleObjects
0x26cfd1c 0x7dd74220 等待多个对象
0x26cfd20 0x7dd8d802 TerminateProcess_0
0x26cfd24 0x7dd74442 FindClose
0x26cfd24 0x7dd74442 查找关闭
0x26cfd28 0x7dded911 MoveFileA
0x26cfd28 0x7dded911 移动文件A
0x26cfd2c 0x7dd753c6 CreateFileA
0x26cfd2c 0x7dd753c6 创建文件A
0x26cfd30 0x7ddf43af GetQueuedCompletionStatusEx
0x26cfd34 0x7dd789b3 DeleteFileW
0x26cfd34 0x7dd789b3 删除文件W
0x26cfd38 0x7dd8ef29 PostQueuedCompletionStatus
0x26cfd38 0x7dd8ef29 队列后完成状态
0x26cfd3c 0x7dd74173 ExpandEnvironmentStringsW
0x26cfd3c 0x7dd74173 展开环境字符串W
0x26cfd40 0x7dd74407 GetFileTime
0x26cfd40 0x7dd74407 获取文件时间
0x26cfd44 0x7dd71136 WaitForSingleObject
0x26cfd44 0x7dd71136 等待单一对象
0x26cfd48 0x7dd716dd ResetEvent
0x26cfd48 0x7dd716dd重置事件
0x26cfd4c 0x7dd71252 FlsGetValue
0x26cfd50 0x7dd717d1 SetFilePointer
0x26cfd50 0x7dd717d1 设置文件指针
0x26cfd54 0x7dd71700 lstrlenW_0
0x26cfd58 0x7dd8efec SwitchToThread
0x26cfd58 0x7dd8efec 开关到线程
0x26cfd5c 0x77c69edf SetSecurityInfo
0x26cfd5c 0x77c69edf设置安全信息
0x26cfd60 0x77c8077c LsaOpenPolicy
0x26cfd64 0x77c740e6 AllocateAndInitializeSid
0x26cfd64 0x77c740e6 分配和初始化Sid
0x26cfd68 0x77c740fe RegCreateKeyExW
0x26cfd6c 0x77c741b3 LookupPrivilegeValueW
0x26cfd6c 0x77c741b3 查找特权值W
0x26cfd70 0x77c7431c GetTokenInformation
0x26cfd70 0x77c7431c 获取令牌信息
0x26cfd74 0x77cb15a0 SetNamedSecurityInfoA
0x26cfd78 0x77c7469d RegCloseKey_0
0x26cfd7c 0x77c81af7 LsaClose
0x26cfd80 0x77c74620 InitializeSecurityDescriptor
0x26cfd80 0x77c74620 初始化安全描述符
0x26cfd84 0x77c7468d RegOpenKeyExW_0
0x26cfd88 0x77c714d6 RegSetValueExW
0x26cfd8c 0x77ca8819 LsaAddAccountRights
0x26cfd90 0x77cb15e9 SetEntriesInAclA
0x26cfd94 0x77c7412e FreeSid
0x26cfd94 0x77c7412e 弗里希德
0x26cfd98 0x77c7418e AdjustTokenPrivileges
0x26cfd98 0x77c7418e 调整令牌权限
0x26cfd9c 0x77cb187f GetExplicitEntriesFromAclA
0x26cfda0 0x77c715ad RegOpenCurrentUser
0x26cfda4 0x77c7157a GetUserNameW
0x26cfda4 0x77c7157a 获取用户名W
0x26cfda8 0x77c7415e SetSecurityDescriptorDacl
0x26cfdac 0x77c60000  0x26cfdac 0x77c60000
0x26cfdb0 0x77c74304 OpenProcessToken
0x26cfdb4 0x77cb1554 GetNamedSecurityInfoA
0x26cfdb4 0x77cb1554 获取名称安全信息A
0x26cfdb8 0x7deb01e3  0x26cfdb8 0x7deb01e3
0x26cfdbc 0x7debd2f3  0x26cfdbc 0x7debd2f3
0x26cfdc0 0x7dea9c70  0x26cfdc0 0x7dea9c70
0x26cfdc4 0x7de922b0  0x26cfdc4 0x7de922b0
0x26cfdc8 0x7de70000  0x26cfdc8 0x7de70000
0x26cfdcc 0x7deec240  0x26cfdcc 0x7deec240
0x26cfdd0 0x7dea2265  0x26cfdd0 0x7dea2265
0x26cfdd4 0x7debc4ca  0x26cfdd4 0x7debc4ca
0x26cfdd8 0x7dea45f5  0x26cfdd8 0x7dea45f5
0x26cfddc 0x7de92340  0x26cfddc 0x7de92340
0x26cfde0 0x7de92270  0x26cfde0 0x7de92270
0x26cfde4 0x7debca3a  0x26cfde4 0x7debca3a
0x26cfde8 0x7de9df20  0x26cfde8 0x7de9df20
0x26cfdec 0x7dea2500  0x26cfdec 0x7dea2500
0x26cfdf0 0x7dea2c42  0x26cfdf0 0x7dea2c42
0x26cfdf4 0x7deebfa0  0x26cfdf4 0x7deebfa0
0x26cfdf8 0x7dcbfd3f MessageBoxW
0x26cfdf8 0x7dcbfd3f 消息框W
0x26cfdfc 0x7dcbfd1e MessageBoxA
0x26cfdfc 0x7dcbfd1e 消息框A
0x26cfe00 0x7dc70a19 GetDesktopWindow
0x26cfe00 0x7dc70a19 获取桌面窗口
0x26cfe04 0x7dc8e061 wsprintfW
0x26cfe08 0x7dc50000 Ordinal2447
0x26cfe08 0x7dc50000序数2447
0x26cfe0c 0x7dc7ae5f wsprintfA
0x26cfe10 0x72589d0b CoCreateInstance
0x26cfe10 0x72589d0b 共创实例
0x26cfe14 0x72540000  0x26cfe14 0x72540000
0x26cfe18 0x72567259 CoInitializeSecurity
0x26cfe18 0x72567259 共同初始化安全性
0x26cfe1c 0x725809ad CoInitializeEx
0x26cfe20 0x72555ea5 CoSetProxyBlanket
0x26cfe24 0x725886d3 CoUninitialize
0x26cfe24 0x725886d3 取消初始化
0x26cfe28 0x6fc33e59 SysFreeString
0x26cfe28 0x6fc33e59 系统自由字符串
0x26cfe2c 0x6fc34642 SysAllocString
0x26cfe2c 0x6fc34642 系统分配字符串
0x26cfe30 0x6fc30000 Ordinal471
0x26cfe30 0x6fc30000序数471
0x26cfe34 0x504b30  0x26cfe34 0x504b30
0x26cfe38 0x504b58  0x26cfe38 0x504b58
0x26cfe3c 0x535120 aAmdRyzen536006_0
0x26cfe40 0x1  0x26cfe40 0x1
0x26cfe44 0x712175e8 InternetSetOptionA
0x26cfe44 0x712175e8 互联网设置选项A
0x26cfe48 0x7127a920 InternetGetLastResponseInfoA
0x26cfe4c 0xcc0004  0x26cfe4c 0xcc0004
0x26cfe50 0x7121b406 InternetReadFile
0x26cfe50 0x7121b406互联网读取文件
0x26cfe54 0x712430f1 InternetOpenUrlA
0x26cfe58 0x7122f18e InternetOpenA
0x26cfe58 0x7122f18e 互联网开放A
0x26cfe5c 0x71224c7d HttpOpenRequestA
0x26cfe60 0x712249e9 InternetConnectA
0x26cfe60 0x712249e9互联网连接A
0x26cfe64 0x71200000 Ordinal367
0x26cfe64 0x71200000序数367
0x26cfe68 0x7121ab49 InternetCloseHandle
0x26cfe68 0x7121ab49 互联网关闭句柄
0x26cfe6c 0x71211b56 InternetQueryOptionA
0x26cfe6c 0x71211b56 互联网查询选项A
0x26cfe70 0x712918f8 HttpSendRequestA
0x26cfe74 0x6dc00000  0x26cfe74 0x6dc00000
0x26cfe78 0x6dc2a9bc DnsQuery_A
0x26cfe7c 0x6dc0436b DnsFree
0x26cfe80 0x7d830000  0x26cfe80 0x7d830000
0x26cfe84 0x7d83647a BCryptVerifySignature
0x26cfe88 0x7d834d42 BCryptImportKey
0x26cfe88 0x7d834d42 B输入密钥
0x26cfe8c 0x7d831fbc BCryptGenerateSymmetricKey
0x26cfe90 0x7d831b44 BCryptFinishHash
0x26cfe94 0x7d831a5f BCryptDestroyHash
0x26cfe98 0x7d831b93 BCryptCreateHash
0x26cfe9c 0x7d831b0b BCryptHashData
0x26cfea0 0x7d8318b8 BCryptDecrypt
0x26cfea4 0x7d83195c BCryptEncrypt
0x26cfea8 0x7d8320d4 BCryptSetProperty
0x26cfea8 0x7d8320d4 BCryptSet属性
0x26cfeac 0x7d83234e BCryptCloseAlgorithmProvider
0x26cfeb0 0x7d834f94 BCryptImportKeyPair
0x26cfeb4 0x7d83519b BCryptExportKey
0x26cfeb4 0x7d83519b BryptExportKey
0x26cfeb8 0x7d831ca7 BCryptGetProperty
0x26cfebc 0x7d831f40 BCryptDestroyKey
0x26cfec0 0x7d832d30 BCryptOpenAlgorithmProvider

原文始发于checkpoint:TUNNEL WARFARE: EXPOSING DNS TUNNELING CAMPAIGNS USING GENERATIVE MODELS – COINLOADER CASE STUDY

版权声明:admin 发表于 2023年8月26日 下午5:03。
转载请注明:TUNNEL WARFARE: EXPOSING DNS TUNNELING CAMPAIGNS USING GENERATIVE MODELS – COINLOADER CASE STUDY | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...