0

I'm using LogonUser to get a HANDLE to the target session token and use it for the function CreateProcessAsUser.

status = LogonUserW(sessiondata->UserName.Buffer, sessiondata->LogonDomain.Buffer,NULL,LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &targettoken);

My executable is going to be executed by Administrator, but even though I'm administrator, I can't get the handle to the token and always get 1326 error: Logon failure: unknown user name or bad password.. I put NULL as lpszPassword with the hope that it checks if I'm administrator and give me the privilege to get the access token.

Of course I should not be using LogonUser for this purpose, so what do you suggest ?

I expected to get a HANDLE to the access token because of my high-level privilege(Administrator) without giving the password.

zbx0310
  • 64
  • 8
  • your hope is wrong – RbMm Mar 27 '22 at 09:44
  • So its impossible ? – zbx0310 Mar 27 '22 at 09:57
  • no, but unclear what you try todo. `WTSQueryUserToken` if you need get existing session token – RbMm Mar 27 '22 at 09:59
  • But this function is used for Remote Desktop services. My executable is a simple application which is intended to get screenshots from all logon sessions – zbx0310 Mar 27 '22 at 10:01
  • you confuse logon and terminal sessions. logon sessions not have self desktop. this is only terminal session. and `WTSQueryUserToken` exactly what need here – RbMm Mar 27 '22 at 10:02
  • What do you mean this is only terminal session ? As I said the executable is not going to be a service. And I'm completely sure that I want to capture logon sessions – zbx0310 Mar 27 '22 at 10:19
  • you are wrong. logon sessions not have desktop – RbMm Mar 27 '22 at 10:21

1 Answers1

1

My executable is a simple application which is intended to get screenshots from all logon sessions

Hey, we can forget about getting the user's login token. There's actually a fairly good way to do this.

  1. Enumerate all processes.
  2. If the process is a WINLOGON process and the session id is not zero
  3. Steal its token
  4. Start a process using that token; pass it a file on the command line
  5. That process takes a screenshot and saves it to a file
  6. When all your processes have finished, pick up your files.

The token from WINLOGON has administrative rights and is on the correct session to see the user's desktop. If you don't create any windows you aren't vulnerable to the user messing with you. (In fact this token creates windows at a higher integrity level. Normal shatter attacks don't work however you can still receive fake keyboard or mouse input if you create windows.)

Most likely, you will only get a screenshot from the currently active screen and any active remote desktop sessions. Other sessions stop their redraw and drop their screen buffers to save memory.

It's most likely your user does not have SeAssignPrimaryTokenPrivilege and SeTcbPrivilege. I have given these to my user in the past; however the easiest way to get them is to become local system by setting up and launching as a service, then removing the service after its done.

OP commented that he got to SYSTEM by PsExec and was able to get the token. PsExec does CreateService under the hood so it's all the same.

Joshua
  • 40,822
  • 8
  • 72
  • 132
  • we can forget about tokenat all. for what we need concrete token ? for what winlogon token ? we really need exec process in concrete terminal session id. we can take any token - so duplicate self token and set session id in it (`TokenSessionId`). of course we need for this `SeTcbPrivilege` and for `CreateProcessAsUser` need `SeAssignPrimaryTokenPrivilege` - so first need impersonate self with token which have this – RbMm Mar 27 '22 at 14:57
  • @RbMm: I tried duplicate self token and set session id long ago. It doesn't work as the resulting token doesn't have the right permissions to access the target desktop. Desktops are secured by nonce SIDs and your duplicated token won't have the right nonce SID. Thus, I went for the winlogon token. – Joshua Mar 27 '22 at 15:10
  • yes, you correct - must be right permissions to access the target desktop. so possibly and use winlogon token. but anyway we need token with SeAssignPrimaryTokenPrivilege ( and SeTcbPrivilege if set TokenSessionId) - so we can duplicate and use this token i think – RbMm Mar 27 '22 at 15:17
  • The problem is I can't open WINLOGON process as administrator. Error code 5 – zbx0310 Mar 28 '22 at 11:33
  • @zbx0310: You have to give yourself extra privileges or become SYSTEM. Try becoming system using CreateService before giving up. – Joshua Mar 28 '22 at 13:54
  • 1
    Thank you guys. I eventually got the tokens by running the executable by PsExec.exe as SYSTEM user. – zbx0310 Mar 28 '22 at 17:43
  • Is this Exactly what you meant by checking if the process is WINLOGON ? `if (wcscmp((wchar_t *)ProcessImg, L"C:\\Windows\\System32\\winlogon.exe") == 0) { printf("PID %d is a winlogon.\n", pid); return prochandle` } – zbx0310 Mar 29 '22 at 19:09
  • @zbx0310: When I wrote my code I did it an even stupider way. I matched any WINLOGON.EXE running as SYSTEM's SID. However you do have a bug. Call `GetSystemDirectory()`. – Joshua Mar 29 '22 at 19:38