赛博大作战中的技术文章仅供参考,此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等(包括但不限于)进行检测或维护参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失,均由使用者本人负责。本文所提供的工具仅用于学习,禁止用于其他!!!
1
前言
某医学在线考试系统,影响版本 < V3.26.9,在最新版本当中已经修复,这里仅作为代码审计的案例分享,敏感内容已打码
2
路由分析
第一步,大致看一眼项目结构,随便翻翻文件global.asax
<%@ Application Codebehind="Global.asax.cs" Inherits="YQExam.Web.Global" Language="C#" %>
可以判断是编译成dll运行的.net项目,YQExam.Web.dll
需要使用dnspy对编译后的dll文件进行反编译,可以发现dll有一定混淆
不过不是很重要,使用de4dot就可以对混淆代码,进行解密
Examples:
de4dot.exe -r c:\my\files -ro c:\my\output
de4dot.exe file1 file2 file3
de4dot.exe file1 -f file2 -o file2.out -f file3 -o file3.out
de4dot.exe file1 --strtyp delegate --strtok 06000123
// 批量反混淆 c:\input是混淆的dll文件夹
// 输出一个反混淆的dll文件夹c:\output
de4dot.exe -r c:\input -ru -ro c:\output
重新打开dll发现就没有混淆了
可以发现该系统为ASP.NET WebForm开发模式,比如
我想访问到图中的代码逻辑
那么请求的url就为http://xxxx/Manage/Ajax/User.ashx
ASP.NET WebForm开发模式 参考:
https://mp.weixin.qq.com/s/PztEiJh67yJ9uNDYqZQCjA
https://mp.weixin.qq.com/s/0xYkOVKuwwAaEqrba7xxZA
接着,我们可以将反编译后的dll进行导出,这个根据个人习惯,导出的话可以用vscode来打开审计,选择左上角-文件-导出到工程,选择一个目录进行导出
3
鉴权绕过读取密码
基础环境准备好了以后就可以开始代码审计,大概读一读有啥过滤
发现存在过滤如下
YQExam.Web.Filter#SqlStringFilter#ParamerValid
// 内部的一些代码逻辑
// 一些判断
if (!ConfigBll.GetSelfVerbs().Contains(request.RequestType)) // 只允许post、get
if (request.UrlReferrer != null && !request.Url.Host.Equals(request.UrlReferrer.Host) && !ConfigBll.GetSelfReferer().Contains // Referrer和Host要相等
// 关键字过滤
foreach (object obj in request.QueryString)
{
string name = (string)obj;
if (FilterSqlString.ExistsSuspicious(request.QueryString[name]))
{
flag = false;
break;
}
}
发现存在权限路径过滤如下
YQExam.Web.Filter#AuthorFilter#AuthorValid
// 存在漏洞的逻辑部分
private void AuthorValid(object sender, EventArgs e)
{
bool flag = true;
HttpContext httpContext = HttpContext.Current;
HttpRequest request = httpContext.Request;
bool flag2 = true;
string absolutePath = request.Url.AbsolutePath;
if (absolutePath.EndsWith(".aspx", StringComparison.CurrentCultureIgnoreCase) || absolutePath.EndsWith(".ascx", StringComparison.CurrentCultureIgnoreCase) || absolutePath.EndsWith(".ashx", StringComparison.CurrentCultureIgnoreCase))
{
if (absolutePath.EndsWith("/Default.aspx", StringComparison.CurrentCultureIgnoreCase) || absolutePath.EndsWith("/Register.aspx", StringComparison.CurrentCultureIgnoreCase) || absolutePath.EndsWith("/MediaFile.aspx", StringComparison.CurrentCultureIgnoreCase) || absolutePath.EndsWith("/Login.aspx", StringComparison.CurrentCultureIgnoreCase))
{
return;
}
...
那么我们可以发现什么呢?没错,就是
if (absolutePath.EndsWith(".aspx", StringComparison.CurrentCultureIgnoreCase) ||
absolutePath.EndsWith(".ascx", StringComparison.CurrentCultureIgnoreCase) || absolutePath.EndsWith(".ashx", StringComparison.CurrentCultureIgnoreCase))
// 如果 absolutePath 以 ".aspx"、".ascx" 或者 ".ashx" 结尾(忽略大小写),那么条件表达式的值将为 true。就会进入权限判断,那结尾加点特殊字符就行了
结合前面审计找到的接口,我们就可以读取用户的账号密码登录后台
这个密码是des加密的,需要写一下解密函数,密钥什么的都在源码中有的,解密丢星球里了,des解密出密码
成功登录后台
4
后台文件上传+文件移动绕过白名单getshell
文件上传的话,看了下后台基本上都是白名单,但问题不大,白名单可以绕过。首先,登录后台随便找个接口传个asmx的shell,后缀是jpg
然后找个文件移动的接口,移动的后缀没有限制导致getshell,发现两处接口 FileDirHelper.DownloadFile(text, strShowName, this.Context); 发现这个函数是移动文件并且可以自由定义后缀
public static void DownloadFile(string strSrcFile, string strShowName, HttpContext context)
{
if (!File.Exists(context.Server.MapPath(strSrcFile)))
{
return;
}
FileInfo fileInfo = new FileInfo(context.Server.MapPath(strSrcFile));
if (!fileInfo.Name.Equals(strShowName, StringComparison.CurrentCultureIgnoreCase))
{
string text = strSrcFile.Replace(fileInfo.Name, strShowName);
File.Copy(context.Server.MapPath(strSrcFile), context.Server.MapPath(text), true);
if (File.Exists(context.Server.MapPath(text)))
{
context.Response.Redirect(text);
return;
}
}
else
{
context.Response.Redirect(strSrcFile);
}
}
最后,基本上都修复了,分享出来供参考学习交流吧,其中,主要是权限绕过的漏洞利用,其实也不是非得读取密码解密登录后台getshell
通过文件移动,成功绕过文件上传的白名单执行了脚本文件!poc丢星球了