COM对象在
HKEY_CLASSES_ROOT\CLSID
下的注册表中列出。默认值具有COM名称和服务器DLL文件。 现在,为了列出与之关联的接口,我使用了
oleview
,对于IFileOperation,它显示了所有接口,而对于ICMLuaUtil,它仅显示了。 即使获得接口名称,也必须获得功能列表和签名,可以从
idl
文件中提取出这些信息。这里给出的一个很好的答案显示了如何通过检查示例代码并搜索与idl
文件夹中的导入名称相同的sdk
文件,从接口名称转换为其功能签名。我尝试对两个接口应用类似的方法,但部分成功。 对于IFileOperation,示例源中有4个都没有包含与sdk文件夹中的
idl
文件完全相同的文件。所以我在文件夹中搜索所有文件的内容,以查找单词IFileOperation
,从而得到了所需的文件:shobjidl_core
。 不幸的是,由于我不知道接口名称,我无法对
ICMLuaUtil
做同样的事情,我尝试了几种名称变化,但一无所获。 我尝试过的其他方法是:
从注册表中找到的DLL中提取所有文件(没有)
COMViewer应该提供其他信息但是即使在兼容模式下,它也无法在Windows 10计算机上运行(无法启动)。
我的问题是如何从(有时是未记录的)COM对象到具体的接口定义,以便可以在代码中使用它? UACMe项目为
ICMLuaUtil
定义了接口的具体定义,因此必须有一种获取接口的方法。获得这些功能签名的准则和步骤是什么?#1 楼
现在,不幸的是,这不是从A到Z的完整答案。但是对于COM来说,只有几步真正针对COM。您链接的项目显然对接口进行了反向工程(
elvint.h
)。这首先意味着接口的名称不一定与Microsoft所说的名称相匹配(不过,在您的情况下,它们是匹配的)。但是,如果实现相应COM接口或其代理DLL的二进制文件是官方系统文件,则可以为其获取PDB文件,即使Microsoft严重削减了公共符号,这通常仍可以使您为功能/方法。当然,链接项目的作者已经知道他们在寻找什么,而且似乎是“神奇地”能够以某种方式“神奇地”规避了典型UAC海拔提示的系统组件尽管应该让他们看到一个。
现在说他们发现Connection Manager配置(与RAS相关)包含了这样的功能,他们现在可以继续执行您期望的操作需要高程,但不需要。然后他们将查找加载到进程中的DLL,然后找到一个InProc服务器或将它们引导到OutProc服务器的代理。用于典型的COM导出功能束(最明显的是第一个):
br /> ...,然后检查版本信息资源。使用
DllGetClassObject
模块,这将成为一个简单的Python脚本工作。基本上,这是RCE始终要做的第一步:情报收集。它不是严格的RCE(例如进行筛选或操作反汇编),但它是我到目前为止完成的所有RCE作业的内在部分。但是对于您而言,您已经使用过oleview.exe,因此知道了最重要的信息:
...这就是为什么我的评论令人困惑:
不幸的是,我无法使用
DllCanUnloadNow
做同一件事,因为我不知道接口名称,我尝试了几种名称变体,但没有得到。
>
现在发现
DllAddRef
是实现我们感兴趣的(COM)对象的DLL,我们可以继续将其加载到IDA(或另一个反汇编程序)中,并且将提示您加载调试Microsoft的符号服务器中的符号。加载符号后,我们将看到以下内容:
要获取IDL,您需要将
DllRelease
类的vtable与当要求该特定类时DLL返回的接口指针相匹配。查看pefile
将使您能够找出IID。现在从这里开始,这将是理解拆装(或伪代码,如果您能负担得起的话)的旧工作。 decompiler插件)。
现在,如果幸运的话,如果有问题的COM服务器(通常是DLL)包含TYPELIB资源(即已编译的版本),则可以节省大量时间IDL,因此是快速进入IDL的最佳起点。对于
ICMLuaUtil
,我们很不幸。此外,如果您没有像Windows组件那样的符号,则必须深入研究从
cmlua.dll
开始的反汇编,CCMLuaUtil
是众所周知的且有据可查,并且即使对于非专业人士而言也应该很容易理解。从那里开始,并具备以下知识:任何COM接口的前三个方法都是从DllGetClassObject
继承的,然后您将尝试理解每个方法的实现(除了那些著名的前三个方法)并分配希望有意义的名称功能及其参数。也就是说:如果没有调试符号,整个任务将变得更加乏味,但并非根本不可能。评论
我什至无法想象有比这个更好的答案。非常感谢。我尝试用IDA加载DLL,实际上在获得符号后我看到了签名。我需要解析,尝试和应用很多信息。谢谢!!
– Anton.P
18年11月23日在11:55
#2 楼
答案很好,这只是演示如何在命令行中使用windbg到达而已dbh是windbg安装中的实用程序,可以加载任何二进制文件并提供大量静态信息
使用它和windbg cdb.exe的命令行版本可以在两个命令中获得方法(注意,方法名称已取消组合)
C:\>dbh c:\Windows\System32\cmlua.dll "x CCM*" | grep -i vf
11 1002d58 : CCMLuaUtil::`vftable'
C:\>cdb -c "dps cmlua.dll+2d58" -z c:\Windows\System32\cmlua.dll
Microsoft (R) Windows Debugger Version 10.0.16299.15 X86
Loading Dump File [c:\Windows\System32\cmlua.dll]
cmlua!_DllMainCRTStartup:
100061e7 8bff mov edi,edi
0:000> cdb: Reading initial command 'dps cmlua.dll+2d58'
10002d58 100042ad cmlua!CCMLuaUtil::QueryInterface
10002d5c 10004e82 cmlua!CCMLuaUtil::AddRef
10002d60 10004279 cmlua!CCMLuaUtil::Release
10002d64 10004346 cmlua!CCMLuaUtil::SetRasCredentials
10002d68 10004401 cmlua!CCMLuaUtil::SetRasEntryProperties
10002d6c 100044dd cmlua!CCMLuaUtil::DeleteRasEntry
10002d70 10004573 cmlua!CCMLuaUtil::LaunchInfSection
10002d74 100045e1 cmlua!CCMLuaUtil::LaunchInfSectionEx
10002d78 10004630 cmlua!CCMLuaUtil::CreateLayerDirectory
10002d7c 1000466e cmlua!CCMLuaUtil::ShellExec
10002d80 10004690 cmlua!CCMLuaUtil::SetRegistryStringValue
10002d84 10004701 cmlua!CCMLuaUtil::DeleteRegistryStringValue
10002d88 100055da cmlua!CCMLuaUtil::DeleteRegKeysWithoutSubKeys
10002d8c 10004767 cmlua!CCMLuaUtil::DeleteRegTree
10002d90 100048cc cmlua!CCMLuaUtil::ExitWindowsFunc
10002d94 10005c72 cmlua!CCMLuaUtil::AllowAccessToTheWorld
10002d98 100048d9 cmlua!CCMLuaUtil::CreateFileAndClose
10002d9c 1000560f cmlua!CCMLuaUtil::DeleteHiddenCmProfileFiles
10002da0 1000492a cmlua!CCMLuaUtil::CallCustomActionDll
10002da4 10004b6c cmlua!CCMLuaUtil::RunCustomActionExe
10002da8 10004c2c cmlua!CCMLuaUtil::SetRasSubEntryProperties
10002dac 10004d0e cmlua!CCMLuaUtil::DeleteRasSubEntry
10002db0 10004da7 cmlua!CCMLuaUtil::SetCustomAuthData
10002db4 10005cdb cmlua!CCMLuaUtil::`vector deleting destructor'
10002db8 00000000
10002dbc 10009138 cmlua!hProxyDll+0x10
10002dc0 10009188 cmlua!hProxyDll+0x60
10002dc4 00000000
10002dc8 69727453
10002dcc 6343676e
10002dd0 706f4368
10002dd4 20784579
0:000>
dbh有一个-d开关,它将输出错误的名称,并且您可以利用该开关将参数打印到方法上
C:\>echo off
for /F %i in ('dbh -d c:\Windows\System32\cmlua.dll "x *CCM*" ^| awk "{print }"') do dbh c:\windows\system32\cmlua.
dll undec %i
?Release@CCMLuaUtil@@UAGKXZ =
public: virtual unsigned long __stdcall CCMLuaUtil::Release(void)
??_ECCMLuaUtil@@UAEPAXI@Z =
public: virtual void * __thiscall CCMLuaUtil::`vector deleting destructor'(unsigned int)
??0CCMLuaUtil@@QAE@XZ =
public: __thiscall CCMLuaUtil::CCMLuaUtil(void)
?AddRef@CCMLuaUtil@@UAGKXZ =
public: virtual unsigned long __stdcall CCMLuaUtil::AddRef(void)
?CreateFileAndClose@CCMLuaUtil@@UAGJPBGKKKK@Z =
public: virtual long __stdcall CCMLuaUtil::CreateFileAndClose(unsigned short const *,unsigned long,unsigned long,unsigne
d long,unsigned long)
?DeleteHiddenCmProfileFiles@CCMLuaUtil@@UAGJPBG@Z =
public: virtual long __stdcall CCMLuaUtil::DeleteHiddenCmProfileFiles(unsigned short const *)
??_GCCMLuaUtil@@UAEPAXI@Z =
public: virtual void * __thiscall CCMLuaUtil::`scalar deleting destructor'(unsigned int)
?SetRasSubEntryProperties@CCMLuaUtil@@UAGJPBG0KPAPAGK@Z =
public: virtual long __stdcall CCMLuaUtil::SetRasSubEntryProperties(unsigned short const *,unsigned short const *,unsign
ed long,unsigned short * *,unsigned long)
?QueryInterface@CCMLuaUtil@@UAGJABU_GUID@@PAPAX@Z =
public: virtual long __stdcall CCMLuaUtil::QueryInterface(struct _GUID const &,void * *)
?CCMLuaUtil_CreateInstance@@YGJABU_GUID@@PAPAX@Z =
long __stdcall CCMLuaUtil_CreateInstance(struct _GUID const &,void * *)
?ExitWindowsFunc@CCMLuaUtil@@UAGJXZ =
public: virtual long __stdcall CCMLuaUtil::ExitWindowsFunc(void)
?CreateLayerDirectory@CCMLuaUtil@@UAGJPBG@Z =
public: virtual long __stdcall CCMLuaUtil::CreateLayerDirectory(unsigned short const *)
?LaunchInfSectionEx@CCMLuaUtil@@UAGJPBG0K@Z =
public: virtual long __stdcall CCMLuaUtil::LaunchInfSectionEx(unsigned short const *,unsigned short const *,unsigned lon
g)
?ShellExec@CCMLuaUtil@@UAGJPBG00KK@Z =
public: virtual long __stdcall CCMLuaUtil::ShellExec(unsigned short const *,unsigned short const *,unsigned short const
*,unsigned long,unsigned long)
?DeleteRasEntry@CCMLuaUtil@@UAGJPBG0@Z =
public: virtual long __stdcall CCMLuaUtil::DeleteRasEntry(unsigned short const *,unsigned short const *)
?DeleteRegistryStringValue@CCMLuaUtil@@UAGJHPBG0@Z =
public: virtual long __stdcall CCMLuaUtil::DeleteRegistryStringValue(int,unsigned short const *,unsigned short const *)
??_7CCMLuaUtil@@6B@ =
const CCMLuaUtil::`vftable'
?LaunchInfSection@CCMLuaUtil@@UAGJPBG00H@Z =
public: virtual long __stdcall CCMLuaUtil::LaunchInfSection(unsigned short const *,unsigned short const *,unsigned short
const *,int)
?SetCustomAuthData@CCMLuaUtil@@UAGJPBG00K@Z =
public: virtual long __stdcall CCMLuaUtil::SetCustomAuthData(unsigned short const *,unsigned short const *,unsigned shor
t const *,unsigned long)
?DeleteRasSubEntry@CCMLuaUtil@@UAGJPBG0K@Z =
public: virtual long __stdcall CCMLuaUtil::DeleteRasSubEntry(unsigned short const *,unsigned short const *,unsigned long
)
?DeleteRegTree@CCMLuaUtil@@UAGJHPBG@Z =
public: virtual long __stdcall CCMLuaUtil::DeleteRegTree(int,unsigned short const *)
?DeleteRegKeysWithoutSubKeys@CCMLuaUtil@@UAGJHPBGH@Z =
public: virtual long __stdcall CCMLuaUtil::DeleteRegKeysWithoutSubKeys(int,unsigned short const *,int)
?CallCustomActionDll@CCMLuaUtil@@UAGJPBG000PAK@Z =
public: virtual long __stdcall CCMLuaUtil::CallCustomActionDll(unsigned short const *,unsigned short const *,unsigned sh
ort const *,unsigned short const *,unsigned long *)
?SetRegistryStringValue@CCMLuaUtil@@UAGJHPBG00@Z =
public: virtual long __stdcall CCMLuaUtil::SetRegistryStringValue(int,unsigned short const *,unsigned short const *,unsi
gned short const *)
?SetRasCredentials@CCMLuaUtil@@UAGJPBG00H@Z =
public: virtual long __stdcall CCMLuaUtil::SetRasCredentials(unsigned short const *,unsigned short const *,unsigned shor
t const *,int)
?SetRasEntryProperties@CCMLuaUtil@@UAGJPBG0PAPAGK@Z =
public: virtual long __stdcall CCMLuaUtil::SetRasEntryProperties(unsigned short const *,unsigned short const *,unsigned
short * *,unsigned long)
?AllowAccessToTheWorld@CCMLuaUtil@@UAGJPBG@Z =
public: virtual long __stdcall CCMLuaUtil::AllowAccessToTheWorld(unsigned short const *)
?RunCustomActionExe@CCMLuaUtil@@UAGJPBG0PAPAG@Z =
public: virtual long __stdcall CCMLuaUtil::RunCustomActionExe(unsigned short const *,unsigned short const *,unsigned sho
rt * *)
#3 楼
这只是@ 0xC0000022L答案的扩展。对于这个问题,我将在下面解释ICMLuaUtil COM接口,因为IFileOperation COM接口在shell32.dll
中,太大;)您提到了错误的CLSID。在这里,我提供了它们的列表:
GUID CLSID_CmstpLua = {3E5FC7F9-9A51-4367-9063-A120244FBEC7}
GUID IID_ICmstpLua = {6EF07F29-F9B8-4DA4-B59E-13DEA060AD60}
GUID IID_ICmstpLua2 = {AE8AFD54-5B57-4961-8A9B-12ADF23B696A}
GUID CLSID_CMLuaUtil = {3E000D72-A845-4CD9-BD83-80C07C3B881F}
GUID IID_ICMLuaUtil = {6EDD6D74-C007-4E75-B76A-E5740995E24C}
如何从CLSID查找DLL文件路径不使用任何第三方程序?在RegEdit中打开此注册表路径
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{CLSID}
。对于这种情况,请尝试以下命令:REG Query "HKLM\SOFTWARE\Classes\CLSID\{3E000D72-A845-4CD9-BD83-80C07C3B881F}\InprocServer32" /VE
REG Query "HKLM\SOFTWARE\Classes\Interface\{6EDD6D74-C007-4E75-B76A-E5740995E24C}" /VE
路径为
%SystemRoot%\System32\cmlua.dll
。在IDA(或任何反汇编程序/反编译器)中将其打开,然后加载PDB符号文件。使用Shift + F3转到函数窗口,然后在该窗口中键入这些单词来搜索构造函数或析构函数。在装配视图中打开该功能。必须有一个像const CCMLuaUtil::vftable
这样的变量,因为您知道为什么。双击它,您将在程序集视图中看到该COM类的布局。 组装视图有很多优点。在程序集视图中,该类中的所有方法均按实际顺序放置,但功能窗口可能未放置(根据设置)。这些方法实际上是作为函数指针放置的。对于64位二进制文件,在每种方法之前(在上面的屏幕截图中),将存在
dq
(qword 8字节)。前三个方法是从IUnknown接口继承的。如果要用C编写该类(作为结构体),则必须包括这三个类。可以在我的GitHub仓库WslReverse中看到这种方法的真实示例,在其中显示了LxssManager.DLL
的隐藏COM接口。也是有关实用C ++反编译的视频|侦察2011 |伊戈尔·斯科钦斯基(Igor Skochinsky)对我有很大帮助。评论
对于额外的信息,我当然也会介绍,但是我有一个初步的问题,您如何知道哪个接口与哪个CLSID相关?在oleview中,CMLuaUtil没有任何与之关联的接口
– Anton.P
18年11月26日在12:04
我的问题是,您如何理解IID_ICMLuaUtil与CLSID_CMLuaUtil相关? (当然不是必须的名称,例如在IFileOperation COM中,某些受支持的接口不共享其名称)。这些命令确实揭示了DLL,但我无法理解完善它们之间链接的一般方法。
– Anton.P
18年11月26日在18:20
@ Anton.P这可能是过于简化的答案:i.stack.imgur.com/ZpIRF.png
– Biswapriyo
18年11月26日在18:40
评论
嗨,欢迎来到RE.SE!我很困惑。句子之一像一样拖尾。而且,为什么您认为需要接口名称? IID / CLSID / GUID是COM永远关心的全部。一切都从IUnknown开始,文档(MSDN)和几本书都详细解释了如何实例化COM对象。但是,这些都是非RCE主题。是否存在接口定义(IDL或其他)仅取决于作者。毕竟,COM旨在允许黑匣子对象彼此交互。只有主叫方和被叫方才需要知道。@ 0xC0000022L感谢您抽出宝贵的时间来理解问题。我确实意识到处理COM(CoCreateInstance,CoGetObject ..)的函数仅需要IID / CLSID。对于ICMLuaUtil,让我来缩小问题的范围,在这里我没有接口名称/ IDL文件,如何获得IID以及如何找出方法签名?它已经完成过,我希望学习如何重现结果(github.com/hfiref0x/UACME/blob/…)
@ Anton.P您是否具备C ++类,构造函数,析构函数,继承的基本知识?我想添加一些信息。
@Biswapriyo是的,我熟悉C ++(非常了解C ++,并且熟悉您列出的概念),并且很高兴获得更多信息