<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>cryptography on Stephen Swanson</title>
    
    
    
    <link>https://stephenswanson.xyz/tags/cryptography/</link>
    <description>Recent content in cryptography on Stephen Swanson</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <managingEditor>stephen@stephenswanson.xyz (Stephen Swanson)</managingEditor>
    <webMaster>stephen@stephenswanson.xyz (Stephen Swanson)</webMaster>
    <copyright>Stephen Swanson - CC BY 3.0 US.</copyright>
    <lastBuildDate>Sat, 01 Jan 2022 14:09:30 -0700</lastBuildDate>
    
	<atom:link href="https://stephenswanson.xyz/tags/cryptography/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>Cracking RSA: The Hard Way</title>
      <link>https://stephenswanson.xyz/articles/cracking-rsa-the-hard-way/</link>
      <pubDate>Sat, 01 Jan 2022 14:09:30 -0700</pubDate>
      <author>stephen@stephenswanson.xyz (Stephen Swanson)</author>
      <guid>https://stephenswanson.xyz/articles/cracking-rsa-the-hard-way/</guid>
      <description>
        
          &lt;img src=&#34;https://stephenswanson.xyz/articles/cracking-rsa-the-hard-way/key.webp&#34;/&gt;
          
        
        
        &lt;style&gt;
