1、进程访问令牌。用这种方法创建系统进程在LocalSecurityAuthority.au3中有实现,具体代码请看其中的_CreateProcessAsSystem。
实现原理:
4)、CreateProcessAsUser (advapi32.dll) 中的hToken参数标识某个进程的用户令牌,如果是来自于SYSTEM用户,那么创建的进程自然是SYSTEM权限,如果来自于Guest,创建的进程会是Guest权限,创建的进程是什么权限,取决于hToken所属的进程的用户。
3)、CreateProcessAsUser 所要求的hToken必须要有TOKEN_QUERY、TOKEN_DUPLICATE、TOKEN_ASSIGN_PRIMARY 权限,而默认情况下系统级进程不开放这3个访问权限。
2)、以READ_CONTROL、WRITE_DAC访问权限打开hToken设置其权限(默认情况下,SYSTEM进程总是开启READ_CONTROL、WRITE_DAC),使其开放上述3个权限。
1)、重新以TOKEN_QUERY、TOKEN_DUPLICATE、TOKEN_ASSIGN_PRIMARY打开进程令牌,获取hToken参数,传递到CreateProcessAsUser,依此完成SYSTEM进程的创建。
2、注册为系统服务。当某个子进程被创建时,会自动继承其父进程的用户场景,在某个服务被启动时,实际是由services.exe启动的,而services.exe本就是SYSTEM进程,所以由它启动的进程也是SYSTEM。对于带GUI界面的服务,可以设置服务属性中的“允许与桌面进行交互”把GUI界面显示出来。
相关文章:用纯AU3编写服务程序
3、嵌入远程线程。将创建进程的代码写入到远程SYSTEM进程winlogon.exe中,CreateRemoteThread运行远程代码,相当于winlogon.exe创建进程,新进程自然是SYSTEM权限。测试发现用这种方法不能很好地运行带GUI界面的程序,可以设置其中某个参数将GUI显示出来,但我不会~
4、修改新进程的父进程。这是昨晚意外发现的一种新方法,初衷是想修改某个进程的父进程,结果发现修改父进程之后,新创建的进程会继承这个父进程的权限。
实现思路:
1)、在创建一个进程时(例如用CreateProcess (kernel32.dll)、CreateProcessAsUser (advapi32.dll)、AutoIt内置函数Run、ShellExecute), 最终会调用到的API函数是ntdll.dll中的NtCreateProcessEx,可以Google一下其原型。其中的InheritFromProcessHandle就是指定父进程的句柄,虽然CreateProcess总是用GetCurrentProcess当做此参数。新进程的权限继承于InheritFromProcessHandle,而不是调用NtCreateProcessEx的创建者。
2)、首先获取$SystemProcess进程的句柄,这个句柄将被当做InheritFromProcessHandle参数。$SystemProcess表示一个变量,具体代表某个系统级进程。
3)、挂钩NtCreateProcessEx。调用CreateProcess或Run、ShellExecute,将截取到此函数调用并执行自己的钩子代码,钩子代码要做的是丢弃原本的InheritFromProcessHandle参数,将$SystemProcess进程的句柄当做新的InheritFromProcessHandle,并恢复原来的未被挂钩状态时的NtCreateProcessEx。恢复之后继续执行NtCreateProcessEx,完成进程的创建。
也可以不必挂钩NtCreateProcessEx,直接调用一系列的创建进程的系统函数,但这样做代码量过于浩大,我们要做的是自己完全模拟一个Kernel32.dll中的CreateProcess函数,关于创建进程的流程,Google可以搜索到。
以下是第4种方法修改父进程的实现代码,创建regedit.exe进程,并设置其父进程为lsass.exe。需要用到两个外部函数库。
Thread.au3 – 纯AU3拦截进程创建,并阻止或允许其运行
LocalSecurityAuthority.au3 – Au3 本地安全管理|审核UDF LocalSecurityAuthority
#include <Thread.au3> #include <LocalSecurityAuthority.au3> Local $aPriv[1][2] = [[$SE_DEBUG_NAME, 2]] $hToken = _OpenProcessToken(-1) _AdjustTokenPrivileges($hToken, $aPriv) _LsaCloseHandle($hToken) $pNtCreateProcess = _RTGetProcAddress("Ntdll.dll", "NtCreateProcessEx") $pOpenProcess = _RTGetProcAddress("Kernel32.dll", "OpenProcess") $pCloseHandle = _RTGetProcAddress("Kernel32.dll", "CloseHandle") $pMessageBoxW = _RTGetProcAddress("User32.dll", "MessageBoxW") $iPid = -1; WinGetProcess("abc") $hProcess = _RTOpenProcess($iPid) _RTVirtualProtectEx($hProcess, $pNtCreateProcess, 8) $bEntrypoint = _RTReadProcessMemory($hProcess, $pNtCreateProcess, 0, 8, "binary") $bEntrypoint = StringTrimLeft($bEntrypoint, 2) $pCallAddr = _RTVirtualAllocEx($hProcess, 1024) $bJump = "B8" & _RTLongPtrToBytes($pCallAddr) & "FFE000" _RTWriteProcessMemory($hProcess, $pNtCreateProcess, "0x" & $bJump, 8, "binary") #CS NTSYSAPI NTSTATUS NTAPI NtCreateProcessEx( OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE InheritFromProcessHandle, IN ULONG CreateFlags, IN HANDLE SectionHandle OPTIONAL, IN HANDLE DebugObject OPTIONAL, IN HANDLE ExceptionPort OPTIONAL, IN ULONG JobMemberLevel ); #CE $iParentPid = ProcessExists("lsass.exe") $bCode = "0x" & _ "55" & _ "8BEC" & _ "68" & _RTUlongToBytes($iParentPid) & _ "6A00" & _ "6A80" & _ "B8" & _RTLongPtrToBytes($pOpenProcess) & _ "FFD0" & _ "A3" & _RTLongPtrToBytes($pCallAddr + 512) & _ "FF7528" & _ "FF7524" & _ "FF7520" & _ "FF751C" & _ "FF7518" & _ "50" & _ "FF7510" & _ "FF750C" & _ "FF7508" & _ "C705" & _RTLongPtrToBytes($pNtCreateProcess + 0) & StringMid($bEntrypoint, 1, 8) & _ "C705" & _RTLongPtrToBytes($pNtCreateProcess + 4) & StringMid($bEntrypoint, 9, 8) & _ "B8" & _RTLongPtrToBytes($pNtCreateProcess) & _ "FFD0" & _ "50" & _ "FF35" & _RTLongPtrToBytes($pCallAddr + 512) & _ "B8" & _RTLongPtrToBytes($pCloseHandle) & _ "FFD0" & _ "58" & _ "5D" & _ "C22400" _RTWriteProcessMemory($hProcess, $pCallAddr, $bCode, BinaryLen($bCode), "binary") _RTCloseHandle($hProcess) Run("regedit.exe")