RpcView简介

一、RpcView

参[3]

1、 下载RpcView源码

先用git下载RpcView源码,大概13MB。

$ https_proxy=socks5://<ip>:<port> git clone https://github.com/silverf0x/RpcView.git RpcView

2、 Visual Studio 2019 社区版

VS 2019社区版自带git、cmake,不需要下载安装它们,就用自带的。没让它们出现在PATH环境变量中,不喜欢动动辄往PATH中加东西。

3、Qt 5.15.2

参[4]

不确认其他Qt版本行不行,反正RpcView作者写的是VS 2019+Qt 5.15.2。

Qt 5.15不再提供离线安装包。有人从5.15.2源码自行编译,编译Windows版比较费劲,没这刚需,我选用在线安装包。

https://www.qt.io/download-qt-installer

在线安装包大约23MB。在线安装需要user/pass。

为编译RpcView只需很少的Qt组件,选中这些项。

安装到C:\Qt,装完大约2.3GB。在线安装结束后想补充安装或卸载组件,双击执行C:\Qt\MaintenanceTool.exe。

4、 编译RpcView源码

在源码根目录自行创建Build子目录,其下有x86、x64两个子目录。

mkdir Build\x86

mkdir Build\x64

4.1 编译64位RpcView

我不想动PATH环境变量,用VS 2019自带cmake,为编译RpcView只需cl这些命令行工具,用不上GUI。打开”x64 Native Tools Command Prompt for VS 2019″

实际只能生成RpcView.exe,最重要的RpcDecompiler.dll未能生成,编译时提示

就是说,当前代码页是936,但internalRpcDecompTypeDefs.h的698行附近出现超范围字符。这本来是”warning C4819″,由于启用了/WX编译选项,变成”error C2220″,导致RpcDecompiler.dll未能生成。

检视源码发现,超范围字符都在注释中,不影响二进制。最简办法是修改源码根目录下的CMakeLists.txt,删掉/WX编译选项

下面几种办法无法解决上述问题

执行第二条cmake命令重新编译

$ dir /B bin\Release\*.exe bin\Release\*.dll

RpcView.exe

RpcCore1_32bits.dll

RpcCore2_32bits.dll

RpcCore2_64bits.dll

RpcCore3_32bits.dll

RpcCore3_64bits.dll

RpcCore4_32bits.dll

RpcCore4_64bits.dll

RpcDecompiler.dll

4.2 运行自编译64位RpcView

cd /d Z:\work\RpcView\Build\x64\bin\Release

mkdir Green\platforms

copy *.exe Green

copy *.dll Green

copy C:\Qt\5.15.2\msvc2019_64\bin\Qt5Core.dll Green

copy C:\Qt\5.15.2\msvc2019_64\bin\Qt5Gui.dll Green

copy C:\Qt\5.15.2\msvc2019_64\bin\Qt5Widgets.dll Green

copy C:\Qt\5.15.2\msvc2019_64\bin\Qt5WinExtras.dll Green

copy C:\Qt\5.15.2\msvc2019_64\plugins\platforms\qwindows.dll Green\platforms

Z:\work\RpcView\Build\x64\bin\Release\Green\RpcView.exe

$ tree /f /a Green

|   Qt5Core.dll

|   Qt5Gui.dll

|   Qt5Widgets.dll

|   Qt5WinExtras.dll

|   RpcCore1_32bits.dll

|   RpcCore2_32bits.dll

|   RpcCore2_64bits.dll

|   RpcCore3_32bits.dll

|   RpcCore3_64bits.dll

|   RpcCore4_32bits.dll

|   RpcCore4_64bits.dll

|   RpcDecompiler.dll

|   RpcView.exe

|

\—platforms

        qwindows.dll

参[5],作者演示了一种偷懒的布署方式

cd /d Z:\work\RpcView\Build\x64\bin\Release

mkdir RpcView64

copy *.exe RpcView64

copy *.dll RpcView64

C:\Qt\5.15.2\msvc2019_64\bin\windeployqt.exe –release RpcView64

windeployqt.exe会向RpcView64子目录复制Qt的库文件,用不用得上都复制过去。

4.3 编译32位RpcView

假设已经修改过根目录下的CMakeLists.txt