math {
    text-align: center;
}
&lt;/style&gt;
&lt;p&gt;Ever since I finished my OSCP in November of 2021, I haven&amp;rsquo;t done much in the field of cybersecurity. Since I&amp;rsquo;m awfully rusty, I decided to start from the very basics and play around with the HTB beginner track. One of the more interesting challenges I finished has been the Weak RSA challenge, which involved generating a private key from a public key with a known factorization. RSA is incredibly common, in fact, the connection to this very website has been secured by RSA (check the certificate details), but I never really explored the underlying math.&lt;/p&gt;
&lt;h2 id=&#34;the-challenge&#34;&gt;The Challenge&lt;/h2&gt;
&lt;p&gt;The challenge consists of a zip archive containing two files, &lt;code&gt;key.pub&lt;/code&gt; and &lt;code&gt;flag.enc&lt;/code&gt;. &lt;code&gt;flag.enc&lt;/code&gt; is the flag encrypted using RSA, and key.pub is a RSA public key in PEM format.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;# key.pub
-----BEGIN PUBLIC KEY-----
MIIBHzANBgkqhkiG9w0BAQEFAAOCAQwAMIIBBwKBgQMwO3kPsUnaNAbUlaubn7ip
4pNEXjvUOxjvLwUhtybr6Ng4undLtSQPCPf7ygoUKh1KYeqXMpTmhKjRos3xioTy
23CZuOl3WIsLiRKSVYyqBc9d8rxjNMXuUIOiNO38ealcR4p44zfHI66INPuKmTG3
RQP/6p5hv1PYcWmErEeDewKBgGEXxgRIsTlFGrW2C2JXoSvakMCWD60eAH0W2PpD
qlqqOFD8JA5UFK0roQkOjhLWSVu8c6DLpWJQQlXHPqP702qIg/gx2o0bm4EzrCEJ
4gYo6Ax+U7q6TOWhQpiBHnC0ojE8kUoqMhfALpUaruTJ6zmj8IA1e1M6bMqVF8sr
lb/N
-----END PUBLIC KEY-----
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;tldr&#34;&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;After finishing the challenge, I found several people who posted writeups. (See &lt;a href=&#34;https://simeononsecurity.ch/writeups/hackthebox-challenges-crypto-weak_rsa/&#34;&gt;here&lt;/a&gt; and &lt;a href=&#34;https://technicalciso.com/htb-weak-rsa/&#34;&gt;here&lt;/a&gt;), but most of them focused on using a tool to automate the attack. Instead, I wanted to do it by hand. For completeness sake though, after extracting the files, this command will solve the challenge:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;$ podman run -it --rm -v $PWD:/data docker.io/razaborg/rsactftool --uncipher /data/flag.enc --publickey /data/key.pub  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&#34;notices note&#34; &gt;&lt;p&gt;I&amp;rsquo;m using podman here, since it&amp;rsquo;s more secure by design than docker, but you can simply swap podman with docker and the command should work as is, since they&amp;rsquo;re drop-in replacements of each other.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;After running the command, the program spits out the flag:
&lt;img src=&#34;d253e27545384568853cd36d1ad2211e.png&#34; alt=&#34;5d8abcbebf5aa3b3ab8e85445b8a3463.png&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;rsa-the-nitty-gritty&#34;&gt;RSA: The Nitty Gritty&lt;/h2&gt;
&lt;p&gt;I wanted to know how the tool got the answer though, so I started digging into how RSA works under the hood.&lt;/p&gt;
&lt;p&gt;RSA is an asymmetric encryption algorithm, meaning that there are two keys used, one for encryption, and one for decryption. The security of RSA depends on the idea that it&amp;rsquo;s hard to factor the product of two prime numbers, but it&amp;rsquo;s easy to multiply those numbers.&lt;/p&gt;
&lt;p&gt;A public RSA key has two parts, a modulus and a public exponent. typically noted as &lt;em&gt;n&lt;/em&gt; and &lt;em&gt;e&lt;/em&gt;, respectively. A private key only needs to contain a private exponent, &lt;em&gt;d&lt;/em&gt;. This formula, where &lt;em&gt;m&lt;/em&gt; is the plaintext message and &lt;em&gt;c&lt;/em&gt; is the encrypted message, is used for encryption:&lt;/p&gt;
&lt;p&gt;$$ c = m^e\text{ mod } n $$&lt;/p&gt;
&lt;p&gt;while:&lt;/p&gt;
&lt;p&gt;$$ m = c^d \text{ mod } n $$&lt;/p&gt;
&lt;p&gt;is used for decryption.&lt;/p&gt;
&lt;p&gt;As an example &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; imagine we wanted to encrypt the message &amp;ldquo;The attack will come at dawn&amp;rdquo; First, we would pick two random prime numbers that are roughly the same size, for example, &lt;em&gt;p&lt;/em&gt; = 79 and &lt;em&gt;q&lt;/em&gt; = 97.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;n&lt;/em&gt;, our modulus, is&lt;/p&gt;
&lt;p&gt;$$n = np = 79\cdot97 = 7663$$&lt;/p&gt;
&lt;p&gt;Next, we pick a random public exponent. Typically, this number is prime, since we must ensure that the exponent is not a factor of&lt;/p&gt;
&lt;p&gt;$$(p -1)(q-1) = 7488$$&lt;/p&gt;
&lt;p&gt;and picking a prime number simplifies that calculation. For this example, we pick &lt;em&gt;e&lt;/em&gt; = 23.&lt;/p&gt;
&lt;p&gt;Lastly, we find &lt;em&gt;d&lt;/em&gt; using this equation:&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;https://stephenswanson.xyz/katex/katex.min.css&#34; /&gt;
&lt;script src=&#34;https://stephenswanson.xyz/katex/katex.min.js&#34;&gt;&lt;/script&gt;
&lt;script defer src=&#34;https://stephenswanson.xyz/katex/auto-render.min.js&#34; onload=&#34;renderMathInElement(document.body);&#34;&gt;&lt;/script&gt;&lt;span&gt;
  &lt;div class=&#34;katex-display&#34;&gt;
    &lt;div class=&#34;katexoverwrite&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;script&gt;
  var divs = Array.from(document.getElementsByClassName(&#34;katexoverwrite&#34;))
  katex.render(&#34;\n\\begin{aligned}\nd \u0026= e^{-1}\\text{ mod } (p -1)(q-1) \\\\\nd \u0026= 23^{-1} mod (79 -1)(97-1) \\\\\nd \u0026= 2279\n\\end{aligned}\n&#34;, divs.pop(), {
    throwOnError: false
});
&lt;/script&gt;
&lt;/span&gt;
&lt;p&gt;Now, we have our public key: 23,7663, and our private key: 2279, 7663. We share the public key with the person sending the message. They then convert the message into a number using a tool like &lt;a href=&#34;https://gchq.github.io/CyberChef/#recipe=To_Decimal%28%27Space%27,false%29&amp;amp;input=VGhlIGF0dGFjayB3aWxsIGNvbWUgYXQgZGF3bg&#34; title=&#34;https://gchq.github.io/CyberChef/#recipe=To_Decimal(&#39;Space&#39;,false)&amp;amp;input=VGhlIGF0dGFjayB3aWxsIGNvbWUgYXQgZGF3bg&#34;&gt;CyberChef&lt;/a&gt;&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;p&gt;$$\text{The attack will come at dawn} = 84 104&amp;hellip;97 119 110$$&lt;/p&gt;
&lt;p&gt;Since the message must be shorter than the modulus, we break it into 33 three digit chunks:
&lt;span&gt;
  &lt;div class=&#34;katex-display&#34;&gt;
    &lt;div class=&#34;katexoverwrite&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;script&gt;
  var divs = Array.from(document.getElementsByClassName(&#34;katexoverwrite&#34;))
  katex.render(&#34;\n\\begin{aligned}\nm_1 \u0026= 841 \\\\\nm_2 \u0026= 041 \\\\\n\u0026...\\\\\nm_{33} \u0026= 110 \\\\\n\\end{aligned}\n&#34;, divs.pop(), {
    throwOnError: false
});
&lt;/script&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Now, we raise each chunk to the power of &lt;em&gt;e&lt;/em&gt; modulus &lt;em&gt;n&lt;/em&gt;&lt;/p&gt;
&lt;span&gt;
  &lt;div class=&#34;katex-display&#34;&gt;
    &lt;div class=&#34;katexoverwrite&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;script&gt;
  var divs = Array.from(document.getElementsByClassName(&#34;katexoverwrite&#34;))
  katex.render(&#34;\n\\begin{aligned}\nc_1 \u0026= 841^ {23} \\text{ mod } 7663 = 579 \\\\\nc_2 \u0026= 041^ {23} \\text{ mod } 7663 = 4278\\\\\n\u0026...\\\\\nc_{33} \u0026= 110^ {23} \\text{ mod } 7663 = 2367\\\\\n\\end{aligned}\n&#34;, divs.pop(), {
    throwOnError: false
});
&lt;/script&gt;
&lt;/span&gt;


&lt;div class=&#34;notices note&#34; &gt;&lt;p&gt;Python handles this math really easily using the &lt;code&gt;pow()&lt;/code&gt; function. To perform the encryption, you can simply do &lt;code&gt;c1 = pow(841, 23, 7663)&lt;/code&gt;, where 841 is the number, 23 is the exponent, and 7663 is the modulus. For small numbers using the modulus operator &lt;code&gt;%&lt;/code&gt; would work, but for large numbers, using the extra argument to the pow function makes it much easier.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;This leaves us with our encrypted string &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;! To decrypt, simply repeat the process, but use the private exponent &lt;em&gt;d&lt;/em&gt; instead of &lt;em&gt;e&lt;/em&gt;:&lt;/p&gt;
&lt;span&gt;
  &lt;div class=&#34;katex-display&#34;&gt;
    &lt;div class=&#34;katexoverwrite&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;script&gt;
  var divs = Array.from(document.getElementsByClassName(&#34;katexoverwrite&#34;))
  katex.render(&#34;\n\\begin{aligned}\nm_1 \u0026= 579^ {2279} \\text{ mod } 7663  = 841 \\\\\nm_2 \u0026= 4278^ {2279} \\text{ mod } 7663 = 041 \\\\\n...\u0026\\\\\nm_{33} \u0026= 2367^ {2279} \\text{ mod } 7663 = 110\\\\\n\\end{aligned}\n&#34;, divs.pop(), {
    throwOnError: false
});
&lt;/script&gt;
&lt;/span&gt;
&lt;p&gt;With the successful decryption, we can now securely communicate over an insecure channel. As long as &lt;em&gt;d&lt;/em&gt; is kept secret, and we are unable to factor the modulus, &lt;em&gt;n&lt;/em&gt;, this message will stay secure.&lt;/p&gt;
&lt;h2 id=&#34;breaking-rsa-the-old-fashioned-way&#34;&gt;Breaking RSA, the old fashioned way&lt;/h2&gt;
&lt;p&gt;Now that we have an understanding of how RSA works, we can begin attacking this key. In order to decrypt the message, we need to find &lt;em&gt;d&lt;/em&gt;. The first step is to see the components of the key.  I used the Python library &lt;a href=&#34;https://www.pycryptodome.org&#34;&gt;PyCryptodome&lt;/a&gt;. To see the components, we just import the key and PyCryptodome will expose the variables:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;Crypto.PublicKey&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RSA&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;key.pub&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;r&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;keyfile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RSA&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;import_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keyfile&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;e:&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;n:&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Running the program:
&lt;img src=&#34;e52bd1a344294029b819d78d32061386.png&#34; alt=&#34;786fb13a5e40b8d32cbf4ac5923fe85e.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;Since we know the modulus, we can check a database to see if this particular number has known factors. For this, I&amp;rsquo;ll use &lt;a href=&#34;http://factordb.com&#34;&gt;factordb.com&lt;/a&gt;. After &lt;a href=&#34;http://factordb.com/index.php?query=573177824579630911668469272712547865443556654086190104722795509756891670023259031275433509121481030331598569379383505928315495462888788593695945321417676298471525243254143375622365552296949413920679290535717172319562064308937342567483690486592868352763021360051776130919666984258847567032959931761686072492923&#34;&gt;pasting&lt;/a&gt; the modulus into factordb, we see that the two factors of this number are known:
&lt;img src=&#34;22a22326280e43d0bb58c6f46d30669a.png&#34; alt=&#34;6041b48aeca8ce895c650e7f0d55c41f.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;We can copy those into our python code as &lt;em&gt;p&lt;/em&gt; and &lt;em&gt;q&lt;/em&gt; from the equations above. Now, we know &lt;em&gt;e&lt;/em&gt; (which is part of the public key), &lt;em&gt;p&lt;/em&gt;, and &lt;em&gt;q&lt;/em&gt;, so we can calculate &lt;em&gt;d&lt;/em&gt;, the secret key, using one of the above equations!&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;Crypto.PublicKey&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RSA&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;key.pub&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;r&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;keyfile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RSA&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;import_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keyfile&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;20423438101489158688419303567277343858734758547418158024698288475832952556286241362315755217906372987360487170945062468605428809604025093949866146482515539&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;q&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;28064707897434668850640509471577294090270496538072109622258544167653888581330848582140666982973481448008792075646342219560082338772652988896389532152684857&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;e&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;pow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;q&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# e^-1 mod (p-1)(q-1)&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;d:&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src=&#34;74426cc6e1c7486f84ffdd375e5e82e2.png&#34; alt=&#34;8d380997ca78106f63aa73f9bc5d21be.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;Now that we have the secret key, we simply have to use our decryption formula! Since the message is much smaller than the key, we don&amp;rsquo;t have to worry about chunking.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;Crypto.PublicKey&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RSA&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;key.pub&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;r&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;keyfile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RSA&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;import_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keyfile&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;20423438101489158688419303567277343858734758547418158024698288475832952556286241362315755217906372987360487170945062468605428809604025093949866146482515539&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;q&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;28064707897434668850640509471577294090270496538072109622258544167653888581330848582140666982973481448008792075646342219560082338772652988896389532152684857&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;e&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;pow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;q&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# e^-1 mod (p-1)(q-1)&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;# Thanks to https://stackoverflow.com/a/62986942 for the decryption code.&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;flag.enc&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;rb&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;flagfile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;encflag&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;from_bytes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;flagfile&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;big&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;pt_int&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;pow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;encflag&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# m^d mod n&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;plaintext&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pt_int&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;to_bytes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;128&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;big&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lstrip&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\x00&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;plaintext&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Finally, we decrypt the flag:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;6b0b072cee204180bc6073d414235940.png&#34; alt=&#34;d8de6c983f6d3ba8f61afc659fda911c.png&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;RSA is an incredible invention. It&amp;rsquo;s strong enough to be used to secure countless SSH or HTTPS connections, but underneath is a small bit of elegant math that college freshman can understand. It&amp;rsquo;s honestly amazing to me that the simple exponentiation that I was bored with in my college algebra class is used as the foundation of internet security.&lt;/p&gt;
&lt;p&gt;As always, if this was interesting or if you learned a trick or two. Please drop me a line. I always appreciate feedback!&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Thanks to &lt;a href=&#34;https://en.wikipedia.org/wiki/RSA_%28cryptosystem%29#Example&#34; title=&#34;https://en.wikipedia.org/wiki/RSA_(cryptosystem)#Example&#34;&gt;Wikipedia&lt;/a&gt; and Bruce Schneier&amp;rsquo;s book &amp;ldquo;&lt;a href=&#34;https://www.schneier.com/books/applied-cryptography/&#34;&gt;Applied Cryptography&lt;/a&gt;&amp;rdquo; for all of this information and these examples.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;The number is shortened for readability. This is the full chunked number: 841 041 013 297 116 116 979 910 732 119 105 108 108 329 911 110 910 132 971 163 210 097 119 110&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Again, here&amp;rsquo;s the full encrypted number: 579 4278 4986 6386 1497 1497 1024 7201 1444 5022 885 432 432 2695 7351 2367 7201 4329 292 1236 3680 2037 5022 2367&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;

        
        </description>
    </item>
    
    <item>
      <title>Breaking Santa&#39;s Encryption for Fun and Profit</title>
      <link>https://stephenswanson.xyz/articles/breaking-santas-encryption-for-fun-and-profit/</link>
      <pubDate>Wed, 29 Apr 2020 13:53:30 -0700</pubDate>
      <author>stephen@stephenswanson.xyz (Stephen Swanson)</author>
      <guid>https://stephenswanson.xyz/articles/breaking-santas-encryption-for-fun-and-profit/</guid>
      <description>
        
          &lt;img src=&#34;https://stephenswanson.xyz/articles/breaking-santas-encryption-for-fun-and-profit/recoverCleartextDocmentChallengeDescription.webp&#34;/&gt;
          
        
        
        &lt;p&gt;Recently, I&amp;rsquo;ve had more time on my hands, so I decided to take a walk down memory lane and rediscover my favorite challenge of the &lt;a href=&#34;https://holidayhackchallenge.com&#34;&gt;2019 SANS Holiday Hack Challenge&lt;/a&gt;, number 10: the Elfscrow Crypto challenge.&lt;/p&gt;
&lt;p&gt;In order to solve this challenge, I relied heavily on &lt;a href=&#34;https://www.youtube.com/watch?v=obJdpKDpFBA&#34;&gt;this talk&lt;/a&gt; by Ron Bowes, and most of this was based on his methods.
I highly recommend watching the video, especially if anything here is confusing.&lt;/p&gt;
&lt;p&gt;After downloading everything, we end up with three files:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;elfscrow.exe&lt;/em&gt;, obviously the encryption program.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;elfscrow.pdb&lt;/em&gt;, the debugging symbols.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;ElfUResearchLabsSuperSledOMaticQuickStartGuideV1.2.pdf.enc&lt;/em&gt;, this looks like an encrypted PDF based on the filename.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We&amp;rsquo;re dealing with a Windows binary, so I decided to reverse engineer this application in a virtual machine. I used &lt;a href=&#34;https://github.com/fireeye/flare-vm&#34;&gt;Flare VM&lt;/a&gt;, since it&amp;rsquo;s built for this, however, you could probably get away with wine or any other Windows system. A quick note about using Flare: although it&amp;rsquo;s recommended to detach the VM from the internet, this program needs to connect back to the North Pole API servers in order to run, so you&amp;rsquo;ll have to connect your VM to the network.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s open up our VM and just play with the program. This is one of the most important steps, at least for me; I just run the program with different options and different inputs, and just take note of the &amp;ldquo;huh&amp;rdquo; moments.
When I was playing around with the program, at least at the beginning, I used an &lt;a href=&#34;http://textfiles.com/holiday/12-bugs&#34;&gt;ASCII text file&lt;/a&gt;. I figured it&amp;rsquo;d be easier to understand the mechanism with a human readable file.&lt;/p&gt;
&lt;p&gt;I played around for a little bit, encrypted the same file a few times in quick succession, and ended up with output that looked something like this. I&amp;rsquo;ve taken the liberty of highlighting the parts of the output that were interesting:&lt;/p&gt;

  &lt;img src=&#34;huh.webp&#34;  alt=&#34;Similar seeds in encryption program&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;




&lt;div class=&#34;notices note&#34; &gt;&lt;p&gt;Quick note before moving on, you might notice an HTTP warning. I had to use &lt;em&gt;&amp;ndash;insecure&lt;/em&gt; to force HTTP, since, as of this writing, there&amp;rsquo;s a cert error that causes the program to fail.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;I&amp;rsquo;ve highlighted two things. First, a major red flag is that the seed only changed slightly, from 1588005546 to 1588005549. This indicates that the random seed is based on the time, and not some other random data. It even looks similar to a timestamp, which is quickly confirmed by decoding one of the seeds into a date:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;$ date -d @1588005546
Mon &lt;span class=&#34;m&#34;&gt;27&lt;/span&gt; Apr &lt;span class=&#34;m&#34;&gt;2020&lt;/span&gt; 09:39:06 AM PDT
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In fact, the seed for the encryption is nothing more than the current time!&lt;/p&gt;
&lt;p&gt;Secondly, the key and key length are interesting to us. Instead of creating their own encryption algorithm, developers often rely on libraries that securely implement other algorithms, like AES. This is much more secure, since there&amp;rsquo;s less room for error on the programmers end, however, if we can identify the algorithm, it can make it easier for us to defeat it, since we can take advantage of libraries too.&lt;/p&gt;
&lt;p&gt;One way we can identify the algorithm is by looking at the key length. AES typically uses keys of around 16-32 bytes, while Blowfish can use between 4-56 bytes&lt;sup&gt;&lt;a href=&#34;https://pycryptodome.readthedocs.io/en/latest/src/cipher/blowfish.html&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, and DES uses 8 bytes.&lt;/p&gt;
&lt;p&gt;Looking at the picture, we can see that the key is 8 bytes long, so it could be Blowfish, DES, or some other algorithm. I&amp;rsquo;m investigating DES first, since it&amp;rsquo;s more common.&lt;/p&gt;
&lt;p&gt;In order to determine the algorithm, I&amp;rsquo;m using a website that can encrypt and decrypt DES, Blowfish, and AES. I like &lt;a href=&#34;http://des.online-domain-tools.com&#34;&gt;http://des.online-domain-tools.com&lt;/a&gt; because we can play with the options easily.
Eventually, we figure out that the algorithm is indeed DES in CBC mode:&lt;/p&gt;

  &lt;img src=&#34;des1.webp&#34;  alt=&#34;Mostly successful DES decryption&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;Everything looks good, except for the first 8 bytes. Let&amp;rsquo;s change the initial vector to null bytes:&lt;/p&gt;

  &lt;img src=&#34;des2.webp&#34;  alt=&#34;Successful DES decryption&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;I stumbled into a little rabbit hole here. I knew that DES is considered weak and is deprecated, so I tried to figure out if there was a simple attack against it. I found out, though, that it would still take days to crack, so it&amp;rsquo;d be unfeasible for a CTF challenge.&lt;/p&gt;
&lt;p&gt;Based on what we know so far, we can draw a diagram that represents the algorithm behind Santa&amp;rsquo;s encryption:&lt;/p&gt;

  &lt;img src=&#34;elfScrowAlgorithm.webp&#34;  alt=&#34;Diagram of the program&#34;  class=&#34;center&#34;  style=&#34;border-radius: 4px;&#34;  /&gt;


&lt;p&gt;Now we can finally make a plan for approaching the actual challenge.
I like breaking it down into small components that can stand on their own. I.e, that I can test before moving on, so that I minimize the amount of code I have to debug at once.&lt;/p&gt;
&lt;p&gt;Looking at the diagram, there are three things our decryption program has to do:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;It has to decrypt DES using a key.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It has to generate that key using a timestamp.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It has to brute force the timestamp, since we only know roughly when the file was encrypted (December 6, 2019, between 7pm and 9pm UTC)&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In essence, we&amp;rsquo;re stepping backwards through the diagram, reversing each element as we come across it.&lt;/p&gt;
&lt;p&gt;We can finally start a python script to decrypt our file. I&amp;rsquo;m using &lt;a href=&#34;https://pycryptodome.readthedocs.io/en/latest/&#34;&gt;PyCryptodome&lt;/a&gt; for a DES implementation. We can pull in our known options to make a little function like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;Crypto.Cipher&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DES&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;decrypt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filebytes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;initialValue&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;bytes&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fromhex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;0000000000000000&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;santasCipher&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DES&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DES&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MODE_CBC&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;iv&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;initialValue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;santasCipher&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;decrypt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;filebytes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The reason why we we split it up into separate functions is that we can test it easily, so let&amp;rsquo;s do that:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;sys&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;12bugs1.enc&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;rb&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;encryptedfile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;bytes&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fromhex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;04b3fd0a56885f80&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stdout&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;write&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;decrypt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;encryptedfile&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here, we convert the key which we got from the testing of the Elfscrow binary to a byte object. Then we decrypt the file and write it to the screen.
When we run this, we get the plaintext of our file.&lt;/p&gt;


&lt;div class=&#34;notices note&#34; &gt;&lt;p&gt;Since we&amp;rsquo;re using python3, the only way to write raw bytes without decoding them or including the &lt;em&gt;\x&lt;/em&gt; prefix is to write directly to stdout. That&amp;rsquo;s why I&amp;rsquo;m using &lt;em&gt;sys.stdout.buffer.write()&lt;/em&gt; instead of &lt;em&gt;print()&lt;/em&gt;. Problems with encoding and decoding cost me a few hours when I was first solving this.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;That&amp;rsquo;s the easy part. Now we have to figure out how to get the hex key from the seed.
For that, we need to look at the disassembly.&lt;/p&gt;
&lt;p&gt;I like using &lt;a href=&#34;https://ghidra-sre.org/&#34;&gt;Ghidra&lt;/a&gt;, it comes preinstalled with Flare VM, but java has to be installed manually. In addition, since we&amp;rsquo;re working with a &lt;code&gt;.pdb&lt;/code&gt; file, we have to register the DIA SDK.&lt;/p&gt;
&lt;p&gt;After we have the Elfscrow binary open in Ghidra, we can start poking around for interesting functions. Since we have a plan that we&amp;rsquo;re following, we can safely ignore much of &lt;code&gt;main&lt;/code&gt;, and instead look for the functions that involve cryptography. I&amp;rsquo;m not great at reading assembly, so my reversing is partially based on the decompiler. After a little bit of investigation, I found:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;generate_key&lt;/code&gt;, which appears to take a reference to an array, and fills that array with a generated key.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;super_secure_srand&lt;/code&gt;, which looks to be a custom implementation of the srand function. It&amp;rsquo;s called with an integer to seed the random number generator.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;super_secure_random&lt;/code&gt;, just returns a semi-random integer and updates the seed.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We need to implement all three of these functions in our decoder script in order to solve the challenge. Let&amp;rsquo;s start with &lt;code&gt;super_secure_srand&lt;/code&gt; because it seems to be the foundation for the other two functions:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt; &lt;span class=&#34;n&#34;&gt;super_secure_srand&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;param_1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;mo&#34;&gt;00401&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d9r&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;PUSH&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;EBP&lt;/span&gt;
    &lt;span class=&#34;mo&#34;&gt;00401&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d91&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;MOV&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;EBP&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ESP&lt;/span&gt;
    &lt;span class=&#34;mo&#34;&gt;00401&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d93&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;MOV&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;EAX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dword&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ptr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EBP&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;param_1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// Loading the first parameter from the function call
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;mo&#34;&gt;00401&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d96&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;PUSH&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;EAX&lt;/span&gt;
    &lt;span class=&#34;mo&#34;&gt;00401&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d97&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;PUSH&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;s_Seed_&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d_004042e8&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// Formatting for fprintf
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;            
    &lt;span class=&#34;mo&#34;&gt;00401&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d9c&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;CALL&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;dword&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ptr&lt;/span&gt;
            
    &lt;span class=&#34;mo&#34;&gt;00401&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;da2&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;ADD&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;EAX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mh&#34;&gt;0x40&lt;/span&gt;
    &lt;span class=&#34;mo&#34;&gt;00401&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;da5&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;PUSH&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;EAX&lt;/span&gt;                                          
    &lt;span class=&#34;mo&#34;&gt;00401&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;da6&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;CALL&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;dword&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ptr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MSVCR90&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DLL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fprintf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
            
    &lt;span class=&#34;mo&#34;&gt;00401&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dac&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;ADD&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;ESP&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mh&#34;&gt;0xc&lt;/span&gt;
    &lt;span class=&#34;mo&#34;&gt;00401&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;daf&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;MOV&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;ECX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dword&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ptr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EBP&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;param_1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// Putting the first parameter into ECX
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;mo&#34;&gt;00401&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;db2&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;MOV&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;dword&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ptr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DAT_0040602c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ECX&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// Moving the first parameter into the variable [DAT_0040602c]
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;            
    &lt;span class=&#34;mo&#34;&gt;00401&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;db8&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;POP&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;EBP&lt;/span&gt;
    &lt;span class=&#34;mo&#34;&gt;00401&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;db9&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;RET&lt;/span&gt;
    &lt;span class=&#34;mo&#34;&gt;00401&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dba&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;align&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;align&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can see that this function prints the new seed, and then sets it in a global variable. This is easily recreated in python with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;n&#34;&gt;seed&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;super_secure_srand&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newSeed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;#print(&amp;#34;Seed = &amp;#34; + newSeed)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;global&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;seed&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;seed&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;newSeed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Next, lets take a peak at &lt;code&gt;super_secure_random&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt; &lt;span class=&#34;n&#34;&gt;super_secure_random&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;mo&#34;&gt;00401&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dc0&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;PUSH&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;EBP&lt;/span&gt;
    &lt;span class=&#34;mo&#34;&gt;00401&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dc1&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;MOV&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;EBP&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ESP&lt;/span&gt;
    &lt;span class=&#34;mo&#34;&gt;00401&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dc3&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;MOV&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;EAX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DAT_0040602c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
             
    &lt;span class=&#34;mo&#34;&gt;00401&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dc8&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;IMUL&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;EAX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EAX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mh&#34;&gt;0x343fd&lt;/span&gt;
             
    &lt;span class=&#34;mo&#34;&gt;00401&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dce&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;ADD&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;EAX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mh&#34;&gt;0x269ec3&lt;/span&gt;
             
    &lt;span class=&#34;mo&#34;&gt;00401&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dd3&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;MOV&lt;/span&gt;    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DAT_0040602c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EAX&lt;/span&gt;
             
    &lt;span class=&#34;mo&#34;&gt;00401&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dd8&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;MOV&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;EAX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DAT_0040602c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
             
    &lt;span class=&#34;mo&#34;&gt;00401&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ddd&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;SAR&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;EAX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mh&#34;&gt;0x10&lt;/span&gt;
    &lt;span class=&#34;mo&#34;&gt;00401&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;de0&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;AND&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;EAX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mh&#34;&gt;0x7fff&lt;/span&gt;
             
    &lt;span class=&#34;mo&#34;&gt;00401&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;de5&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;POP&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;EBP&lt;/span&gt;
    &lt;span class=&#34;mo&#34;&gt;00401&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;de6&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;RET&lt;/span&gt;
    &lt;span class=&#34;mo&#34;&gt;00401&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;de7&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;align&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;align&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;9&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This function is a little bit more complicated, but we can take each instruction piece by piece and understand it.&lt;/p&gt;
&lt;p&gt;First we make a local copy of the global seed in the EAX register. Then we multiply our local copy by 0x343fd and add 0x269ec3 to it. Next, we save our local seed as the global seed. Lastly, we shift our local copy to the right by 0x10 and perform an AND against 0x7fff. We then return our local copy.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s confusing to think about in assembler, but implemented in python, it looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;super_secure_random&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;# Mutating the original seed&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;global&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;seed&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;newSeed&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;seed&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;newSeed&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;newSeed&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;0x343fd&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;newSeed&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;newSeed&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;0x269ec3&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;# Saving a changed seed&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;seed&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;newSeed&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;# Mixing it up a little more&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;newSeed&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;newSeed&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;0x10&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;newSeed&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;newSeed&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;0x7fff&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;newSeed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The arithmetic can be greatly simplified, but it&amp;rsquo;s easiest for me to track the binary operations if it&amp;rsquo;s all broken up into as many steps as possible.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;generate_key&lt;/code&gt; is a little more complicated. The function graph looks like this:&lt;/p&gt;

  &lt;img src=&#34;generate_key.webp&#34;  alt=&#34;Function graph of the generate key function&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;If we break it up into separate pieces, however, and take each piece individually, we can still figure out what it does.
In the first block, we can skip most of it until the call to &lt;code&gt;time&lt;/code&gt;, since that&amp;rsquo;s the first place we see a value we&amp;rsquo;re interested in. We then head into a small set of instructions that call &lt;code&gt;super_secure_srand&lt;/code&gt; with the time:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;  &lt;span class=&#34;mf&#34;&gt;00401e0&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;CALL&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;time&lt;/span&gt;
  &lt;span class=&#34;mf&#34;&gt;00401e13&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;ADD&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;ESP&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mh&#34;&gt;0x4&lt;/span&gt;
  &lt;span class=&#34;mf&#34;&gt;00401e16&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;PUSH&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;EAX&lt;/span&gt;
  &lt;span class=&#34;mf&#34;&gt;00401e17&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;CALL&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;super_secure_srand&lt;/span&gt;
          
  &lt;span class=&#34;mf&#34;&gt;00401e1&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;c&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;ADD&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;ESP&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mh&#34;&gt;0x4&lt;/span&gt;
  &lt;span class=&#34;mf&#34;&gt;00401e1&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;MOV&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;dword&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ptr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EBP&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;local_8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;mh&#34;&gt;0x0&lt;/span&gt;
          
  &lt;span class=&#34;mf&#34;&gt;00401e26&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;JMP&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;LAB_00401e31&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then we initialize the variable &lt;code&gt;local_8&lt;/code&gt; to 0. If we look back at the flow graph, we seem to be in a &lt;code&gt;for&lt;/code&gt; loop. Although the picture doesn&amp;rsquo;t show it, every loop the value is compared to 0x8. In C++, it would look like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;// loop interior
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we can look at the interior of the loop:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;  &lt;span class=&#34;mf&#34;&gt;00401e37&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;CALL&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;super_secure_random&lt;/span&gt;
          
  &lt;span class=&#34;mf&#34;&gt;00401e3&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;c&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;MOVZX&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;ECX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AL&lt;/span&gt;
  &lt;span class=&#34;mf&#34;&gt;00401e3&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;AND&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;ECX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mh&#34;&gt;0xff&lt;/span&gt;
          
  &lt;span class=&#34;mf&#34;&gt;00401e45&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;MOV&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;EDX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dword&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ptr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EBP&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;param_1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
  &lt;span class=&#34;mf&#34;&gt;00401e48&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;ADD&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;EDX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dword&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ptr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EBP&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;local_8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
  &lt;span class=&#34;mf&#34;&gt;00401e4&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;MOV&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;byte&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ptr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EDX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CL&lt;/span&gt;
  &lt;span class=&#34;mf&#34;&gt;00401e4&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;JMP&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;LAB_00401e28&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We call &lt;code&gt;super_secure_random&lt;/code&gt;, but only take the last 8 bits, which we AND with 0xff. Once we have the new value, we make it the &lt;code&gt;i&lt;/code&gt;th element in an 8 character long list.&lt;/p&gt;

  &lt;img src=&#34;forEach.webp&#34;  alt=&#34;A graph demonstrating the function of the generate key algorithm&#34;  class=&#34;center&#34;  style=&#34;border-radius: 3px;&#34;  /&gt;


&lt;p&gt;Basically, we generate a byte for each element in our 8 byte key.&lt;/p&gt;
&lt;p&gt;All told, the key generation algorithm looks like this in python:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;generate_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;randomSeed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;keystring&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;super_secure_srand&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;randomSeed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;keyElement&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;super_secure_random&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;to_bytes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;byteorder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;little&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;keyElement&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;keyElement&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;0xff&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;keystring&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;keystring&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;format&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keyElement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;02x&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;keystring&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If we wanted to be 100% true to the program, we&amp;rsquo;d set &lt;code&gt;randomSeed&lt;/code&gt; equal to the current timestamp, but since we&amp;rsquo;re attempting to decrypt it, we need to have control over the variable.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s test what we have so far.
If we put in the seed 1588005546, and everything works right, we should get the key of the first run, &lt;code&gt;04b3fd0a56885f80&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;generate_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1588005546&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;# output: 04b3fd0a56885f80&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And sure enough, we get the right hex value! Now, given the time the program was run, we can decrypt any document.&lt;/p&gt;
&lt;p&gt;We just have one more step: bruteforce the seed used for our PDF.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s a slight problem though, between 7 and 9pm, there are 7200 seconds, which means 7200 different binary blobs, and looking for our PDF is akin to looking for a needle in a haystack, unless there&amp;rsquo;s a way to tell them apart.&lt;/p&gt;
&lt;p&gt;Luckily, at the beginning of most files, there&amp;rsquo;s an identifier. These are the &lt;a href=&#34;https://en.wikipedia.org/wiki/Magic_number_%28programming%29#In_files&#34;&gt;&amp;ldquo;magic bytes&amp;rdquo;&lt;/a&gt; of a file, and it&amp;rsquo;s how the &lt;code&gt;file&lt;/code&gt; utility can tell a PDF from a JPG. The bytes we&amp;rsquo;re looking for are &lt;code&gt;25 50 44 46&lt;/code&gt;, or &lt;code&gt;%PDF&lt;/code&gt; when they&amp;rsquo;re decoded.&lt;/p&gt;
&lt;p&gt;What we need to do is attempt decryption with every timestamp in the range, and check the first 4 bytes for the PDF magic number. First, lets get the two timestamps we&amp;rsquo;re interested in:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;$ date -d &lt;span class=&#34;s2&#34;&gt;&amp;#34;2019-12-06 7:00 PM UTC&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;+%s&amp;#34;&lt;/span&gt;
&lt;span class=&#34;m&#34;&gt;1575658800&lt;/span&gt;
$ date -d &lt;span class=&#34;s2&#34;&gt;&amp;#34;2019-12-06 9:00 PM UTC&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;+%s&amp;#34;&lt;/span&gt;
&lt;span class=&#34;m&#34;&gt;1575666000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we just need to loop over every number between them and attempt to decrypt our file.
Here&amp;rsquo;s the python code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;bruteforceFileSeed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;filebytes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;firstTimestamp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;secondTimestamp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;#Using tqdm to display a fancy progress bar as we loop through every time between our two timestamps&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;seed&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tqdm&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;firstTimestamp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;secondTimestamp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)):&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;generate_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;decryptedFilebytes&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;decrypt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;bytes&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fromhex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filebytes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

        &lt;span class=&#34;c1&#34;&gt;#Checking for PDF magic number&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;decryptedFilebytes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;bytes&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fromhex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;25504446&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
            &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Success with key:&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;and seed&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;seed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;decryptedFilebytes&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;#If we haven&amp;#39;t found anything in the range, exit with an error&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Failure!&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;rb&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;encryptedfile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;#Begin the process&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;decryptedFilebytes&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;bruteforceFileSeed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;encryptedfile&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1575658800&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1575666000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;#If we&amp;#39;ve succeeded, write our decrypted bytes to the second file&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;decryptedFilebytes&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;wb&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;decryptedfile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;decryptedfile&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;write&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;decryptedFilebytes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once we have all of that in our script, we&amp;rsquo;re finally ready to attempt to decrypt our file:&lt;/p&gt;

  &lt;img src=&#34;success.webp&#34;  alt=&#34;Successful decryption!&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;After about two minutes, our loop breaks with the success message. The file was encrypted with the key &lt;code&gt;b5ad6a321240fbec&lt;/code&gt; at 1575663650.
Even better than that, we have a decrypted file waiting for us!
Let&amp;rsquo;s open up &lt;em&gt;ElfUResearchLabsSuperSledOMaticQuickStartGuideV1.2.pdf&lt;/em&gt; and see if it worked:&lt;/p&gt;

  &lt;img src=&#34;elfu.webp&#34;  alt=&#34;Decrypted PDF&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;We&amp;rsquo;ve completed the challenge! We have the plaintext of the document, and if we look at the middle line of the first page, we see that the flag for this challenge was &amp;ldquo;Machine Learning Sleigh Route Finder&amp;rdquo;. The completed python script can be found &lt;a href=&#34;https://github.com/ArchWizard56/holidayhack2019/blob/master/Recover%20Cleartext%20Document/decrypt.py&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If this write up was interesting or if you learned something, please drop me a line! It&amp;rsquo;s always great learning where I can improve or answering any questions about my methods.&lt;/p&gt;

        
        </description>
    </item>
    
  </channel>
</rss>