如何针对其他应用程序/COM 对象对 Windows 应用程序进行身份验证
我的系统中有 3 个组件:
- COM 对象 - 为具有 func1()、func2() 的应用程序提供服务
- App1 - 受信任的应用程序需要使用 com 对象 funcs (1 和 2)
- App2 - 恶意应用程序,未授权使用 func1(),可以使用 func2() 它是无害的。
COM 对象 如何“验证”App1 并允许其使用 func1() 和 func2()并拒绝从 App2 访问 func1() ?
一种方法是仅允许管理员用户访问 func1(),但这不是一个好的解决方案,因为安全最佳实践:使用最低权限的用户运行。 App1 只需要管理员权限即可访问 COM 对象,App1 中的任何安全漏洞都会为攻击者提供管理员权限。
如何解决这个问题?
I have 3 components in my system:
- COM Object - Provide Services to application that has func1(), func2()
- App1 - Trusted Application that need to use the com object funcs (1 and 2)
- App2 - Malicious application, not authorized to use func1(), can use func2() it is not harmful.
How can the COM Object can "authenticate" App1 and allowing it to use func1() and func2() and deny access to func1() from App2 ?
One way to do it is by allowing only Administrators users to access func1() but this is not a good solution because of security best practice: run with least privileged user. App1 will only need admin to access to the COM Object, any security hole in App1 will give the attacker Admin access.
How can this be solved?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
一般来说,您应该更准确地定义如何您想要划分(识别)“好”应用程序,以便允许其他“坏”应用程序使用您的 COM 对象。
如果您的 COM 对象是进程内服务器(一个 DLL,将加载到使用它的应用程序的地址空间中),那么您可以制定“快速且肮脏”的解决方案:在
DllMain
内部你可以测试加载你的dll的exe文件的名称。您可以使用GetModuleFileName
将NULL
作为第一个参数来执行此操作。如果“错误”的 exe 尝试加载您的 dll,DllMain
可能会返回FALSE
。您可以在任何方法(而不是DllMain
)中执行相同的测试。解决问题的最佳通用方法(我认为最好的方法)是向 COM 对象添加一个附加方法,您可以使用该方法对调用者进行授权。例如,要使用任何“秘密”函数(例如
func1()
),您可以要求调用者先调用另一个authorize()
函数。调用者向您的 COM 对象提供一些信息作为authorize()
的输入参数,这些信息可用于验证调用者权限。如果授权成功,authorize()
将返回一个授权令牌 (cookie),它可以是您稍后可以轻松验证的任何内容。最好的代币应该基于数字签名等加密算法。函数func1()
可以有一个附加参数 - 从authorize1()
接收的令牌 (cookie)。通过这种方式,您可以实现您想要的任何类型的授权。这种方式适用于任何类型的 COM 对象(不仅适用于进程内服务器)。In general you should define more exactly how you want to devide (identify) "good" aplication which are allowed to use your COM object from other "bad" applications.
If your COM object are in-proc server (a DLL which will be loaded in the address space of the application which use it) then you can make "quick & dirty" solution: Inside of the
DllMain
you can test the name of the exe file which loaded your dll. You can do this with respect ofGetModuleFileName
withNULL
as the first parameter. If a "wrong" exe try to load your dll theDllMain
can returnFALSE
. The same test you can do in any of your method instead ofDllMain
.The best general way to solve your problem (the best which I see of cause) will be to add an additional method to your COM Object which you can use to authorize the caller. For example, to use any "secret" functions like
func1()
you can require the caller to call anotherauthorize()
function before. The caller give your COM Object as input prameter ofauthorize()
some information which can be used to verify the caller permissions. If the authorization is OK,authorize()
will gives back an authorization token (cookie) which can be anything which you can easy to verify later. The best tokens should be based on cryptografical algorithms like digitaly signing. The functionfunc1()
can have an additional parameter - the token (cookie) received fromauthorize1()
. In this way you can implement any kind of authorization which you want. This way will works with any kind of COM Objects (not only with in-proc-servers).我认为 @quip 指的是支持许可的 IClassFactory2 接口集。请参阅此处:
http://msdn.microsoft。 com/en-us/library/ms680095(v=VS.85).aspx
本文涉及每台计算机许可证(这不是您想要的)和运行时许可证密钥,这听起来像您正在寻找的内容。
要点是,获得授权的 App1 应该调用 CoGetClassObject() 来获取实现 IClassFactory2 的对象,然后调用 IClassFactory2::CreateInstanceLic() 并传入一个密钥,让 COM 服务器知道它已获得授权。这将依次使用适当的标志实例化您的 COM 对象,表明该对象可以完全使用(假设有有效的密钥)。如果传入无效密钥,请初始化 COM 对象以供未经授权的客户端使用。
未经授权的App2将调用标准的CoCreateInstance(),该标准的CoCreateInstance()在幕后调用CoGetClassObject()来获取实现IClassFactory的对象,然后调用IClassFactory::CreateInstance()。此实现应该使用为未经授权的客户端设置的标志来实例化您的 COM 对象。
I think @quip was referring to the IClassFactory2 set of interfaces that supports licensing. See here:
http://msdn.microsoft.com/en-us/library/ms680095(v=VS.85).aspx
The article touches on per machine licenses (which is not what you want) and runtime license keys which sounds like what you are looking for.
The point is that App1 which is authorized, should call CoGetClassObject() to get an object that implements IClassFactory2, and then call IClassFactory2::CreateInstanceLic() passing in a secret key that lets the COM server know that it is authorized. This will in turn instantiate your COM object with the appropriate flags indicating that is available for full use (assuming a valid key). If an invalid key is passed in, initialize your COM object for use by an unauthorized client.
App2 which is not authorized, will call the standard CoCreateInstance() which under the covers call CoGetClassObject() to get an object that implements IClassFactory, and then call IClassFactory::CreateInstance(). This implementation should instantiate your COM object with flags set for an unauthorized client.
Windows 安全性是基于用户的,因此我不相信您能够在应用程序级别执行此操作。如果用户可以执行该函数,那么两个程序都可以执行该函数。
Windows security is user based so I do not believe that you will be able to do this at the application level. If the user can execute the function, then both programs will be able to execute the function.