打开”x86 Native Tools Command Prompt for VS 2019″

cd /d Z:\work\RpcView\Build\x86

set CMAKE_PREFIX_PATH=C:\Qt\5.15.2\msvc2019\

cmake ../../ -A win32

cmake –build . –config Release

$ dir /B bin\Release\*.exe bin\Release\*.dll

RpcView.exe

RpcCore1_32bits.dll

RpcCore2_32bits.dll

RpcCore3_32bits.dll

RpcCore4_32bits.dll

RpcDecompiler.dll

4.4 运行自编译32位RpcView

cd /d Z:\work\RpcView\Build\x86\bin\Release

mkdir Green\platforms

copy *.exe Green

copy *.dll Green

copy C:\Qt\5.15.2\msvc2019\bin\Qt5Core.dll Green

copy C:\Qt\5.15.2\msvc2019\bin\Qt5Gui.dll Green

copy C:\Qt\5.15.2\msvc2019\bin\Qt5Widgets.dll Green

copy C:\Qt\5.15.2\msvc2019\bin\Qt5WinExtras.dll Green

copy C:\Qt\5.15.2\msvc2019\plugins\platforms\qwindows.dll Green\platforms

Z:\work\RpcView\Build\x86\bin\Release\Green\RpcView.exe

$ tree /f /a Green

|   Qt5Core.dll

|   Qt5Gui.dll

|   Qt5Widgets.dll

|   Qt5WinExtras.dll

|   RpcCore1_32bits.dll

|   RpcCore2_32bits.dll

|   RpcCore3_32bits.dll

|   RpcCore4_32bits.dll

|   RpcDecompiler.dll

|   RpcView.exe

|

\—platforms

        qwindows.dll

5、为什么需要编译RpcView源码

https://github.com/silverf0x/RpcView

此处提供预编译好的RpcView,若在测试环境中直接可用,则无需自编译源码。参[5],执行预编译版本很可能遭遇这个提示。

修改这几个文件

Z:\work\RpcView\RpcCore\RpcCore4_64bits\RpcInternals.h

Z:\work\RpcView\RpcCore\RpcCore4_32bits\RpcInternals.h

假设测试环境中rpcrt4.dll的版本是10.0.14393.4704,需要在如下数组中增加这个版本信息。

这是某个Win10环境,若是其他OS其他rpcrt*.dll,找相应文件做类似修改。

RpcCore1 for Windows XP

RpcCore2 for Windows 7

RpcCore3 for Windows 8

RpcCore4 for Windows 8.1 and 10

cmake –build . –config Release

重新编译、运行。

6、Patch RpcView

RpcView的版本检查相当保守。该软件在做Hacking,这么保守可以理解,避免进程崩溃么。但它这种搞法,每打一次rpcrt4.dll相关的补丁,就得自编译,有些受不了。

作者提到

对于Win10,在可以想见的相当长的时间范围内,都不需要重新逆向rpcrt4.dll去适配相关数据结构,仅仅是一个版本检查的事儿。假设手头有预编译版RpcView,着急在测试环境中用,完全可以进行二进制Patch。

$ ls -l RpcCore4*.dll

-rwxrwxrwx 1 scz scz 27648 Nov  9  2017 RpcCore4_32bits.dll

-rwxrwxrwx 1 scz scz 27648 Nov  9  2017 RpcCore4_64bits.dll

$ sha256sum RpcCore4*.dll

3a7ec71fc68fd5644269961187c7fc5e27f97c8655435cf0775670d348dbb327  RpcCore4_32bits.dll

3ec945caaeab442477823125d23b9f0f80bb1ec1e8c1581dd5ecd6c0965a0cca  RpcCore4_64bits.dll

将10.0.10240.16384这种古老版本换成10.0.14393.4704

0xA000028004000LL,  //10.0.10240.16384

0xA000038391260LL,  //10.0.14393.4704

$ python3 -c “import sys;x=sys.argv[1];print(”.join(map(str.__add__,x[-2::-2],x[-1::-2])))” 0A000028004000

0040002800000A

$ python3 -c “import sys;x=sys.argv[1];print(”.join(map(str.__add__,x[-2::-2],x[-1::-2])))” 0A000038391260

6012393800000A

