一:背景

1.讲故事

前几天有位朋友在微信上找到我,说他的一个程序上了生产之后,被运维监控定位到这个程序会向一个网址为: http://m.365ey.net 上不定期打数据,而且还是加密的格式,要他解释到底是怎么回事?朋友说根本不认识这个网址,最后在恐慌中排查到是项目中引用了 DeveloperSharp.RabbitMQ 组件所致,截图如下:

朋友反编译了下sdk源码,发现都是混淆过的没法看,聊的过程中朋友很恐慌,很焦虑,担心生产的数据被泄漏,让我帮忙看下是否有手段定位下到底都采集了什么数据?

说实话,这种事情听起来就很惊魂,情从肺腑出,方能入肺腑。。。只要是一个正能量的人,这个忙肯定是尽最大可能的帮一下。

二:WinDbg 分析

1. 前置工作准备

从 nuget 中把 DeveloperSharp.RabbitMQ 下载下来,写好一个测试案例。


internal class Program
{
static void Main(string[] args)
{
for (int i = 0; i < int.MaxValue; i++)
{
try
{
var queueName = "jk";
var content = $" hello world! {i}";
RabbitMQHelper.SendMessage(queueName, content); Console.WriteLine($"时间:{DateTime.Now}, i={i} 次处理!");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
Thread.Sleep(1000);
}
}
}
}

为了安全,我把程序放到虚拟机中,同时在 hosts 下给它设置个错误的 ip 地址。


192.168.1.30 m.365ey.net

接下来打开 Fiddler,再用 WinDbg TTD 的方式把程序启动起来来记录程序的全部行为,方便我后续分析,

正如朋友所说,真的有采集行为:

  • http://m.365ey.net:13064/AssistLog.svc
  • http://m.365ey.net:13063/QueryLog.svc

2. 如何寻找请求代码块

截获请求的代码很简单,因为屏蔽了 IP,所以请求肯定会抛异常,我只需要用 sxe clr 拦截下 First Chance Exception 就能捕获到调用代码。


