知识点
1.NET普通源码&编译源码
2.DLL反编译&后缀文件&指向
3.代码审计-SQL注入&文件上传
ASPX文件 -> CS ASPX.CS DLL反编译后寻找 看核心代码分析漏洞
CS ASPX.CS DLL反编译文件 -> ASPX文件寻找 确定漏洞进行调试测试
代码审计时要把这个反编译文件提取导入到IDE中 后期搜索关键字或函数挖掘
详细点
后缀解析:
asp.net可以用C#、VB.NET,Jscript.net等等来开发,但是通常首选都是C#和VB.NET
审计asp.net的时候,首先得弄明白结构,它并不像php那么单纯。
一般来说,在asp.net应用中,需要进行观察的文件有:.aspx,.cs,.ashx,dll文件
1..aspx是页面后的代码,aspx负责显示,服务器端的动作就是在.cs定义的
2..cs是类文件,公共类什么的就是这个
3..ashx是一般处理程序,主要用于写web handler,可以理解成不会显示的aspx页面
4..dll就是cs文件编译之后的程序集
Inherits、CodeFile、CodeBehind
指向解析:
Inherits
msdn解释:定义供页继承的代码隐藏类。它可以是从 Page类派生的任何类。此特性与CodeFile特性一起使用,后者包含指向代码隐藏类的源文件的路径。Inherits特性在使用C#作为页面语言时区分大小写,而在使用Visual Basic作为页面语言时不区分大小写。
CodeFile
msdn解释:指定指向页引用的代码隐藏文件的路径。此特性与Inherits特性一起使用,用于将代码隐藏源文件与网页相关联。此特性仅对编译的页有效。
CodeBehind
msdn解释:指定包含与页关联的类的已编译文件的名称。该特性不能在运行时使用。此特性用于Web应用程序项目。
反编译工具-ILSpy&dnSpy&ReFlector
ILSpy:https://github.com/icsharpcode/ILSpy/releases
dnSpy:https://github.com/dnSpy/dnSpy/releases
ReFlector:https://www.xitongzhijia.net/soft/44725.html
SQL注入-MSSQL监控-反编译&函数搜索
安装appform8.5程序,访问界面,可以看到有id传参。
找到当前页面的源代码。
点击查看代码
<%@ Page Language="C#" AutoEventWireup="true" MasterPageFile="~/Appform/Appform.Master" CodeBehind="Leave_Detail.aspx.cs" Inherits="Appleave.AppLeave.AppLeaveView" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<asp:HiddenField runat="server" ID="hf_hrname" />
<div id="PopPage">
<div style=" font-size:12px; font-family:Verdana">
<div class="banner">
<asp:Label runat="server" ID="lbl_bannertitle" Text="员工请假申请表" CssClass="bannerText"></asp:Label>
</div>
<div style=" text-align:center; font-family:Verdana; font-size:20px" >
<h3><asp:Label runat="server" style=" font-family:微软雅黑; font-size:20px" ID="lblactivename"></asp:Label></h3>
</div>
<div class="subtitle">
<%=isen ? "1.Leave User Info." : "1.请假人信息"%>
(ID:<asp:Label ID="lbl_id" runat="server" Text="Label"></asp:Label>)</div>
<table class="gwTableClass" border=0 cellSpacing=0 cellPadding=0 width="95%" align=center>
<tbody>
<tr>
<td>
<table border="0" cellSpacing="1" borderColorDark="#ffffff" cellPadding="8"
width="90%" bgColor="#A1A3AD" align=center>
<tbody>
<tr bgColor=#ffffff>
<td class="gwTdLabel" width="20%">
<%=isen?"Department":"部门" %>
</td>
<td width="30%">
<asp:TextBox runat="server" Enabled="false" CssClass="gwTextInput" ID="txt_deptname"
></asp:TextBox>
</td>
<td class=gwTdLabel width="20%">
<%=isen ? "Login Name" : "登录名"%>
</TD>
<td width="30%">
<asp:TextBox runat="server" Enabled="false" CssClass="gwTextInput" ID="txt_loginname"
></asp:TextBox>
<asp:RequiredFieldValidator ControlToValidate="txt_loginname" Display="Dynamic" ID="RequiredFieldValidator5" runat="server" ErrorMessage="*"></asp:RequiredFieldValidator>
</td>
</tr>
<tr bgColor=#ffffff>
<td class=gwTdLabel width="20%">
<%=isen ? "Display Name" : "显示名"%>
</TD>
<td width="30%">
<asp:TextBox runat="server" ID="txt_displayname" Enabled="false" CssClass="gwTextInput"></asp:TextBox>
<asp:RequiredFieldValidator ID="cnnameRequiredFieldValidator" Display="Dynamic" ControlToValidate="txt_displayname" runat="server" ErrorMessage="必须填写中文名"></asp:RequiredFieldValidator>
</td>
<td class=gwTdLabel width="20%">
<%=isen ? "Email" : "邮件"%>
</TD>
<td width="30%">
<asp:TextBox runat="server" Enabled="false" CssClass="gwTextInput" ID="txt_email"></asp:TextBox>
<asp:RequiredFieldValidator ControlToValidate="txt_email" ID="RequiredFieldValidator3" runat="server" ErrorMessage="必须填写邮件"></asp:RequiredFieldValidator>
</td>
</tr>
<tr bgColor=#ffffff>
<td class=gwTdLabel width="20%">
<%=isen ? "Staff Code" : "员工号"%>
</TD>
<td width="30%">
<asp:TextBox runat="server" Enabled="false" CssClass="gwTextInput" ID="txt_staffcode"></asp:TextBox>
<asp:RequiredFieldValidator ControlToValidate="txt_staffcode" ID="telRequiredFieldValidator1" runat="server" ErrorMessage="必须填写员工号"></asp:RequiredFieldValidator>
</td>
<td class=gwTdLabel width="20%">
<%=isen ? "App Username" : "申请人登录名"%>
</TD>
<td width="30%">
<asp:TextBox runat="server" CssClass="gwTextInput" ID="txt_appusername" Enabled="false"></asp:TextBox>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<br />
<!-- part 2 -->
<div class="subtitle">
<%=isen ? "2.Leave Information" : "2.请假信息"%>
</div>
<table class="gwTableClass" border=0 cellSpacing=0 cellPadding=0 width="95%" align=center>
<tbody>
<tr>
<td>
<table border="0" cellSpacing="1" borderColorDark="#ffffff" cellPadding="8"
width="90%" bgColor="#A1A3AD" align=center>
<tbody>
<tr bgColor=#ffffff >
<td width="25%"> <%=isen ? "Overtime" : "请假时间"%>
</td>
<td width="50%" colspan="2">
<%=isen ? "From" : "从"%>
<asp:Label runat="server" ID="lbl_fromdate"></asp:Label>
<div style=" height:5px;"></div>
<%=isen ? "To " : "到"%>
<asp:Label runat="server" ID="lbl_todate"></asp:Label>
</td>
<td width="25%">
<%=isen ? "Total" : "共"%> <asp:Label runat="server" ID="lbl_totalhour"></asp:Label>
<%=isen ? "Hours" : "小时"%>
</td>
</tr>
<tr bgColor=#ffffff>
<td class="gwTdLabel" width="25%">
<%=isen ? "Leave Types" : "请假类型"%>
:</td>
<td width="*" colspan="3">
<asp:Label runat="server" ID="lbl_apptext"></asp:Label>
<asp:Label runat="server" ID="lbl_other"></asp:Label>
</td>
</tr>
<tr bgColor=#ffffff>
<td class="gwTdLabel" width="25%">
<%=isen ? "Reason" : "请假原因"%>
:</td>
<td width="*" colspan="3">
<asp:Label runat="server" ID="lbl_reason"></asp:Label>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<br />
<!-- / reason -->
<div class="subtitle">
<%=isen ? "3.Process Flow" : "3.处理流程"%>
</div>
<table class="gwTableClass" border=0 cellSpacing=0 cellPadding=0 width="95%" align=center>
<tbody>
<tr>
<td>
<table border="0" cellSpacing="1" borderColorDark="#ffffff" cellPadding="8"
width="90%" bgColor="#A1A3AD" align=center>
<tbody>
<tr bgColor=#ffffff style=" font-weight:bold">
<td class="gwTdLabel" width="80px"><%=isen ? "Operate Time" : "处理时间"%></td>
<td width="80px"><%=isen ? "Operate User" : "处理人"%></td></td>
<td width="*"><%=isen ? "Detail" : "处理内容"%> </td>
<td width="80px""><%=isen ? "Result" : "处理结果"%> </td>
</tr>
<asp:Repeater runat="server" ID="rpt_log">
<ItemTemplate>
<tr bgColor=#ffffff >
<td class="gwTdLabel" width="80px" style=" font-size:11px;">
<%# DateTime.Parse(Eval("createdate").ToString()).ToString("HH:mm<br> yyyy-MM-dd")%>
</td>
<td width="80px"><%#Eval("opusername") %></td>
<td width="*"><%#Eval("contents") %></td>
<td width="80px""><%#Eval("result") %></td>
</tr>
</ItemTemplate>
</asp:Repeater>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<br />
<div class="subtitle">
<%=isen ? "4.Submit Application" : "4.提交审批"%>
</div>
<table class="gwTableClass" border=0 cellSpacing=0 cellPadding=0 width="95%" align=center>
<tbody>
<tr>
<td>
<table border="0" cellSpacing="1" borderColorDark="#ffffff" cellPadding="8"
width="90%" bgColor="#A1A3AD" align=center>
<tbody>
<tr bgColor=#ffffff >
<td colspan="4">
<%=isen ? "To" : "向"%>
<asp:DropDownList runat="server" ID="ddl_to" Width="200px"></asp:DropDownList>
<%=isen ? "Message" : "发送留言"%>
<asp:TextBox runat="server" ID="txt_msg" Width="400px"></asp:TextBox>
<asp:Button ID="btn_msg" runat="server" Text="提交审批" class="btn"
onclick="btn_msg_Click" />
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</asp:Content>
但在源代码搜索id关键字,没有找到传参的地方,所以得去找找源代码中包含的其他文件。
CodeBehind="Leave_Detail.aspx.cs" Inherits="Appleave.AppLeave.AppLeaveView"
这种源文件大多数是以库文件的形式存在,会放在bin目录下,利用ILSpy工具对Appform.dll文件进行反编译。
在page_load函数中找到了id传参的地方。
然后利用MSSQL数据库监控工具监控给id传参时数据库执行的语句。
对应的代码也在page_load函数中。
可以看到源代码中没有对appid进行过滤,所以可能存在SQL注入,尝试注入。
但是MSSQL数据库监控工具没有监听到任何语句。
猜测是有过滤函数,找到如下语句。
DataSet dataSet = (DataSet)(object)Instance.ExeDataSet(text);
跟进ExeDataSet函数。
点击查看代码
public static DataSet ExeDataSet(string strSql)
{
SqlConnection connection = new SqlConnection(_con);
SqlCommand sqlCommand = new SqlCommand(strSql);
sqlCommand.Connection = connection;
using SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(sqlCommand);
DataSet dataSet = new DataSet();
sqlDataAdapter.Fill(dataSet);
sqlCommand.Parameters.Clear();
return dataSet;
}
是个预编译的写法,所以所有涉及到该函数的都不会存在SQL注入。只能找其他不涉及该函数的注入点进行注入尝试。搜索ExeDataSet关键字,发现许多文件都涉及到。
所以这些文件都不需要找了,只需找其他文件存在SQL执行语句的即可。找到Appform/Appform/AddLeaveData.cs文件。
点击查看代码
protected void Button1_Click(object sender, EventArgs e)
{
string s = Instance.ExeScalar(" select count(*) from leave_data where username='" + txt_username.Text + "' and year='" + txt_year.Text + "' and staffcode='" + txt_staffcode.Text + "'").ToString();
if (int.Parse(s) > 0)
{
Helper.Result((Page)(object)this, "用户已经存在,请更新用户");
return;
}
SqlParameter[] prams = new SqlParameter[5]
{
new SqlParameter("@username", txt_username.Text),
new SqlParameter("@annualhours", Convert.ToInt32((double)float.Parse(txt_annualday.Text) * 480.0)),
new SqlParameter("@sickhours", Convert.ToInt32((double)float.Parse(txt_sickday.Text) * 480.0)),
new SqlParameter("@year", txt_year.Text),
new SqlParameter("@staffcode", txt_staffcode.Text)
};
string sql = " insert into leave_data (username,annualhours,sickhours,year,staffcode) values(@username,@annualhours,@sickhours,@year,@staffcode)";
Instance.ExeNonquery(sql, (SqlParameter[])(object)prams);
Helper.Result((Page)(object)this, "操作成功");
}
访问对应界面,查看界面元素,发现可以跟代码的传参变量对应上。
所以此处就可以进行注入了。
注入语句成功带入。查找MSSQL注入语句进行注入。
1' and 1=(select is_srvrolemember('sysadmin'))--
执行后,返回如下界面。
注入语句也被成功带入。
但是这样不能判断注入的语句有没有执行,故将注入语句中的'sysadmin'随便乱写一个'dasdasdadmin'。
执行发现页面报错了。
这样就能说明当前用户确实是admin用户,注入的语句成功被执行了。
文件上传-操作函数搜索-反编译&功能抓包
安装企业商学院学习平台 V2020程序,由于功能点较多,找文件上传漏洞不方便,所以此处通过搜索文件上传的关键函数进行查找。
.net上传文件有三种方法。
(1)方法一:用Web控件FileUpload,上传到网站根目录。
点击查看代码
Test.aspx关键代码:
<form id="form1" runat="server">
<asp:FileUpload ID="FileUpload1" runat="server" />
<asp:Button ID="Button1" runat="server" Text="上传" OnClick="Button1_Click" />
<asp:Label ID="Label1" runat="server" Text="" Style="color: Red"></asp:Label>
</form>
Test.aspx.cs关键代码:
protected void Button1_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
FileUpload1.SaveAs(Server.MapPath("~/") + FileUpload1.FileName);
Label1.Text = "上传成功!";
}
}
(2)方法二:用Html控件HtmlInputFile,上传到网站根目录。
点击查看代码
Test.aspx关键代码:
<form id="form1" runat="server">
<input type="file" id="file1" runat="server" />
<asp:Button ID="Button1" runat="server" Text="上传" OnClick="Button1_Click" />
<asp:Label ID="Label1" runat="server" Text="" Style="color: Red"></asp:Label>
</form>
Test.aspx.cs关键代码:
protected void Button1_Click(object sender, EventArgs e)
{
if (file1.PostedFile.ContentLength > 0)
{
file1.PostedFile.SaveAs(Server.MapPath("~/") + Path.GetFileName(file1.PostedFile.FileName));
Label1.Text = "上传成功!";
}
}
(3)方法三:用Html元素<input type="file" …/>,通过Request.Files上传到网站根目录。
input type="file" name="xxxxxxx"/>一定不要忘记“name”属性。否则在后台代码中用Request.Files是取不到值得!
点击查看代码
Test.aspx关键代码:
<form id="form1" runat="server" enctype="multipart/form-data">
<input type="file" name="file" />
<asp:Button ID="Button1" runat="server" Text="上传" OnClick="Button1_Click" />
<asp:Label ID="Label1" runat="server" Text="" Style="color: Red"></asp:Label>
</form>
Test.aspx.cs关键代码:
protected void Button1_Click(object sender, EventArgs e)
{
if (Request.Files["file"].ContentLength > 0)
{
Request.Files["file"].SaveAs(Server.MapPath("~/") + Path.GetFileName(Request.Files["file"].FileName));
Label1.Text = "上传成功!";
}
}
可以看到这三种方法都带有SaveAs关键字,所以去源代码中搜索SaveAs。
js文件不用管,SaveAs关键字只出现在upload_json.ashx文件中,看下该文件位于哪个目录。
发现是位于kindeditor编辑器的目录下,网上搜索可以知道kindeditor不存在文件上传漏洞,所以接下来需要去dll文件中搜索。但是bin目录下存在很多dll文件,具体去反编译哪个呢,我们可以根据源代码中引用比较多的dll文件去打开。
发现比较多引用的是Song.Site文件,所以反编译Song.Site.dll,并将反编译后的代码保存。
在反编译之后的代码中去搜索SaveAs关键字。
先看第一处,发现源代码中没有过滤代码。
但是源代码中不存在过滤代码,不代表没有过滤功能。因为源代码中引用了其他类里的功能,所以还需要去看WeiSha.Common.Server.MapPath具体的代码。反编译WeiSha.Common.dll文件,找到MapPath函数的源代码。
存在正则匹配过滤,所以第一处可以先放弃。其他几处也可以根据此方法一个个去判断,最终找到一处。
该文件引用了四个dll文件。
发现这四个文件中存在过滤功能的是WeiSha.WebControl中的FileUpload函数。
看到FileAllow类,看看这是干什么的。
继续跟进ViewState。
看来FileAllow类是从前端获取可允许上传的文件类型的,查找哪些文件引用了List_Edit.cs。
然后List_Edit.cs是在Template目录下的,所以去访问Template目录下的List_Edit.aspx文件。
访问的时候出错了,这不是搭建的问题,是页面本身存在问题。它其实是个功能点,需要通过访问其他页面来触发。这里需要通过访问Manage/console.aspx来触发。
在模板信息编辑处上传一个aspx文件,提示我们只能上传jpg、bmp、gif和png后缀的文件。
查看前端元素。
通过fileallow字段来控制的,这就跟FileAllow类对上了。所以只需要在前端加上我们想要上传的文件后缀名即可。
再上传aspx文件,上传成功。
如果这里上传个aspx的后门木马,就可以控制该网站了。