您的位置:首页 > 其它

创建SYSTEM用户权限的进程

2013-02-22 11:25 387 查看
#include <stdio.h>

#include <windows.h>

#include <Tlhelp32.h>

#include <AccCtrl.h>

#include <Aclapi.h>

typedef NTSTATUS (WINAPI *pfRtlAdjustPrivilege)(

ULONG Privilege,

BOOLEAN Enable,

BOOLEAN CurrentThread,

PBOOLEAN Enabled);

void AdjustPrivilege()

{

pfRtlAdjustPrivilege RtlAdjustPrivilege = NULL;

RtlAdjustPrivilege = (pfRtlAdjustPrivilege)GetProcAddress(GetModuleHandle("NTDLL.DLL"), "RtlAdjustPrivilege");

if(RtlAdjustPrivilege)

{

BOOLEAN blPev;

RtlAdjustPrivilege(20, TRUE, FALSE, &blPev);

printf("提权成功: %d\n", blPev);

}

}

DWORD GetProcessID( LPSTR lpName)

{

if(!lpName)

{

return 0;

}

HANDLE hProcessSnap = NULL;

BOOL bRet = FALSE;

PROCESSENTRY32 pe32 = {0};

DWORD dwProcessId = 0;

hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

if (hProcessSnap == INVALID_HANDLE_VALUE)

return dwProcessId;

pe32.dwSize = sizeof(PROCESSENTRY32);

if (Process32First(hProcessSnap, &pe32))

{

do

{

if(stricmp(pe32.szExeFile, lpName) == 0)

{

dwProcessId = pe32.th32ProcessID;

CloseHandle (hProcessSnap);

return dwProcessId;

}

}

while (Process32Next(hProcessSnap, &pe32));

}

CloseHandle(hProcessSnap);

return dwProcessId;

}

BOOL CreateSystemProcess(LPTSTR szProcessName, LPTSTR szCmdLine)

{

HANDLE hProcess;

HANDLE hToken, hNewToken;

DWORD dwPid;

PACL pOldDAcl = NULL;

PACL pNewDAcl = NULL;

BOOL bDAcl;

BOOL bDefDAcl;

DWORD dwRet;

PACL pSacl = NULL;

PSID pSidOwner = NULL;

PSID pSidPrimary = NULL;

DWORD dwAclSize = 0;

DWORD dwSaclSize = 0;

DWORD dwSidOwnLen = 0;

DWORD dwSidPrimLen = 0;

DWORD dwSDLen;

EXPLICIT_ACCESS ea;

PSECURITY_DESCRIPTOR pOrigSd = NULL;

PSECURITY_DESCRIPTOR pNewSd = NULL;

STARTUPINFO si;

PROCESS_INFORMATION pi;

CHAR szFullCmdLine[512] = {0};

BOOL bError;

AdjustPrivilege();

dwPid = GetProcessID("winlogon.exe");

if(dwPid == 0)

{

bError = TRUE;

goto Cleanup;

}

hProcess = OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, dwPid );

if ( hProcess == NULL )

{

printf( "OpenProcess() = %d\n", GetLastError() );

bError = TRUE;

goto Cleanup;

}

if ( !OpenProcessToken( hProcess, READ_CONTROL | WRITE_DAC, &hToken ) )

{

printf( "OpenProcessToken() = %d\n", GetLastError() );

bError = TRUE;

goto Cleanup;

}

// 设置 ACE 具有所有访问权限

ZeroMemory( &ea, sizeof( EXPLICIT_ACCESS ) );

BuildExplicitAccessWithName(

&ea,

"Everyone",

TOKEN_ALL_ACCESS,

GRANT_ACCESS,

0 );

if ( !GetKernelObjectSecurity(

hToken,

DACL_SECURITY_INFORMATION,

pOrigSd,

0,

&dwSDLen ))

{

// 第一次调用给出的参数肯定返回这个错误,这样做的目的是

// 为了得到原安全描述符 pOrigSd 的长度

if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER )

{

pOrigSd = ( PSECURITY_DESCRIPTOR ) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwSDLen );

if ( pOrigSd == NULL )

{

printf( "Allocate pSd memory to failed!\n" );

bError = TRUE;

goto Cleanup;

}

// 再次调用才正确得到安全描述符 pOrigSd

if ( !GetKernelObjectSecurity(

hToken,

DACL_SECURITY_INFORMATION,

pOrigSd,

dwSDLen,

&dwSDLen ) )

{

printf( "GetKernelObjectSecurity() = %d\n", GetLastError() );

bError = TRUE;

goto Cleanup;

}

}

else

{

printf( "GetKernelObjectSecurity() = %d\n", GetLastError() );

bError = TRUE;

goto Cleanup;

}

}

// 得到原安全描述符的访问控制列表 ACL

if ( !GetSecurityDescriptorDacl( pOrigSd, &bDAcl, &pOldDAcl, &bDefDAcl ) )

{

printf( "GetSecurityDescriptorDacl() = %d\n", GetLastError() );

bError = TRUE;

goto Cleanup;

}

// 生成新 ACE 权限的访问控制列表 ACL

dwRet = SetEntriesInAcl( 1, &ea, pOldDAcl, &pNewDAcl );

if ( dwRet != ERROR_SUCCESS )

{

printf( "SetEntriesInAcl() = %d\n", GetLastError() );

pNewDAcl = NULL;

bError = TRUE;

goto Cleanup;

}

if ( !MakeAbsoluteSD( pOrigSd,

pNewSd,

&dwSDLen,

pOldDAcl,

&dwAclSize,

pSacl,

&dwSaclSize,

pSidOwner,

&dwSidOwnLen,

pSidPrimary,

&dwSidPrimLen ) )