0:013> sxe clr
0:013> g
(3398.3f7c): CLR exception - code e0434352 (first/second chance not available)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
Time Travel Position: 16D93B:0
eax=079befe8 ebx=00000005 ecx=00000005 edx=00000000 esi=079bf0a8 edi=00000001
eip=77207380 esp=079befe0 ebp=079bf040 iopl=0 nv up ei pl nz ac pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000216
ntdll!RtlRaiseException:
77207380 55 push ebp
0:013> !clrstack
OS Thread Id: 0x3f7c (13)
Child SP IP Call Site
079bf0fc 77207380 [HelperMethodFrame: 079bf0fc]
079bf1ac 78861902 System.Net.HttpWebRequest.GetResponse() [f:\dd\NDP\fx\src\net\System\Net\HttpWebRequest.cs @ 2254]
079bf1fc 0a5a2e89 System.ServiceModel.Channels.HttpChannelFactory`1+HttpRequestChannel+HttpChannelRequest[[System.__Canon, mscorlib]].WaitForReply(System.TimeSpan)
079bf24c 0a5a1199 System.ServiceModel.Channels.RequestChannel.Request(System.ServiceModel.Channels.Message, System.TimeSpan)
079bf2c0 0a5a1026 System.ServiceModel.Dispatcher.RequestChannelBinder.Request(System.ServiceModel.Channels.Message, System.TimeSpan)
079bf2d0 0a5703f3 System.ServiceModel.Channels.ServiceChannel.Call(System.String, Boolean, System.ServiceModel.Dispatcher.ProxyOperationRuntime, System.Object[], System.Object[], System.TimeSpan)
079bf3cc 0a57010d System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(System.Runtime.Remoting.Messaging.IMethodCallMessage, System.ServiceModel.Dispatcher.ProxyOperationRuntime)
079bf3f8 0a56f79e System.ServiceModel.Channels.ServiceChannelProxy.Invoke(System.Runtime.Remoting.Messaging.IMessage)
079bf438 7b224e24 System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(System.Runtime.Remoting.Proxies.MessageData ByRef, Int32) [f:\dd\ndp\clr\src\BCL\system\runtime\remoting\realproxy.cs @ 823]
079bf5d0 7a5df148 [TPMethodFrame: 079bf5d0] wfP8f24Vyfpc8suOyj.bBZbSsm9FOwaYWDWVc.Record1(System.String, System.String, System.String, System.String, System.String, System.String, System.String)
079bf644 067c835f System.Base.ApplicationContext+c.b__19_0()
079bf6b0 7b1dd4bb System.Threading.Tasks.Task.InnerInvoke() [f:\dd\ndp\clr\src\BCL\system\threading\Tasks\Task.cs @ 2884]
...

从线程栈看,请求 http://m.365ey.net:13064/AssistLog.svc 是由 Record1 方法发起的,一看就是个 WCF 方法,参数名称和个数都和 Fiddler 中保持一致, 截图如下:

3. 这些参数都是什么

要找到原参数信息,需要找到是谁调用了 Record1 方法,可以用 !U 067c835f 查看函数汇编代码,简化后如下:


0:013> !U 067c835f
Normal JIT generated code
System.Base.ApplicationContext+<>c.<HashObjectMap>b__19_0()
Begin 067c7ed8, size 584
...
067c8333 8b3d74361904 mov edi,dword ptr ds:[4193674h] (Object: System.Runtime.Remoting.Proxies.__TransparentProxy)
067c8339 ff75b0 push dword ptr [ebp-50h]
067c833c ff75ac push dword ptr [ebp-54h]
067c833f ff75a8 push dword ptr [ebp-58h]
067c8342 ff75a4 push dword ptr [ebp-5Ch]
067c8345 ff75a0 push dword ptr [ebp-60h]
067c8348 b94e080000 mov ecx,84Eh
067c834d ff15b05d7a06 call dword ptr ds:[67A5DB0h] (System.Base.ApplicationContext+<>c.zmMLEYhjSCTVEl2CxBD(Int32), mdToken: 0600009e)
067c8353 50 push eax
067c8354 8b55b4 mov edx,dword ptr [ebp-4Ch]
067c8357 8bcf mov ecx,edi
067c8359 ff15d8016d00 call dword ptr ds:[6D01D8h]
...

原来是 <HashObjectMap>b__19_0 方法做的调用,也就是 call dword ptr ds:[6D01D8h] ,不信的话可以截图看源码:

从混淆的代码看,有几个特征:

  • aa 依赖于 n9UuXCvGC
  • bb 依赖于 gY03KpyvZ
  • cc 依赖于 GsvWjQg1p
  • hh 依赖于 text

等等,那怎么提取呢? 这里只演示一个 aa 参数吧,可以在汇编代码的第一个 x4phG7d0qxdP1ZxlQa.pliOsRbOU 方法上下一个断点,即 067c820b 处观察方法参数,下断点后,让程序回流。


0:013> !U 067c8359
Normal JIT generated code
System.Base.ApplicationContext+<>c.<HashObjectMap>b__19_0()
...
067c8206 50 push eax
067c8207 8bd3 mov edx,ebx
067c8209 8bcf mov ecx,edi
067c820b ff15e8667a06 call dword ptr ds:[67A66E8h] (System.Base.ApplicationContext+x4phG7d0qxdP1ZxlQa.pliOsRbOU(System.String, System.String, System.String), mdToken: 0600003e)
067c8211 8945b4 mov dword ptr [ebp-4Ch],eax
... 0:013> bp 067c820b
0:013> g-
Breakpoint 1 hit
Time Travel Position: 117A27:A80
eax=032c0ca4 ebx=032bf94c ecx=0329e558 edx=032bf94c esi=032bea78 edi=0329e558
eip=067c820b esp=079bf640 ebp=079bf6a8 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
067c820b ff15e8667a06 call dword ptr ds:[67A66E8h] ds:002b:067a66e8=067cdf00 0:013> ub 067c820b
067c81ef 8945b8 mov dword ptr [ebp-48h],eax
067c81f2 8b3d68361904 mov edi,dword ptr ds:[4193668h]
067c81f8 8b5e08 mov ebx,dword ptr [esi+8]
067c81fb b914040000 mov ecx,414h
067c8200 ff15b0647a06 call dword ptr ds:[67A64B0h]
067c8206 50 push eax
067c8207 8bd3 mov edx,ebx
067c8209 8bcf mov ecx,edi

上面输出的 ecx, edx, eax 分别就是 pliOsRbOU() 方法的三个参数。


0:013> !do ecx
Name: System.String
MethodTable: 7ad924e4
EEClass: 7ae97690
Size: 40(0x28) bytes
File: C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
String: 192.168.0.106
Fields:
MT Field Offset Type VT Attr Value Name
7ad942a8 4000283 4 System.Int32 1 instance 13 m_stringLength
7ad92c9c 4000284 8 System.Char 1 instance 31 m_firstChar
7ad924e4 4000288 70 System.String 0 shared static Empty
>> Domain:Value 00b0bce8:NotInit <<
0:013> !do edx
Name: System.String
MethodTable: 7ad924e4
EEClass: 7ae97690
Size: 46(0x2e) bytes
File: C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
String: N8CDEFGH+JKLM..P
Fields:
MT Field Offset Type VT Attr Value Name
7ad942a8 4000283 4 System.Int32 1 instance 16 m_stringLength
7ad92c9c 4000284 8 System.Char 1 instance 4e m_firstChar
7ad924e4 4000288 70 System.String 0 shared static Empty
>> Domain:Value 00b0bce8:NotInit <<
0:013> !do eax
Name: System.String
MethodTable: 7ad924e4
EEClass: 7ae97690
Size: 32(0x20) bytes
File: C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
String: TripleDES
Fields:
MT Field Offset Type VT Attr Value Name
7ad942a8 4000283 4 System.Int32 1 instance 9 m_stringLength
7ad92c9c 4000284 8 System.Char 1 instance 54 m_firstChar
7ad924e4 4000288 70 System.String 0 shared static Empty
>> Domain:Value 00b0bce8:NotInit <<

从输出中可以看到,aa 参数原来提取了我的 ip 地址,用同样的方式可以提取出所有的方法参数,这里就不详述了,我做了一个整理,截图如下:

从图中可以看到: AssistLog.svc 请求大概会提取:

  • IP地址
  • 机器码
  • 机器名
  • 时间戳
  • IP地址 + 机器码 + 时间戳

用同样的方式调查请求 http://m.365ey.net:13063/QueryLog.svc,整理如下:

这个请求中主要统计了一些接口版本等信息,并没有发现有消息的外泄,分析到这里还是比较欣慰的,将信息反馈给朋友,让朋友不要担心,应该不会有问题。

三: 总结

总的来说我还是非常相信作者,写一个 SDK 已经够辛苦了,做一些违法犯罪的事情道理上说不通,作者也就是纯技术心,想收集下用户端的使用情况,不过在未经许可的情况下确实有所不妥,但初心不坏。

如果 SDK 的作者能够帮他的使用者解答疑惑,让他的粉丝群体可以安心使用,那就更好了,在此感谢作者的辛苦付出,祝组件越来越强大。

某 .NET RabbitMQ SDK 有采集行为,你怎么看?的更多相关文章

  1. Windows SDK笔记(经典--一定要看)

    Windows SDK笔记(一):Windows程序基本结构 一.概述 Windows程序具有相对固定的结构,对编写者而言,不需要书写整个过程,大部分过程由系统完成.程序中只要按一定的格式填写系统留给 ...

  2. rabbitMQ教程(二)一篇文章看懂rabbitMQ

    一.rabbitMQ是什么: RabbitMQ,遵循AMQP协议,由内在高并发的erlanng语言开发,用在实时的对可靠性要求比较高的消息传递上. 学过websocket的来理解rabbitMQ应该是 ...

  3. rabbitMQ教程(三)一篇文章看懂rabbitMQ

    一.rabbitMQ是什么: RabbitMQ,遵循AMQP协议,由内在高并发的erlanng语言开发,用在实时的对可靠性要求比较高的消息传递上. 学过websocket的来理解rabbitMQ应该是 ...

  4. 为什么下了android 4.1 的SDK后在本地用浏览器看api说明文档时,浏览器打开api的html文件很慢?试了好几款浏览器都一样。为什么?

    http://www.oschina.net/question/436724_61401 http://www.google.com/jsapi  他惹的祸 注释掉就可以了- <!-- < ...

  5. 如何监控业务的响应速度?Cloud Insight SDK 实践分享

    一直在说 Cloud Insight 是数据聚合平台,可以用 SDK 和 API 实现业务监控,如今不拿出点实践人们恐怕是不能信服.那今天本文就先简单介绍一下 SDK 可以应用在哪些方面,再举个真实用 ...

  6. RabbitMQ 发布订阅持久化

    RabbitMQ是一种重要的消息队列中间件,在生产环境中,稳定是第一考虑.RabbitMQ厂家也深知开发者的声音,稳定.可靠是第一考虑,为了消息传输的可靠性传输,RabbitMQ提供了多种途径的消息持 ...

  7. spring boot +RabbitMQ +InfluxDB+Grafara监控实践

    本文需要有相关spring boot 或spring cloud 相关微服务框架的基础,如果您具备相关基础可以很容易的实现下述过程!!!!!!! 希望本文的所说对需要的您有所帮助 从这里我们开始进入闲 ...

  8. .NET文件并发与RabbitMQ(初探RabbitMQ)

    本文版权归博客园和作者吴双本人共同所有.欢迎转载,转载和爬虫请注明原文地址:http://www.cnblogs.com/tdws/p/5860668.html 想必MQ这两个字母对于各位前辈们和老司 ...

  9. 在C#中使用消息队列RabbitMQ

    1.什么是RabbitMQ.详见 http://www.rabbitmq.com/. 作用就是提高系统的并发性,将一些不需要及时响应客户端且占用较多资源的操作,放入队列,再由另外一个线程,去异步处理这 ...

随机推荐

  1. MySQL(一)——查看密码与修改

    查看数据库密码,策略与修改 查看数据库密码: RPM安装: # cat /var/log/mysqld.log | grep password 源码安装: # cat /usr/local/mysql ...

  2. Mybatis-Plus高级之LambdaQueryWrapper,Wrappers.<实体类>lambdaQuery的使用

    一.前言 小编今天又来分享干货了,绝对的干净又卫生,大伙请放心食用哈!Mybatis-Plus我们经常使用,但是里面的很多功能,小编开始只是知道一点点,做个增删改查没问题.小编在新项目中发现,大神们不 ...

  3. 学军中学第三届“图灵杯”趣味网络邀请赛——中级T4.欧拉回路 (图论,哈希)

    题面 补题链接 7 5 6 7 1 2 3 3 13 5 30 50 10 30 70 8 题解 存在欧拉回路的条件是:1. 每个点的度数都是偶数.2. 有边的连通块最多一个. 数据范围是允许我们 n ...

  4. ABC206 F - Interval Game 2 (区间DP,博弈论,SG函数)

    题面 题意很简单 A l i c e \tt Alice Alice 和 B o b \tt Bob Bob 在博弈.摆在他们面前有 N \rm N N 个区间 [ l i , r i ) \rm[l ...

  5. 1.6_HTML基础属性

    name 属性 name 属性用于指定标签元素的名称. <a> 标签内必须提供 href 或 name 属性. <a name="value"> id 属性 ...

  6. 【manim】学习路径1-安装篇-windows、macOS

    下一章:https://www.cnblogs.com/remyuu/p/16462369.html 本系列以大量实战讲解manim数学动画引擎. 文档编辑器推荐:Sublime Text 这里是一些 ...

  7. 配置Windows server dhcp与AD域对接并使用Win1创的用户登录Win2

    创建两台windows_server_2012 创建步骤链接(https://www.cnblogs.com/zhengyan6/p/16338084.html) 注意:所有虚拟机都要在同意网段 配置 ...

  8. Webpack与Vite热更新差异对比

    随着项目的日渐迭代,项目整体的代码量也会越来越多,从而导致项目体积越来越大:在Webpack时代,很多人会对历史项目(巨型项目)感到头疼,因为往往巨型项目在本地开发调试的时候会因为本地代码的修改触发H ...

  9. 9. 第八篇 kube-controller-manager安装及验证

    文章转载自:https://mp.weixin.qq.com/s?__biz=MzI1MDgwNzQ1MQ==&mid=2247483826&idx=1&sn=88f0cef6 ...

  10. Elasticsearch:Java 运用示例

    在今天的文章中,我们来介绍如何使用Java来访问Elasticsearch. 首先,我们必须在我们的系统中安装Elasticsearch. Maven 配置 针对Java的开发,我们必须在pom.xm ...