- 概述
这是一篇基于WebApplication开发的.Net应用程序代码审计,程序中所有的代码文件都被编译为一个程序集,保存在目录下的bin文件夹中,由于打码打的不太好(要挨打),所以尽量只给出代码,提供思路参考学习交流,希望师傅们在拿到.Net程序的时候,也可以简单粗略的定位出明显漏洞(RCE),直接一把梭干掉,喜提年终奖。首先看了一下目录下的Web.config,Global.aspx,发现并没有做全局过滤,或者是什么权限控制,所以我们可以直接去找功能项,然后去反汇编他具体的DLL文件,在根据详情的程序代码,访问功能项页面传入对应的参数进行调用。
- 任意文件下载
在Common中的LXXXFileXXXth.aspx中的的代码如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Loadxxx.aspx.cs" Inherits="XXXXXXX.Newxx.Common.LXXXXX" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> </div> </form> </body> </html>
重点关注对象:Inherits="XXXXXXX.Newxx.Common.LXXXXX",这里是引用Dll文件的位置,要考的,在我们确定了程序集目录的情况下,根据特征,利用ILSpy软件,对Dll文件直接进行反汇编,就可以看到详情的代码,可以看到这里引用了XXX文件,我们跟到文件的代码
重点注意到这几行代码
string text = base.Request.QueryString["filepath"]; string str = (base.Request.QueryString["Subject"] == null) ? "" : base.Request.QueryString["Subject"]; ...... ...... this.PrintInfo(text, str + ".eml");
在PrintInfo(string filePath, string fileName)中,传入的2个值,分别为Path和下载的文件名字,文件名拼接中的str是可控的(接收到的Subject)+ ".eml",text也是可控的(接收到的filepath),所以我们这里只需要根据绝对路径,构造filepath为绝对路径的文件,Subject传不传都没事,因为反正下载后的默认文件名也是.eml,但是内容确实我们读取文件的内容。
我们这里构造Payload,可以看到成功下载了某目录下的.aspx文件
- Sql注入
在PXgXwxxxxe目录下的lxxCxxpxxust.aspx文件中的代码如下:
这里还是跟上面一样,关注重点对象Inherits="XXXXXXX.Newxx.xxx.LXXXXX",然后快速定位到代码层,前面有过介绍,这里我们直接跟踪,贴出代码。
重点代码分析:
...... this.mouldId = base.Request.QueryString["mouldId"].ToString(); ...... DataTable dataSource = new MouldDao().GetDataSource("select DefaultValue from syListField where MouldID='" + this.mouldId + "' and FieldName='CType'"); ...... this.type = dataSource.Rows[0][0].ToString();
首先取mouldId的值,然后并没有使用@参数化传参,也没有任何的过滤,导致我们可以拼接Sql语句,造成Sql注入攻击,可以看到这里传入'进入,然后造成了Sql语句报错。
- 任意文件上传
在PXgXwxxxxe目录下的uxxpxxe.aspx文件中的代码如下:
上同,关注关键点Inherits="XXXXXXX.Newxx.xxx.LXXXXX",定位到代码层,这里贴出代码。
注意其中的几行重点代码:
protected HtmlForm form1;// DataRow dataRow = new BasePage().GetEmp().Rows[0];//用户权限验证 HttpPostedFile httpPostedFile = base.Request.Files["Filedata"];//multipart/form-data中的name名
其中DataRow dataRow = new BasePage().GetEmp().Rows[0]用户权限验证,是可以被绕过的,也就是在GetEmp()中,由于我是稀里糊涂绕过的,这里就不讲解了(严重划水,主要确实是稀里糊涂绕过的,大概讲一下思路就是,了解程序本身的加密过程,把他给拖出来,然后Python或者其语言复现重写加密脚本,生成JSON形式的Cookie以及相关ID值,因为他是从COOKIE中直接取值验证的,相当于Token伪造吧。),然后就可以进入到下面的上传主程序,本地构造Html表单。
<body> <form action="http://xxxxx.com/xxxx/xxxxx.aspx?ItemNo=" method="post" enctype="multipart/form-data"> <input type="file" name="Filedata"> <input type="submit" name="Submit" value="upload" ></form> </form> </body>
这里上传成功的话,就会返回文件名,然后根据目录在文件名后面加上后缀aspx即可,算是一个前台RCE了。
- 总结
确认.NET的开发类型,关注web.config和Global.asax文件,熟悉文件目录,反汇编Dll文件,快速定位代码层(也可以直接搜索相关函数,文件操作类,输出类,或者Eval,exec之类的函数),回溯跟踪,根据代码构造Payload,成功Rce(应该打好码了吧/手动滑稽)