{

// 第一次调用给出的参数肯定返回这个错误,这样做的目的是

// 为了创建新的安全描述符 pNewSd 而得到各项的长度

if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER )

{

pOldDAcl = ( PACL ) HeapAlloc( GetProcessHeap(),

HEAP_ZERO_MEMORY,

dwAclSize );

pSacl = ( PACL ) HeapAlloc( GetProcessHeap(),

HEAP_ZERO_MEMORY,

dwSaclSize );

pSidOwner = ( PSID ) HeapAlloc( GetProcessHeap(),

HEAP_ZERO_MEMORY,

dwSidOwnLen );

pSidPrimary = ( PSID ) HeapAlloc( GetProcessHeap(),

HEAP_ZERO_MEMORY,

dwSidPrimLen );

pNewSd = ( PSECURITY_DESCRIPTOR ) HeapAlloc( GetProcessHeap(),

HEAP_ZERO_MEMORY,

dwSDLen );

if ( pOldDAcl == NULL ||

pSacl == NULL ||

pSidOwner == NULL ||

pSidPrimary == NULL ||

pNewSd == NULL )

{

printf( "Allocate SID or ACL to failed!\n" );

bError = TRUE;

goto Cleanup;

}

// 再次调用才可以成功创建新的安全描述符 pNewSd

// 但新的安全描述符仍然是原访问控制列表 ACL

if ( !MakeAbsoluteSD( pOrigSd,

pNewSd,

&dwSDLen,

pOldDAcl,

&dwAclSize,

pSacl,

&dwSaclSize,

pSidOwner,

&dwSidOwnLen,

pSidPrimary,

&dwSidPrimLen ) )

{

printf( "MakeAbsoluteSD() = %d\n", GetLastError() );

bError = TRUE;

goto Cleanup;

}

}

else

{

printf( "MakeAbsoluteSD() = %d\n", GetLastError() );

bError = TRUE;

goto Cleanup;

}

}

// 将具有所有访问权限的访问控制列表 pNewDAcl 加入到新的

// 安全描述符 pNewSd 中

if ( !SetSecurityDescriptorDacl( pNewSd, bDAcl, pNewDAcl, bDefDAcl ) )

{

printf( "SetSecurityDescriptorDacl() = %d\n", GetLastError() );

bError = TRUE;

goto Cleanup;

}

// 将新的安全描述符加到 TOKEN 中

if ( !SetKernelObjectSecurity( hToken, DACL_SECURITY_INFORMATION, pNewSd ) )

{

printf( "SetKernelObjectSecurity() = %d\n", GetLastError() );

bError = TRUE;

goto Cleanup;

}

// 再次打开 WINLOGON 进程的 TOKEN,这时已经具有所有访问权限

if ( !OpenProcessToken( hProcess, TOKEN_ALL_ACCESS, &hToken ) )

{

printf( "OpenProcessToken() = %d\n", GetLastError() );

bError = TRUE;

goto Cleanup;

}

// 复制一份具有相同访问权限的 TOKEN

if ( !DuplicateTokenEx( hToken,

TOKEN_ALL_ACCESS,

NULL,

SecurityImpersonation,

TokenPrimary,

&hNewToken ) )

{

printf( "DuplicateTokenEx() = %d\n", GetLastError() );

bError = TRUE;

goto Cleanup;

}

ZeroMemory( &si, sizeof( STARTUPINFO ) );

si.cb = sizeof( STARTUPINFO );

// 不虚拟登陆用户的话,创建新进程会提示

// 1314 客户没有所需的特权错误

ImpersonateLoggedOnUser( hNewToken );

// 我们仅仅是需要建立高权限进程,不用切换用户

// 所以也无需设置相关桌面,有了新 TOKEN 足够

sprintf(szFullCmdLine, "\"%s\" %s", szProcessName, szCmdLine);

printf("%s\n", szFullCmdLine);

// 利用具有所有权限的 TOKEN,创建高权限进程

if ( !CreateProcessAsUser( hNewToken,

NULL,

szFullCmdLine,

NULL,

NULL,

FALSE,

NULL, //NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE,

NULL,

NULL,

&si,

&pi ) )

{

printf( "CreateProcessAsUser() = %d\n", GetLastError() );

bError = TRUE;

goto Cleanup;

}

bError = FALSE;

Cleanup:

if ( pOrigSd )

{

HeapFree( GetProcessHeap(), 0, pOrigSd );

}

if ( pNewSd )

{

HeapFree( GetProcessHeap(), 0, pNewSd );

}

if ( pSidPrimary )

{

HeapFree( GetProcessHeap(), 0, pSidPrimary );

}

if ( pSidOwner )

{

HeapFree( GetProcessHeap(), 0, pSidOwner );

}

if ( pSacl )

{

HeapFree( GetProcessHeap(), 0, pSacl );

}

if ( pOldDAcl )

{

HeapFree( GetProcessHeap(), 0, pOldDAcl );

}

CloseHandle( pi.hProcess );

CloseHandle( pi.hThread );

CloseHandle( hToken );

CloseHandle( hNewToken );

CloseHandle( hProcess );

if ( bError )

{

return FALSE;

}

return TRUE;

}

int _tmain(int argc, _TCHAR* argv[])

{

if(argc > 0)

{

char szCmdline[512] = {0};

for(int i=2; i<argc; i++)

{

strcat(szCmdline, " ");

strcat(szCmdline, argv[i]);

}

printf("%s\n", szCmdline);

CreateSystemProcess(argv[1], szCmdline);

}

//getchar();

return 0;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