用WinHex打开RpcCore4_64bits.dll、RpcCore4_32bits.dll,搜索”0040002800000A”,

将之替换成”6012393800000A”。

$ fc /b RpcCore4_32bits.dll.orig RpcCore4_32bits.dll

00005AC0: 00 60

00005AC1: 40 12

00005AC2: 00 39

00005AC3: 28 38

$ fc /b RpcCore4_64bits.dll.orig RpcCore4_64bits.dll

00005AC0: 00 60

00005AC1: 40 12

00005AC2: 00 39

00005AC3: 28 38

执行Patch过的预编译RpcView成功。

7、使用RpcView

参[5],我是看到这篇才注意到RpcView的,毕竟很多年不挖洞。

a) 以管理员身份运行RpcView.exe,在Process框中找目标进程,比如lsass.exe

b) 在Interfaces框中选接口,Procedures框中出现相应接口的远程过程列表

c) 在Interfaces框中选中某个接口后,右键Decompile,在Decompilation框中出现相应接口的IDL

d) RpcView支持微软符号,[5]的作者说不支持符号服务器,只支持符号目录,可能得提前下载符号

   Options->Configure Symbols->

   srv*z:\sym*http://msdl.microsoft.com/download/symbols

RpcView生成的IDL不错。十几年前自己写过rpcdig.idc,用来挖MS/DCE RPC的洞。后来开发Nessus的Tenable公司公开过一个IDA插件mIDA,从PE中逆向生成IDL,效果非常好,风靡一时。

https://github.com/tenable/mIDA

https://github.com/sourceincite/tools/tree/master/pymsrpc/mIDA

mIDA only works with the Windows GUI version of IDA (5.2 or later).

mIDA是C++写的,后来没再更新过,估计早已不能适配高版本IDA。RpcView是个很不错的替代品。

我现在拿RpcView当交互式调试工具用,不挖洞、不Fuzz,但更多人可能有RPC挖洞需求,[5]值得一阅,早看过的当我没说。

下次举例写一下如何用RpcView辅助调试。

8、命令行参数

多看一眼RpcCore.c中RpcCoreInit(),注意该函数有个形参bForce,当其为真时进行掩码式版本检查,只要大版本接近就认为版本检查通过,比如10.0.x.x都算同一个版本。顺藤摸瓜,在RpcView.cpp中wWinMain()看到两个命令行参数

/f  force loading for unsupported runtime versions

/DA decompile all interfaces

/f同时在main()、wWinMain()中,可以直接用。不必修改RpcInternals.h,直接编译git回来的源码,指定/f执行

Z:\work\RpcView\Build\x64\bin\Release\Green\RpcView.exe /f

前面不该吐槽RpcView的版本检查,人家洗心革面过。

/DA只在main()中,不能直接用。DecompileAllInterfaces()向控制台输出,如有此类需求,启用_DEBUG宏,编译CLI版本。

8.1 预编译版本不支持/f参数

预编译RpcView用的源码比git旧,不支持/f参数,IDA反编译确认。自编译RpcView的价值体现出来了。

参考资源

[3] RpcView

https://github.com/silverf0x/RpcView

    (a tool to explore and decompile all RPC functionalities)

[4] Qt

https://download.qt.io/archive/qt/

https://download.qt.io/archive/qt/5.15/5.15.2/

https://www.qt.io/download-qt-installer

    (qt-unified-windows-x86-4.1.1-online.exe)

[5] 尝试进行RPC漏洞挖掘 – houjingyi [2019-01-09]

https://cert.360.cn/report/detail?id=44669690fc7a8daab42472cebd8cfb88

版权声明

本站“技术博客”所有内容的版权持有者为绿盟科技集团股份有限公司(“绿盟科技”)。作为分享技术资讯的平台,绿盟科技期待与广大用户互动交流,并欢迎在标明出处(绿盟科技-技术博客)及网址的情形下,全文转发。
上述情形之外的任何使用形式,均需提前向绿盟科技(010-68438880-5462)申请版权授权。如擅自使用,绿盟科技保留追责权利。同时,如因擅自使用博客内容引发法律纠纷,由使用者自行承担全部法律责任,与绿盟科技无关。

Spread the word. Share this post!

Meet The Author

C/ASM程序员

Leave Comment