您的位置 » 首页 » 代码审计,实用工具 » 代码审计:逐浪CMS(ZOOMLA!CMS)详细漏洞挖掘过程

代码审计:逐浪CMS(ZOOMLA!CMS)详细漏洞挖掘过程

发表于4年前 | 作者: seay | 分类: 代码审计, 实用工具 | 孵化于:2013年06月06日 | 文章热度:20,526 次 全屏阅读

显示不全请点击全屏阅读

0X00 综述

逐浪CMS是基于.net编写的一款CMS,号称还是军工单位也采用过这套CMS,更号称开源,那天下了他所谓的“源代码“下来,纠结了,页面除了aspx文件,连cs和其它文件基本都不见一个,这叫做开源吗?坑人也不至于这样吧……好吧,虽然不是高手,但是也先拿他开刀吧,各种被坑不爽啊……
0X01 PRE-1(LOCALDB)
挖掘这货的漏洞之前先了解一点其它方面的东西,没什么兴趣的可以跳过。先推荐一个mssql2012的新版本,localdb版(2012版独有的),在mssql的大部分版本中,这个版本最精简,安装简单,不用纠结很多其它方面的东西,而且还有一个问题,老版本的数据库无法恢复高版本数据库备份出来的数据,比如2005无法恢复2008备份出来的bak数据库文件。
提供一下mssql 2012 express的地址:
http://www.microsoft.com/zh-cn/download/details.aspx?id=35579
另外单独给下localdb的下载:
http://download.microsoft.com/download/5/F/9/5F955661-5AA9-400D-ACFA-44F14311BC14/CHS/x86/SqlLocalDB.msi
下面介绍一些简单的使用,或者参考以下链接也可以:
http://www.kodyaz.com/sql-server-2012/sql-server-localdb-management-utility-sqllocaldb.aspx
安装好之后,可以使用sqllocaldb.exe来管理数据库实例的创建、开启、停用等。
比如创建一个数据库的实例:Sqllocaldb create localdb
【ASP.NET代码审计】逐浪CMS(ZOOMLA!CMS)漏洞挖掘
启动数据库实例:SqlLocalDB.exe start localdb,使用该命令后会有如下提示:
LocalDB 实例“LocalDB”已启动。
创建好实例之后,查看实例的连接参数,他启用了一个管道的信息,这个比较重要。
查看实例信息:SqlLocalDB.exe info localdb,结果如下图(重点记住实例管道的名称):
【ASP.NET代码审计】逐浪CMS(ZOOMLA!CMS)漏洞挖掘
随便找一个连接工具,比如分离精简出来的查询分析器,直接连接,如图:
【ASP.NET代码审计】逐浪CMS(ZOOMLA!CMS)漏洞挖掘
这样既可成功连接到本地的数据库中,但是注意只能使用SQL语句进行查询。
0X02 PRE-2(对象浏览器)
另外也要先了解vs2008的对象浏览器的使用,主要介绍用对象浏览器来查找dll中包含的类名、方法名等,懂的可以跳过。找到视图-对象浏览器:
【ASP.NET代码审计】逐浪CMS(ZOOMLA!CMS)漏洞挖掘
打开之后,选择自定义组件集:
【ASP.NET代码审计】逐浪CMS(ZOOMLA!CMS)漏洞挖掘
点击旁边的…按钮添加dll等:
【ASP.NET代码审计】逐浪CMS(ZOOMLA!CMS)漏洞挖掘
在搜索框内输入信息进行查询:
【ASP.NET代码审计】逐浪CMS(ZOOMLA!CMS)漏洞挖掘
随便选中一个类名或方法名就可以看见该方法在哪个dll里面,这对于没有源码的情况下查找相关信息比较有用,比如下图的方法就在ZoomLa.BLL.dll中:
当然还可以用其它方法。这只是给一个例子。
0X03 SQL注入的挖掘
按PRE-2的方法,我们看看manage_Config_sousuo这货所在的dll,找到在App_Web_m5rncppr.dll里面,使用如ilspy等工具直接去查看源代码,找到对应的类,先看Page_Load:
【ASP.NET代码审计】逐浪CMS(ZOOMLA!CMS)漏洞挖掘

protected void Page_Load(object sender, EventArgs e)
{
}

