代码审计 | SiteServerCMS身份认证机制

来源:岁月联盟 编辑:猪蛋儿 时间:2020-03-16
加密: TranslateUtils.EncryptStringBySecretKey()
解密: TranslateUtils.DecryptStringBySecretKey()
且看EncryptStringBySecretKey():
源文件: ./SiteServer.Utils/TranslateUtils.cs

加密后将在字符串中的+、=、&、?、/特殊符号用0***0代替,解密前则反过来操作,然而那个SecretKey又出现了,它保存在根目录的Web.config中的appSettings节点下,是加解密的密钥,它的初始化是这样的:
源文件: ./SiteServer.Utils/WebConfigUtils.cs

SecretKey = StringUtils.GetShortGuid();,一个16位字符串的UID,类是:6f2bc5f951826267,注意一下150行被注释掉的SecretKey值。
回到正题,跟进encryptor.DesEncrypt()加密过程:
源文件: ./SiteServer.Utils/Auth/DesEncryptor.cs

使用DES加密,没有指定加密模式(.Net默认是CBC模式,是不是又想到了什么?),密钥从16位减到8位(是不是又有人想着爆破了?),加密解密iv都是固定值:
byte[] iv = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
现在来梳理一下accessToken的加密过程:
accessToken -> EncryptStringBySecretKey() -> ToBase64String() -> Replace()
用正确密码登录成功Cookie则返回像下图这么一串东西,下面为未加密的accessToken:

冒着掉头发的风险又看了一大截,居然说登录还是要正确的密码? 骗子。。。
2.4 Cookie 认证
还没讲完,那后端是如何通过Cookie认证呢?一般都会在控制器看到这么写判断是否有权限:
var AuthRequest = new AuthenticatedRequest();
if (!AuthRequest.IsAdminLoggin) return;
以管理员登录为例,首先从Cookie中获取accessToken,获取流程如下:
源文件: ./SiteServer.CMS/Core/AuthenticatedRequest.cs

从GetCookie()取出后,同文件AuthenticatedRequest():

从AdminToken中获取信息做判断,还记得AdminLogin中也有个IsAdminLoggin = true;吗?
至此,通过Cookie身份认证部分讲得差不多了,普通用户的认证方式与管理员的类似,不重复了。
三、漏洞回顾
看起来好像没什么问题呀?一般,进入正题之前,都要先讲讲历史,如果网上搜索siteserver+漏洞关键词,你会看到模板远程GetShell、XSS/抓包绕过后台、挂马挖矿…等相关内容,而导致这些漏洞产生大多跟加密密钥泄露有关,这里分5.0版本前后,5.0版本之前可能没有源码,可以把.dll丢到dnSky里反编译。
3.1 文件远程下载
在讲历史之前,我先讲一个和密钥(SecretKey)有关的故事,在以前的版本,有些管理接口可能是为方便,可以匿名访问,身份认证仅依赖于系统的加密字符串,还是以v6.14.0为例,看文件:
源文件: ./SiteServer.BackgroundPages/Ajax/AjaxOtherService.cs

这个AJAX请求地址就是不需要权限的,而远程文件下载地址要求是加密字符串,不然没法使用,好了,故事讲完了。
3.2 密钥 Key
在 5.0 版本之前
这里为什么要把5.0版本作为分界线呢? 因为5.0版本之前,密钥(Cipherkey)是存在数据库的,它存在一张bairong_Config表的SettingsXML字段里,生成算法如下:

一个8位随机字符串,IV也是写在源码里:
byte[] rgbIV = new byte[] { 18, 52, 86, 120, 144, 171, 205, 239 };
我们知道之前的某些版本是存在SQL注入的,利用SQL注入读取这个字段获取Cipherkey,然后就可以在加密下载链接,配合远程文件下载达到GetShell的目的。
1.x和2.x这种上古版本,年代久远就直接忽略了。
在 5.0 版本之后
5.0版本之后的secretKey是存在文件里的,其中5.x版本是存在:
源文件: ./SiteFiles/Configuration/Configuration.config
secretKey是 硬编码固定值: vEnfkn16t8aeaZKG3a4Gl9UUlzf4vgqU9xwh8ZV5
而6.0之后secretKey保存在Web根目录的Web.config里(随机生成),IV和5.x一样硬编码在源码里:
byte[] iv = { 0×12, 0×34, 0×56, 0×78, 0×90, 0xAB, 0xCD, 0xEF };

上一页  [1] [2] [3]  下一页