标题: RpcView简介 创建: 2021-10-27 09:57 更新: 2021-12-20 17:01 链接: https://scz.617.cn/windows/202110270957.txt -------------------------------------------------------------------------- 目录: ☆ RpcView 1) 下载RpcView源码 2) Visual Studio 2019 社区版 3) Qt 5.15.2 4) 编译RpcView源码 4.1) 编译64位RpcView 4.2) 运行自编译64位RpcView 4.3) 编译32位RpcView 4.4) 运行自编译32位RpcView 5) 为什么需要编译RpcView源码 6) Patch RpcView 7) 使用RpcView 8) 命令行参数 8.1) 预编译版本不支持/f参数 ☆ 参考资源 -------------------------------------------------------------------------- ☆ RpcView 参[3],RpcView可以逆向生成RPC接口所对应的IDL 1) 下载RpcView源码 https://github.com/silverf0x/RpcView 先用git下载RpcView源码,大概13MB。 $ https_proxy=socks5://: git clone https://github.com/silverf0x/RpcView.git RpcView 2) Visual Studio 2019 社区版 -------------------------------------------------------------------------- Visual Studio 2019 社区版 https://visualstudio.microsoft.com/zh-hans/downloads/ https://visualstudio.microsoft.com/zh-hans/thank-you-downloading-visual-studio/?sku=Community&rel=16 -------------------------------------------------------------------------- VS 2019社区版自带git、cmake,不需要下载安装它们,就用自带的。没让它们出现 在PATH环境变量中,不喜欢动动辄往PATH中加东西。 3) Qt 5.15.2 参[4] 不确认其他Qt版本行不行,反正RpcView作者写的是VS 2019+Qt 5.15.2。 https://download.qt.io/archive/qt/5.15/5.15.2/OFFLINE_README.txt Due to The Qt Company offering changes, open source offline installers are not available any more since Qt 5.15. Qt 5.15不再提供离线安装包。有人从5.15.2源码自行编译,编译Windows版比较费劲, 没这刚需,我选用在线安装包。 https://www.qt.io/download-qt-installer 需要将在线安装包从UNC路径复制到本地,大约23MB。在线安装需要user/pass 为编译RpcView只需很少的Qt组件,选中这些项 I have read and approve the obligations of using Open Source Qt I am an individual person not using Qt for any company Disable sending pseudonymous usage statistics in Qt Creator Associate common file types with Qt Creator (清空) Custom installation Archive LTS Qt 5.15.2 MSVC 2019 32-bit MSVC 2019 64-bit Developer and Designer Tools (不装任何子项) 安装到 C:\Qt 装完大约2.3GB 在线安装结束后想补充安装或卸载组件,双击执行 C:\Qt\MaintenanceTool.exe 4) 编译RpcView源码 $ tree /f /a . Z:\work\RpcView | CMakeLists.txt // 将来需要修改 | ... | +---Build // 自行创建的子目录 | +---x64 | \---x86 +---Qt | Qt.h | +---RpcCommon | ... | +---RpcCore | | ... | | ... | | | +---RpcCore4_32bits | | RpcInternals.h // 将来需要修改 | | | \---RpcCore4_64bits | RpcInternals.h // 将来需要修改 | +---RpcDecompiler | .... | \---RpcView ... 在源码根目录自行创建Build子目录,其下有x86、x64两个子目录。 mkdir Build\x86 mkdir Build\x64 4.1) 编译64位RpcView 理想情况下这样编译 cd /d Z:\work\RpcView\Build\x64 set CMAKE_PREFIX_PATH=C:\Qt\5.15.2\msvc2019_64\ "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" ../../ -A x64 "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" --build . --config Release 我不想动PATH环境变量,用VS 2019自带cmake,为编译RpcView只需cl这些命令行工 具,用不上GUI。若不想这么长的路径,还可以 打开"x64 Native Tools Command Prompt for VS 2019" cd /d Z:\work\RpcView\Build\x64 set CMAKE_PREFIX_PATH=C:\Qt\5.15.2\msvc2019_64\ cmake ../../ -A x64 cmake --build . --config Release 实际只能生成RpcView.exe,最重要的RpcDecompiler.dll未能生成,编译时提示 -------------------------------------------------------------------------- Z:\work\RpcView\RpcDecompiler\internalRpcDecompTypeDefs.h(698,1): error C2220: the following warning is treated as an e rror (compiling source file Z:\work\RpcView\RpcDecompiler\InternalComplexTypesMisc.cpp) [Z:\work\RpcView\Build\x64\RpcD ecompiler\RpcDecompiler.vcxproj] Z:\work\RpcView\RpcDecompiler\internalRpcDecompTypeDefs.h(698,1): warning C4819: The file contains a character that can not be represented in the current code page (936). Save the file in Unicode format to prevent data loss (compiling sour ce file Z:\work\RpcView\RpcDecompiler\InternalComplexTypesMisc.cpp) [Z:\work\RpcView\Build\x64\RpcDecompiler\RpcDecompi ler.vcxproj] -------------------------------------------------------------------------- 就是说,当前代码页是936,但internalRpcDecompTypeDefs.h的698行附近出现超范 围字符。这本来是"warning C4819",由于启用了/WX编译选项,变成"error C2220", 导致RpcDecompiler.dll未能生成。 检视源码发现,超范围字符都在注释中,不影响二进制。最简办法是修改源码根目录 下的CMakeLists.txt,删掉/WX编译选项 -------------------------------------------------------------------------- #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8") #set(CMAKE_CXX_FLAGS_RELEASE "/W4 /WX /O2 /Oi /Ot /Gy /MD /EHsc /MP") #set(CMAKE_C_FLAGS_RELEASE "/W4 /WX /O2 /Oi /Ot /Gy /MD /EHsc /MP") set(CMAKE_CXX_FLAGS_RELEASE "/W4 /O2 /Oi /Ot /Gy /MD /EHsc /MP") set(CMAKE_C_FLAGS_RELEASE "/W4 /O2 /Oi /Ot /Gy /MD /EHsc /MP") -------------------------------------------------------------------------- 下面几种办法无法解决上述问题 chcp 437 chcp 65001 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8") 执行第二条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], 执行预编译版本很可能遭遇这个提示 -------------------------------------------------------------------------- Unsupported runtime version Please send us a mail to contact@rpcview.org with your rpcrt4.dll files ( in System32 and SysWOW64 directories) OK -------------------------------------------------------------------------- 修改这几个文件 Z:\work\RpcView\RpcCore\RpcCore4_64bits\RpcInternals.h Z:\work\RpcView\RpcCore\RpcCore4_32bits\RpcInternals.h 假设测试环境中rpcrt4.dll的版本是10.0.14393.4704,需要在如下数组中增加这个 版本信息 -------------------------------------------------------------------------- static UINT64 RPC_CORE_RUNTIME_VERSION[] = { ... 0xA000028004000LL, //10.0.10240.16384 ... 0xA000038390A69LL, //10.0.14393.2665 0xA000038390C2BLL, //10.0.14393.3115 0xA000038391260LL, //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\RpcCore\RpcCore.c */ VOID* __fastcall RpcCoreInit(BOOL bForce) { UINT64 RuntimVersion; RpcCoreInternalCtxt_T* pRpcCoreInternalCtxt=NULL; WCHAR RpcRuntimePath[MAX_PATH]; UINT i; BOOL bFound = FALSE; ... // // Get the RPC runtime version (rpcrt4.dll) to verify if it is supported by this Core // if (GetSystemDirectoryW(RpcRuntimePath,_countof(RpcRuntimePath))==0) goto End; StringCbPrintfW(RpcRuntimePath,sizeof(RpcRuntimePath),L"%s\\rpcrt4.dll",RpcRuntimePath); RuntimVersion=GetModuleVersion(RpcRuntimePath); /* * 在RPC_CORE_RUNTIME_VERSION[]中寻找当前rpcrt4.dll的版本,若无,则认 * 为不支持 */ for (i = 0; i < _countof(RPC_CORE_RUNTIME_VERSION); i++) { if (bForce && ((RuntimVersion & 0xFFFFFFFF00000000) == (RPC_CORE_RUNTIME_VERSION[i] & 0xFFFFFFFF00000000))) { bFound = TRUE; break; } if (RuntimVersion == RPC_CORE_RUNTIME_VERSION[i]) { bFound = TRUE; break; } } -------------------------------------------------------------------------- RpcView的版本检查相当保守。该软件在做Hacking,这么保守可以理解,避免进程崩 溃么。但它这种搞法,每打一次rpcrt4.dll相关的补丁,就得自编译,有些受不了。 作者提到 -------------------------------------------------------------------------- How to add a new RPC runtime Basically you have two possibilities to support a new RPC runtime (rpcrt4.dll) version: The easy way: just edit the RpcInternals.h file in the corresponding RpcCore directories (32 and 64-bit versions) to add your runtime version in the RPC_CORE_RUNTIME_VERSION table. The best way: reverse the rpcrt4.dll to define the required structures used by RpcView, e.g. RPC_SERVER, RPC_INTERFACE and RPC_ADDRESS. -------------------------------------------------------------------------- 对于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不支持 srv*\\vmware-host\Shared Folders\sym*http://msdl.microsoft.com/download/symbols 只能用 srv*z:\sym*http://msdl.microsoft.com/download/symbols RpcView生成的IDL不错。十几年前自己写过rpcdig.idc,用来挖DCE/MS RPC的洞。后 来开发Nessus的Tenable公司公开过一个IDA插件mIDA,从PE中逆向生成IDL,效果非 常好,风靡一时。 https://github.com/tenable/mIDA https://github.com/sourceincite/tools/tree/master/pymsrpc/mIDA mIDA is an IDA plugin which extracts RPC interfaces and recreates the associated IDL file. mIDA supports inline, interpreted and fully interpreted server stubs. 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.14/5.14.2/qt-opensource-windows-x86-5.14.2.exe https://download.qt.io/archive/qt/5.14/5.14.2/md5sums.txt (077a9888560bace2d56f8eed995db58c) https://mirrors.tuna.tsinghua.edu.cn/qt/archive/qt/5.14/5.14.2/qt-opensource-windows-x86-5.14.2.exe https://download.qt.io/archive/qt/5.15/5.15.2/ https://download.qt.io/archive/qt/5.15/5.15.2/single/qt-everywhere-src-5.15.2.tar.xz https://download.qt.io/archive/qt/5.15/5.15.2/OFFLINE_README.txt https://mirrors.tuna.tsinghua.edu.cn/qt/archive/qt/5.15/5.15.2/single/qt-everywhere-src-5.15.2.tar.xz 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