Beyond good ol’ Run key, Part 38

It’s been a while since my last post about persistence tricks. Today I decided to fix this and write about yet another trick – kinda old, yet still cool – that works even today despite being as old as Windows NT.

The userinit.exe process was featured in a number of persistence posts before (here , here and here). Turns out, we have not given it all the attention it needs yet.

When you add a new user to the system, you have an option to change some properties of the user account as shown on the below screenshot. One of these properties is responsible for loading the user logon script (I named it foobar123.bat on the test system).

pic0

The alternative to GUI is using the following command:

  • net user /scriptpath:<Relative Path>

Once added to the user properties, the script will be executed anytime user logs on:

pic3

You may be wondering where on the system it has to be placed to ensure it is executed.

There are two places:

  • You can place it on Netlogon share:
    • either the real one from the domain controller (where all user scripts reside),
      or
    • you can create a fake, local one by using the trick shown below:

pic1

In such case the script will be loaded like this:

pic4

  • You can place it inside the %systemroot%\System32\Repl\Import\Scripts directory

In such case it will be executed like this:

pic2If you use net user command, the relative path is relative to %systemroot%\System32\Repl\Import\Scripts.

This trick is not my idea and is described in various places on the internet – I shamelessly ‘borrowed’ most of the bits and ideas from here.

Beyond good ol’ Run key, Part 37

The technique I will describe today is extremely old and well-known yet I don’t recall writing about it in detail and would probably forget about it completely if not for Nick who pinged me about it a whiiiiiiiile ago 🙂 Thanks Nick!

The path interception is a vulnerability type which is abused by both malware and pentesters. The most common example of this vulnerability on Windows platform relies on dropping “c:\program.exe” and waiting for a service or other application to be launched from a path that was not quoted. When quotes are not used the given path is traversed and anytime a blank character is encountered the OS will attempt to execute any program that happens to be matching the substring being part of the traversed path.  Sounds complicated.

In other words.

  • “C:\program Files\foo bar\file.exe”

is not equal to

  • C:\program Files\foo bar\file.exe

In a first case, the path is given in a precise way with no room for error. OS will attempt to launch only one program.

In a second, the OS will attempt to launch:

  • C:\program.exe

first, then:

  • C:\program Files\foo.exe

and eventually:

  • C:\program Files\foo bar\file.exe

Nowadays users can’t freely write to these paths, so to leverage it one needs to explore all the existing autostart locations on the system and find a combo of both an unquoted path + a writable directory that enable the exploit to work.

It’s a simple, yet powerful way not only to gain persistence, but in some cases to elevate privileges as well.

A DLL variant of this vulnerability can rely on adding a new startup entry (or leveraging an existing one) that would point to clean components only (f.ex. a clean rundll32.exe loading an existing, clean system DLL).

Let’s look at an example – we could add something like this to HKCU\…\Run:

  • rundll32.exe c:\Program Files\Internet Explorer\ieproxy.dll

and then drop:

  • c:\Program.dll

or

  • c:\Program Files\Internet.dll

which rundll32.exe would then hopefully load for us.

There is a little caveat though, the rundll32.exe checks if the second token (obtained by splitting the command line arguments using blank characters as a delimiter – and in our case ‘Files\Internet.dll’) contains a path separator character (‘\’, or ‘/’). If it does, rundll32 assumes it is an incorrect command line and exits. So, the above example doesn’t work.

To bypass it, one could use a root path with more than one space. The old folder name ‘C:\Document and Settings’ works perfectly here, but it is a legacy path that may not be the best choice for new systems. For these systems (and since most of new computers are now 64-bit) we can use ‘c:\Program Files (x86)’ (first token: ‘c:\Program’, second token: ‘Files’).

If you see a string like the below in the Registry under HKCU\…\RUN:

  • “C:\Windows\System32\rundll32.exe” c:\Program Files\Internet Explorer\ieproxy.dll

it may not raise the immediate suspicion. The real-case scenario could go even further and use even more ambiguous path f.ex. one belonging to a graphic card, or a sound card.

Running the aforementioned entry from a command line will get you the following message:

rundll_program

This is because rundll32.exe attempts to load C:\program.dll.

rundll_program2

As such, dropping c:\<DLL name exploiting path truncation>.dll will give you a lame persistence (lame, because you still need to either find an existing, or add a clean entry to a startup location + need to write to C:\ drive – this could have worked 10 years ago, but not today 🙂 ).