<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>SANS Holiday Hack Challenge 2019 on Stephen Swanson</title>
    
    
    
    <link>https://stephenswanson.xyz/series/sans-holiday-hack-challenge-2019/</link>
    <description>Recent content in SANS Holiday Hack Challenge 2019 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>Wed, 29 Apr 2020 13:53:30 -0700</lastBuildDate>
    
	<atom:link href="https://stephenswanson.xyz/series/sans-holiday-hack-challenge-2019/index.xml" rel="self" type="application/rss+xml" />
    
    
    <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>