.Net代码审计之某OA系统任意文件上传

.Net代码审计之某OA系统任意文件上传

点击星标关注公众号,不再迷路~

.Net代码审计之某OA系统任意文件上传

原文转载自自己在Freebuf上面的投稿,链接:https://www.freebuf.com/articles/web/400213.html



前言


此处审计的oa系统有个前提,就是/resource目录下专门存储静态文件,是不解析的,想要文件上传就需要利用目录穿越到代码所在的/C6目录下面


思路历程


咱们findstr搜索下上传的关键字,比如:uploadfile这类的

.Net代码审计之某OA系统任意文件上传


好吧一看还挺多,咱们挑一个来看,比如Web.Module.dll文件

.Net代码审计之某OA系统任意文件上传

反编译dll文件打开查看Web.Module.dll,找到一个Save关键字的上传方法

.Net代码审计之某OA系统任意文件上传

看下类UploadFileEditorSave,初始化方法为Page_Load

.Net代码审计之某OA系统任意文件上传


传参FileName会被作为文件保存的路径,存入text中

之后判断fileSerName是否为””的字符串,而fileSerName是从配置中读取到的

.Net代码审计之某OA系统任意文件上传

是””则调用

path = UploadFileEditorSave.MapFilePath(text);

不是””则调用

path = Upload.MapFilePath(text);


这边假设他不为””,因为一般配置中信息不为空

追踪Upload.MapFilePath方法:

.Net代码审计之某OA系统任意文件上传

首先代码先对_FilePath做了处理

_FilePath = _FilePath.ToLower();

首先获取转成小写的字符串路径

_FilePath = _FilePath.Replace("\", "//").Replace("/resource/", "/");

将路径中的所有\替换为//,所有/resource/替换为/(有先后顺序)

已假设fileServerName不为空,则进入if判断中,if判断又分了三个子判断

代码如下:

text = ConfigurationSettings.AppSettings["FileServerPath"];
if (_FilePath.Replace("../", "/").Length < _FilePath.Length)
{
text += _FilePath.Replace("\", "/").Replace("../", "/").Replace("/", "\");
}
else if (_FilePath.Split(new char[]
{
'^'
}).Length > 1)
{
text += _FilePath.Replace("resource", "^").Split(new char[]
{
'^'
})[1].Replace("../", "").Replace("/", "\");
}
else
{
text += _FilePath.Replace("\", "/").Replace("../", "/").Replace("/", "\");
}
text = text.Replace("\\", "\");
text = "\" + text.Replace("\\", "\");
Upload.DealGarbageChar(ref text, "\");
text = fileServerName + text;

判断1

if (_FilePath.Replace("../", "/").Length < _FilePath.Length)
{
text += _FilePath.Replace("\", "/").Replace("../", "/").Replace("/", "\");
}

此处如果_FilePath存在../字符串,则对_FilePath又进行了处理,将所有\替换为/,所有../替换为/,所有/替换为\(有先后顺序)

判断2

text += _FilePath.Replace("resource", "^").Split(new char[]
{
'^'
})[1].Replace("../", "").Replace("/", "\");

如果_FilePath存在多个^符号,则通过Split方法在^处分割字符串,得到一个字符串数组。

然后选取这个数组的第二个元素(索引为 1),并对该元素进行替换操作:删除所有的../,然后将/替换为反斜杠

判断3

如果都不满足,则对_FilePath进行处理,将所有\替换为/,所有../替换为/,所有/替换为\(有先后顺序)

text += _FilePath.Replace("\", "/").Replace("../", "/").Replace("/", "\");

最后再对_FilePath处理一遍,将所有\\替换为\

text = text.Replace("\\", "\");
text = "\" + text.Replace("\\", "\");
Upload.DealGarbageChar(ref text, "\");
text = fileServerName + text;

然后调用DealGarbageChar方法删除多余的\\

.Net代码审计之某OA系统任意文件上传绕过

看上去是不是已经绝望到无法上传然后目录穿越,其实不然

注意到他对目录穿越只处理的对象是../,可以双写..来绕过。咱们传入….,其中会变成\这样的字符串,代码中就变成了\….\,咱们就直接进入子判断的判断3中

text += _FilePath.Replace("\", "/").Replace("../", "/").Replace("/", "\");

首先替换\为/,字符串就变为/…./,之后替换../为/,则字符串变为/../,最后替换/为\,字符串变为\..\

结果还是能实现目录穿越,且用..避开了判断1,直接进入判断3中

最后拼接到fileServeName,然后返回最为文件路径

text = fileServerName + text;

之后调用Upload.NoAESRead方法存入输入的内容到文件路径

.Net代码审计之某OA系统任意文件上传


利用


完整的调用分析就到这里,咱们构造数据包尝试下:

FileName传参为……..C6commonAdd.aspx,目录穿越/C6/common/Add.aspx文件中,到再上传aspx一句话木马的内容

.Net代码审计之某OA系统任意文件上传上传成功返回状态码200

使用冰蝎连接一下,测试上传成功

.Net代码审计之某OA系统任意文件上传

至此利用链分析完毕



END




关注HackingWiki漏洞感知

了解更多安全相关内容~




原文始发于微信公众号(HackingWiki漏洞感知):.Net代码审计之某OA系统任意文件上传

版权声明:admin 发表于 2024年5月15日 上午8:01。
转载请注明:.Net代码审计之某OA系统任意文件上传 | CTF导航

相关文章