没有任何特别的地方,就是说没有任何的验证等,找找哪个aspx文件还有这个类和dll名,/manage/Config/sousuo.aspx里的信息是:

<%@ page language=”C#” autoeventwireup=”true” inherits=”manage_Config_sousuo, App_Web_m5rncppr” enableEventValidation=”false” viewStateEncryptionMode=”Never” %>

包括有类名和dll名。所以可以完全断定我们要看的就是这个页面了。
查看click方法:

 
if (this.TextBox1.Text == "")
    {
        function.WriteErrMsg("请输入要检索的内容", "/manage/Config/sousuo.aspx");
    }
    string cmdText = "declare @str varchar(100) set @str='" + this.TextBox1.Text + "' declare @s varchar(8000) declare tb cursor local for select s='if exists(select 1 from ['+b.name+'] where ['+a.name+'] like ''%'+@str+'%'') print '' ['+b.name+'].['+a.name+']''' from syscolumns a join sysobjects b on a.id=b.id where b.xtype='U' and a.status>=0 and a.xusertype in(175,239,231,167) open tb fetch next from tb into @s while @@fetch_status=0 begin exec(@s) fetch next from tb into @s end close tb deallocate tb";
     this.conn.InfoMessage += new SqlInfoMessageEventHandler(this.info);
    this.conn.Open();
    new SqlCommand(cmdText, this.conn)
    {
        CommandType = CommandType.Text
    }.ExecuteNonQuery();
 
 
TextBox1.Text就是搜索的文本框本身,cmdText就是拼接的字符串,很明显有注入的问题。至于对于declare怎样进行注入,再研究下declare基本就可以搞了。
【ASP.NET代码审计】逐浪CMS(ZOOMLA!CMS)漏洞挖掘
不过这个sql注入不是什么最致命的问题。后面一个漏洞才是有点威胁的。
0X04 无验证数据库备份与数据库下载
简单说,就是非管理员可以随意备份数据库,而且可以直接下下来……
好了,直接简单说下过程:
无意中看到另外一个类manage_Config_BackupRestore中的page_load方法:
protected void Page_Load(object sender, EventArgs e)
    {
        if (!base.IsPostBack)
        {
            this.DatabasePath.Text = DateTime.Now.ToString("MMdd") + "ZoomlaCMS";
         }
        string[] array = SqlHelper.ConnectionString.ToString().Split(new char[]
        {
            ';'
        });
        string[] array2 = array;
        for (int i = 0; i < array2.Length; i++)
        {
            string text = array2[i];
            if (text.ToLower().Contains("initial catalog"))
            {
                this.database = text.Split(new char[]
                {
                    '='
                })[1];
            }
        }
        if (!base.IsPostBack)
        {
            this.Bind();
        }
    }
 
 
从上面的代码可以看出,无论是第一次打开页面还是已经有提交过数据到页面中去,都没有做某种限制,什么限制?限制未登录人员进行操作。好,再看另外一个比较关键的方法,就是按钮点击事件的click方法:
protected void Backup_Click(object sender, EventArgs e)
    {
        string text = HttpContext.Current.Request.PhysicalApplicationPath + "/temp";
         if (!Directory.Exists(text))
        {
            Directory.CreateDirectory(text);
        }
        string strSql = string.Concat(new string[]
        {
            "backup database ",
            this.database,
            " to  disk='",
            text,
            "/",
            this.DatabasePath.Text,
            ".bak'  with  init "
        });
        if (!SqlHelper.ExecuteSql(strSql))
        {
            function.WriteSuccessMsg("<li>数据库备份成功</li>", "/manage/Config/BackupRestore.aspx");
         }
    }

 
上面的操作简单说就是把数据备份到网站目录下的temp文件夹中去。然后也没有做任何的访问控制!!
好吧,既然那么悲剧,拿官网来测试一下:
【ASP.NET代码审计】逐浪CMS(ZOOMLA!CMS)漏洞挖掘
小小备份一个:
【ASP.NET代码审计】逐浪CMS(ZOOMLA!CMS)漏洞挖掘
还会自动压缩让你下载的,很不错。整个数据库都在手上了,一个爽啊。
不过在恢复这个数据库的时候遇到了不少问题,不是安装这里出错就是哪个东西找不到,所以就折腾出了上面的localdb,不过也还是遇到一些问题,下面我也提供一个恢复数据库的操作过程给大家,以便大家以后做相关的测试的时候,无需搞太多很复杂的东西。
具体操作是参考以下链接进行的:

