一、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)申请版权授权。如擅自使用,绿盟科技保留追责权利。同时,如因擅自使用博客内容引发法律纠纷,由使用者自行承担全部法律责任,与绿盟科技无关。