代码审计 | SiteServerCMS身份认证机制
一、前言
SiteServerCMS是一款开源免费的企业级CMS系统,功能比较丰富,代码一多起来,难免会有些漏洞产生,之前应急响应碰到过几次这个系统,有些问题修复了,有些问题依然还在,趁着整理之前零散的资料,结合6.14.0版本写个总结。
SiteServerCMS有多种身份认证方式,这里以最常见的Cookie认证来展开分析:
官网: https://www.siteserver.cn/
Github: https://github.com/siteserver/cms/releases
二、身份认证
2.1 登录框
从何说起呢?渗透,经常开局就只有一个登录框,有时还有验证码,那就从登录框开始吧,SiteServerCMS是后台管理+前台内容(含会员)的前后分离模式,各有独立的登录地址,先从后台登录开始,默认后台登录地址是:
http://IP:Port/SiteServer/pageLogin.cshtml
随便输入个用户名和密码登录查看数据包,通过JSON格式提交到了/api/v1/administrators/actions/login,进入脱发模式,打开源码跟进,位置:
源文件: ./SiteServer.Web/Controllers/V1/AdministratorsController.cs
登录失败次数+1,出局。
2.2 Cookie & accessToken
使用正确的用户名密码登录,登录成功后,会生成一个accessToken的字符串,这个accessToken是作为Cookie身份认证用的:
var accessToken = request.AdminLogin(adminInfo.UserName, isAutoLogin);
不信且看,走进AdminLogin(),跟进accessToken生成过程:
var accessToken = AdminApi.Instance.GetAccessToken(adminInfo.Id, adminInfo.UserName, expiresAt);
源文件: ./SiteServer.CMS/Core/AuthenticatedRequest.cs
SiteServerCMS有多种身份认证方式,这里的Constants.AuthKeyAdminCookie对应的是Cookie命名份格式: SS+名称,规则如下:
源文件: ./SiteServer.Utils/Constants.cs
public const string AuthKeyUserHeader = "X-SS-USER-TOKEN";
public const string AuthKeyUserCookie = "SS-USER-TOKEN";
public const string AuthKeyUserQuery = "userToken";
public const string AuthKeyAdminHeader = "X-SS-ADMIN-TOKEN";
public const string AuthKeyAdminCookie = "SS-ADMIN-TOKEN";
public const string AuthKeyAdminQuery = "adminToken";
public const string AuthKeyApiHeader = "X-SS-API-KEY";
public const string AuthKeyApiCookie = "SS-API-KEY";
public const string AuthKeyApiQuery = "apiKey";
public const int AccessTokenExpireDays = 7;
public static string GetSessionIdCacheKey(int userId)
{
return $"SESSION-ID-{userId}";
}
回来继续跟进GetAccessToken():
源文件: ./SiteServer.CMS/Plugin/Apis/AdminApi.cs
又回来了,继续回到上一个文件,找到那个GetAccessToken():
还记得第三个参数类型是什么吗? 突然冒出来的WebConfigUtils.SecretKey是什么?JwtHashAlgorithm.HS256又是什么鬼?为了避免篇幅太长:
WebConfigUtils.SecretKey: 加密密钥,圈起来,要考的;
JwtHashAlgorithm.HS256: Hash算法模式,知道就行了。
继续跟进JsonWebToken.Encode(),直接跳过中间的方法到最后一个Encode():
源文件: ./SiteServer.Utils/Auth/JWT.cs
这里的参数对应关系:
payload对应userToken;
key对应WebConfigUtils.SecretKey;
algorithm对应JwtHashAlgorithm.HS256。
然后整个accessToken生成格式为:
算法类型 + 认证信息 + 哈希摘要
Base64UrlEncode(headerBytes) + "." + Base64UrlEncode(payloadBytes) + "." + Base64UrlEncode(signature)
明文格式大致像这样:
{"typ":"JWT","alg":"HS256"}.{"UserId":1,"UserName":"admin","ExpiresAt":"//Date(1583293343684)//"}.哈希摘要
accessToken生成完了,看完头发掉了不少,有什么用?
2.3 加密 & 解密
暂时还派不上用场,现在我要讲另一件事:加密与解密。
且回到AdminLogin(),登录成功后会将accessToken通过Cookie返回客户端:
CookieUtils.SetCookie(Constants.AuthKeyAdminCookie, accessToken);
这里暂时不去理会是否isAutoLogin,捡简单的,跟进SetCookie():
源文件: ./SiteServer.Utils/CookieUtils.cs
注意这里有一个很关键的参数isEncrypt,缺省值是true,默认都是启用的:
[1] [2] [3] 下一页