Skip to main content

The craziest command line I've run to date

Here is a lovely but slightly redacted image:

There's a lot going on here, so let me explain. First off, the Command Prompt is no ordinary Command Prompt. See the title bar of the window? 'cmd.exe' is running as NT AUTHORITY\SYSTEM, the most powerful user account in Windows, on my desktop as a child process of a non-elevated process via the assistance of a temporary NT System Service. A procedure that had never been done before May of 2021. I recommend reading this post (and watching the really cool video I made about it) if you haven't already done so. In short, we're already in completely uncharted territory on Windows.

Since the parent process is running as NT AUTHORITY\SYSTEM, it is one step away from being able to create security tokens for other users without the user's credentials (i.e. without the user's password, biometrics, etc). The above command creates an elevated token for a user in the Administrators group from scratch, routes stdout and stderr over TCP/IP sockets in separate threads, merges the parent environment with the environment for the user's profile, and starts running a PHP script as a child process using the created token and custom environment variables in the desired starting directory.

The best part of this is: It all works. The command does all of the above as described. However, the 1,421 character command spanning 12 lines to do all of the above and the technology hoops that had to be jumped through to make it possible in the first place is kinda crazy/bonkers. So while it is possible, it isn't pretty, is a tad more fragile than I'd like, and took months to get to this point. But it works.

Comments

  1. In the screen shot... What is the value 5573657233322000:0

    ReplyDelete
    Replies
    1. That is Source + LUID separated by a colon.

      For Source, createprocess.exe accepts a binary hex-encoded string containing the value. In the example shown above, it is "User32 \x00". It's supposedly used for tracking purposes in the kernel. Although since someone can plug in any value they like, it doesn't seem particularly useful. The LUID is similarly not very useful and can be any integer. 0 works fine. However, both are required to call NtCreateToken().

      Delete

Post a Comment