[轉載]創建高權限進程
文章作者:sinister
信息來源:白細胞
Author: sinister
Email:
Homepage:
Date: 2006-02-12
/*****************************************************************
文件名 : wssrun.c
描述 : 創建高權限進程
作者 : sinister
最後修改日期 : 2006.2.09
*****************************************************************/
//
// 寫這個初衷是為了讓 Windows 任務管理器可以結束掉一些服務
// 和僵死進程,用 pslist/pskill 之類工具無法獲得象任務管理
// 器那樣豐富的信息,還得來回切換,麻煩的很。最初想寫個驅動
// 監視任務管理器運行,使用 SYSTEM 進程 TOKEN 替換來達到目的。
// 後來覺得通用性不好,就改用了這種方法。此方法還可使 regedit
// 查看、編輯 SAM 等注冊表鍵,何樂而不為。
//
// wssrun taskmgr.exe
// wssrun regedit.exe
//
#include
#include
#include
#include
#include
#include
#include
#pragma comment(lib,"Shlwapi.lib")
/////////////////////////////////////////////////////////////////
// 函數類型 :自定義工具函數
// 函數模塊 :
////////////////////////////////////////////////////////////////
// 功能 :提升當前進程權限
// 注意 :
/////////////////////////////////////////////////////////////////
// 作者 : sinister
// 發布版本 : 1.00.00
// 發布日期 : 2006.2.09
/////////////////////////////////////////////////////////////////
// 重 大 修 改 曆 史
////////////////////////////////////////////////////////////////
// 修改者 :
// 修改日期 :
// 修改內容 :
/////////////////////////////////////////////////////////////////
BOOL
EnableDebugPriv( LPCTSTR szPrivilege )
{
HANDLE hToken;
LUID sedebugnameValue;
TOKEN_PRIVILEGES tkp;
if ( !OpenProcessToken( GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hToken ) )
{
return FALSE;
}
if ( !LookupPrivilegeValue( NULL, szPrivilege, &sedebugnameValue ) )
{
CloseHandle( hToken );
return FALSE;
}
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = sedebugnameValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if ( !AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof tkp, NULL, NULL ) )
{
CloseHandle( hToken );
return FALSE;
}
return TRUE;
}
/////////////////////////////////////////////////////////////////
// 函數類型 :自定義工具函數
// 函數模塊 :
////////////////////////////////////////////////////////////////
// 功能 :通過指定進程名得到其進程 ID
// 注意 :
/////////////////////////////////////////////////////////////////
// 作者 : sinister
// 發布版本 : 1.00.00
// 發布日期 : 2006.2.09
/////////////////////////////////////////////////////////////////
// 重 大 修 改 曆 史
////////////////////////////////////////////////////////////////
// 修改者 :
// 修改日期 :
// 修改內容 :
/////////////////////////////////////////////////////////////////
DWORD
GetProcessId( LPCTSTR szProcName )
{
PROCESSENTRY32 pe;
DWORD dwPid;
DWORD dwRet;
BOOL bFound = FALSE;
//
// 通過 TOOHLP32 函數枚舉進程
//
HANDLE hSP = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
if ( hSP )
{
pe.dwSize = sizeof( pe );
for ( dwRet = Process32First( hSP, &pe );
dwRet;
dwRet = Process32Next( hSP, &pe ) )
{
//
// 使用 StrCmpNI 比較字符傳,可忽略大小寫
//
if ( StrCmpNI( szProcName, pe.szExeFile, strlen( szProcName ) ) == 0 )
{
dwPid = pe.th32ProcessID;
bFound = TRUE;
break;
}
}
CloseHandle( hSP );
if ( bFound == TRUE )
{
return dwPid;
}
}
return NULL;
}
/////////////////////////////////////////////////////////////////
// 函數類型 :自定義工具函數
// 函數模塊 :
////////////////////////////////////////////////////////////////
// 功能 : 創建具有高權限的進程
// 注意 :
/////////////////////////////////////////////////////////////////
// 作者 : sinister
// 發布版本 : 1.00.00
// 發布日期 : 2006.2.09
/////////////////////////////////////////////////////////////////
// 重 大 修 改 曆 史
////////////////////////////////////////////////////////////////
// 修改者 :
// 修改日期 :
// 修改內容 :
/////////////////////////////////////////////////////////////////
BOOL
CreateSystemProcess( LPTSTR szProcessName )
{
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;
BOOL bError;
if ( !EnableDebugPriv( "SeDebugPrivilege" ) )
{
printf( "EnableDebugPriv() to failed!/n" );
bError = TRUE;
goto Cleanup;
}
//
// 選擇 WINLOGON 進程
//
if ( ( dwPid = GetProcessId( "WINLOGON.EXE" ) ) == NULL )
{
printf( "GetProcessId() to failed!/n" );
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 足夠
//
//
// 利用具有所有權限的 TOKEN,創建高權限進程
//
if ( !CreateProcessAsUser( hNewToken,
NULL,
szProcessName,
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;
}
void
main( int argc, char** argv )
{
if ( argc < 2 )
{
printf( "Usage: wssrun /n" );
return ;
}
if ( CreateSystemProcess( argv[1] ) == FALSE )
{
printf( "wssrun: CreateSystemProcess() to failed!/n" );
return ;
}
}
WSS(Whitecell Security Systems),一個非營利性民間技術組織,致力於各種係統安全技術的研究。堅持傳統的hacker精神,追求技術的精純。
WSS 主頁:
WSS 論壇:
信息來源:白細胞
Author: sinister
Email:
Homepage:
Date: 2006-02-12
/*****************************************************************
文件名 : wssrun.c
描述 : 創建高權限進程
作者 : sinister
最後修改日期 : 2006.2.09
*****************************************************************/
//
// 寫這個初衷是為了讓 Windows 任務管理器可以結束掉一些服務
// 和僵死進程,用 pslist/pskill 之類工具無法獲得象任務管理
// 器那樣豐富的信息,還得來回切換,麻煩的很。最初想寫個驅動
// 監視任務管理器運行,使用 SYSTEM 進程 TOKEN 替換來達到目的。
// 後來覺得通用性不好,就改用了這種方法。此方法還可使 regedit
// 查看、編輯 SAM 等注冊表鍵,何樂而不為。
//
// wssrun taskmgr.exe
// wssrun regedit.exe
//
#include
#include
#include
#include
#include
#include
#include
#pragma comment(lib,"Shlwapi.lib")
/////////////////////////////////////////////////////////////////
// 函數類型 :自定義工具函數
// 函數模塊 :
////////////////////////////////////////////////////////////////
// 功能 :提升當前進程權限
// 注意 :
/////////////////////////////////////////////////////////////////
// 作者 : sinister
// 發布版本 : 1.00.00
// 發布日期 : 2006.2.09
/////////////////////////////////////////////////////////////////
// 重 大 修 改 曆 史
////////////////////////////////////////////////////////////////
// 修改者 :
// 修改日期 :
// 修改內容 :
/////////////////////////////////////////////////////////////////
BOOL
EnableDebugPriv( LPCTSTR szPrivilege )
{
HANDLE hToken;
LUID sedebugnameValue;
TOKEN_PRIVILEGES tkp;
if ( !OpenProcessToken( GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hToken ) )
{
return FALSE;
}
if ( !LookupPrivilegeValue( NULL, szPrivilege, &sedebugnameValue ) )
{
CloseHandle( hToken );
return FALSE;
}
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = sedebugnameValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if ( !AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof tkp, NULL, NULL ) )
{
CloseHandle( hToken );
return FALSE;
}
return TRUE;
}
/////////////////////////////////////////////////////////////////
// 函數類型 :自定義工具函數
// 函數模塊 :
////////////////////////////////////////////////////////////////
// 功能 :通過指定進程名得到其進程 ID
// 注意 :
/////////////////////////////////////////////////////////////////
// 作者 : sinister
// 發布版本 : 1.00.00
// 發布日期 : 2006.2.09
/////////////////////////////////////////////////////////////////
// 重 大 修 改 曆 史
////////////////////////////////////////////////////////////////
// 修改者 :
// 修改日期 :
// 修改內容 :
/////////////////////////////////////////////////////////////////
DWORD
GetProcessId( LPCTSTR szProcName )
{
PROCESSENTRY32 pe;
DWORD dwPid;
DWORD dwRet;
BOOL bFound = FALSE;
//
// 通過 TOOHLP32 函數枚舉進程
//
HANDLE hSP = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
if ( hSP )
{
pe.dwSize = sizeof( pe );
for ( dwRet = Process32First( hSP, &pe );
dwRet;
dwRet = Process32Next( hSP, &pe ) )
{
//
// 使用 StrCmpNI 比較字符傳,可忽略大小寫
//
if ( StrCmpNI( szProcName, pe.szExeFile, strlen( szProcName ) ) == 0 )
{
dwPid = pe.th32ProcessID;
bFound = TRUE;
break;
}
}
CloseHandle( hSP );
if ( bFound == TRUE )
{
return dwPid;
}
}
return NULL;
}
/////////////////////////////////////////////////////////////////
// 函數類型 :自定義工具函數
// 函數模塊 :
////////////////////////////////////////////////////////////////
// 功能 : 創建具有高權限的進程
// 注意 :
/////////////////////////////////////////////////////////////////
// 作者 : sinister
// 發布版本 : 1.00.00
// 發布日期 : 2006.2.09
/////////////////////////////////////////////////////////////////
// 重 大 修 改 曆 史
////////////////////////////////////////////////////////////////
// 修改者 :
// 修改日期 :
// 修改內容 :
/////////////////////////////////////////////////////////////////
BOOL
CreateSystemProcess( LPTSTR szProcessName )
{
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;
BOOL bError;
if ( !EnableDebugPriv( "SeDebugPrivilege" ) )
{
printf( "EnableDebugPriv() to failed!/n" );
bError = TRUE;
goto Cleanup;
}
//
// 選擇 WINLOGON 進程
//
if ( ( dwPid = GetProcessId( "WINLOGON.EXE" ) ) == NULL )
{
printf( "GetProcessId() to failed!/n" );
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 足夠
//
//
// 利用具有所有權限的 TOKEN,創建高權限進程
//
if ( !CreateProcessAsUser( hNewToken,
NULL,
szProcessName,
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;
}
void
main( int argc, char** argv )
{
if ( argc < 2 )
{
printf( "Usage: wssrun /n" );
return ;
}
if ( CreateSystemProcess( argv[1] ) == FALSE )
{
printf( "wssrun: CreateSystemProcess() to failed!/n" );
return ;
}
}
WSS(Whitecell Security Systems),一個非營利性民間技術組織,致力於各種係統安全技術的研究。堅持傳統的hacker精神,追求技術的精純。
WSS 主頁:
WSS 論壇:
最後更新:2017-04-02 00:06:17