http://www.2cto.com/database/201306/217865.html恢复数据库第一步,连接上之后执行下面的操作:
USE master
RESTORE FILELISTONLY
   FROM DISK = 'c:\1.Bak'
GO
 
 
【ASP.NET代码审计】逐浪CMS(ZOOMLA!CMS)漏洞挖掘
可以查询到logicalname,这两个信息比较重要,把他拼凑到命令中,第二步执行的命令如下:
USE master
RESTORE DATABASE DB
   FROM DISK = 'c:\1.Bak'
   WITH MOVE 'zoomlapub' TO ' c:\DB.mdf',
   MOVE 'zoomlapub_log' TO ' c:\DB_log.ldf',
STATS = 10, REPLACE
GO
执行了这步之后,就恢复出了一个DB数据库了。直接use这个数据库,进行下面的查询:
select * from zl_manager
结果就不发出来了。
 
0X05 SHELL
登录后台,选择模板管理——新建模板,直接写aspx文件,无亮点了。
0X06 无法成功破解MD5的情况下?
官网后台的admin密码,在cmd5目前是没有破解出来的。那如果遇到这种情况的话,该怎么办?无法登录了?
我们看看下面一段代码:
public void CheckIsLogin()
{
    string managePath = B_Admin.GetManagePath();
    if (HttpContext.Current.Request.Cookies["ManageState"] == null)
    {
        HttpContext.Current.Response.Redirect("~/" + managePath + "/Login.aspx");
         return;
    }
    string loginName = HttpContext.Current.Request.Cookies["ManageState"]["LoginName"];
     if (!string.IsNullOrEmpty(loginName))
    {
        loginName = StringHelper.Base64StringDecode(loginName);
    }
    string password = HttpContext.Current.Request.Cookies["ManageState"]["Password"];
     if (this.GetLoginAdmin(loginName, password).IsNull)
    {
        HttpContext.Current.Response.Redirect("~/" + managePath + "/Login.aspx");
    }
}
 
我再提供一段cookie的测试数据:
bdshare_firstime=1043514000222; ASP.NET_SessionId=s51a23555nie5tqx2ln3lxub; hasshown=1; ASP.NET_SessionId=13gv3o45g44arjfbv50errzd; ManageState=ManageId=1&LoginName=YWRtaW4=&TrueName=YWRtaW4=&Password=7fef6171469e80d32c0559f88b377245&Role=1&randNum=8105349550; UserState=LoginName=YWRtaW4=&Password=7fef6171469e80d32c0559f88b377245; ASPX=8788addf2ceec7e4b2971ae436cb82e7
 
其它自行分析了。
 
 
0X07写在最后
之前我也在另外一个文档里面提到过,asp.net的机制和php不一样,所以可以产生的都是比较常规的漏洞。比如上面的sql注入、数据库备份等问题的产生也都是比较常规的问题,还有拿shell也是,都不用去做分析都知道问题产生的地方了。
这套CMS最新版是CMS2 X1.0(官网上厂商吹得很强大啊),上面的问题有好几个比较新点的版本都有,估计下去越更新问题越多,很明显厂家就不是特别的注重安全方面的问题,而且号称开源,但是又不是真正的开源,只是一个幌子,当然了可以反编译出来就是后话了。
目前上面脱裤的问题厂商已经修复了,但是SQL注入暂时还是没有修复的。
 
作者:wefgod

Tags:

代码审计, 逐浪CMS漏洞,

如果您喜欢我的博客,欢迎点击图片定订阅到邮箱填写您的邮件地址,订阅我们的精彩内容: 也可以点击链接【订阅到鲜果】

如果我的想法或工具帮助到了你,也可微信扫下方二维码打赏本人一杯咖啡


来自 Seay互联网安全博客
本文地址:http://www.cnseay.com/2953/
文章版权说明请看置顶文章,尊重作者,转载请以链接形式标明原文地址

马上分享给你的朋友吧~

已经有1个筒子留下了脚印...

  • dave 说:
    1楼
    2014 年 4 月 7 日 上午 1:19 回复

    还是喜欢看 代码审计的文章。。Thanks

发表评论

你的大名(必填)

你的邮箱(必填)

评论内容(必填)